{"action":"created","comment":{"url":"https://api.github.com/repos/emberjs/rfcs/pulls/comments/64121145","id":64121145,"diff_hunk":"@@ -0,0 +1,837 @@\n+- Start Date: 2016-05-09\n+- RFC PR:\n+- Ember Issue:\n+\n+> Note: This RFC replaces the closely related RFC for [Module\n+Normalization](https://github.com/emberjs/rfcs/pull/124). As discussed in the\n+[Alternatives](#alternatives) section below, many concepts are shared between\n+the two proposals, but there is also a fundamental difference.\n+\n+# Summary\n+\n+Create a unified pattern for organizing and naming modules in Ember projects\n+that is deterministic, extensible, and ergonomic.\n+\n+# Motivation\n+\n+Ember CLI's conventions for project layouts and file naming are central to every\n+Ember developer's experience. It's crucial to get both the technical and\n+ergonomic details right.\n+\n+The existing conventions used by Ember CLI have evolved gradually and\n+organically over the years. Ember CLI and its predecessor Ember App Kit were\n+early adopters of ES modules and have always leveraged strong conventions to\n+deduce an understanding of modules based on their locations. Ember CLI's\n+resolver encodes those conventions to enable run-time module resolutions.\n+\n+The current system works fairly well, but has some complexities and\n+inconsistencies that both steepen its learning curve and limit its technical\n+potential.\n+\n+Drawbacks include:\n+\n+* Confusion over which of two orthogonal approaches to use for organizing\n+  modules:\n+\n+  * classic - modules are organized at the top-level by \"type\"\n+    (`components`, `templates`, etc.) and then by namespace and name.\n+\n+  * pods - modules are organized by namespace, then name, then type.\n+\n+* Addons define modules to be merged into an application through a special `app`\n+  directory. These public modules are typically private modules that are\n+  imported and re-exported, which introduces an extra module per export and an\n+  extra level of abstraction to learn.\n+\n+* Because addons' modules are mixed into an application, there's the possibility\n+  of naming collisions between two addons or an addon and its consuming\n+  application.\n+\n+* Modules don't have a clear sense of \"locality\", which prevents the ability to\n+  declare modules that are available only in a \"local\" namespace (this as-yet\n+  unsupported feature has been called \"local lookup\").\n+\n+* Resolution rules that are declared only in JavaScript are difficult to\n+  analyze and optimize.\n+\n+* Module resolution is inefficient due to the number of potential places to\n+  lookup a particular module by name.\n+\n+Recognizing these drawbacks, the Core Team compiled a set of\n+[design constraints](https://github.com/emberjs/core-notes/blob/master/ember.js/2016-01/january-22.md#summary-of-pods-design-constraints)\n+for a rethink of Ember's approach to modules:\n+\n+1. Reasonable branching factor. Users should see a reasonable number of items at any given level in their hierarchy. Flattening out too much results in an unreasonably large number of items.\n+2. No slashes in component names. The existing system allows this, but we don't want to support invocation of nested components in Glimmer Components.\n+3. Addons need to participate in the naming scheme, most likely with namespace prefix and double-colon separator.\n+4. Subtrees should be relocatable. If you move a directory to a new place in the tree, its internal structure should all still work.\n+5. There should be no cognitive overhead when adding a new thing. The right way should be obvious and not impose unnecessary decisions.\n+6. We need clean separation between the namespace of the user's own components, helpers, routes, etc and the framework's own type names (\"component\", \"helper\", etc) so that we can disambiguate them and add future ones.\n+7. Ideally we will have a place to put tests and styles alongside corresponding components.\n+8. Local relative lookup for components and helpers needs to work.\n+9. Avoid the \"titlebar problem\", in which many files are all named \"component.js\" and you can't tell them apart in your editor.\n+10. The resolver should be configured via declarative rules, not imperative\n+    JavaScript. In addition to enforcing consistency, this allows addons to\n+    augment the system with their own types in a predictable way.\n+11. Module structures must be statically analyzable at build time to enable\n+    efficiency optimizations.\n+12. Module classifications must be extensible and allow for customizations by\n+    apps, engines, and addons.\n+\n+> Note: Constraints > 9 were added based on discussions subsequent to the\n+initial meeting.\n+\n+This proposal attempts to address these constraints with a single consistent\n+approach to modules that will make Ember easier to use and learn _and_ improve\n+the efficiency of Ember's resolver at run-time.\n+\n+# Detailed Design\n+\n+This proposal introduces a new top-level directory, `src`, and establishes\n+conventions for organizing modules within it. Also proposed is a refactor of the\n+Ember resolver to enable efficient and flexible resolutions based upon the new\n+module conventions.\n+\n+The `src` directory will be used to contain the core ES modules within an Ember\n+CLI project, whether that project contains an application, addon, or engine. To\n+maintain backward compatibility, the `src` directory will be allowed to\n+co-exist alongside existing `app` and/or `addon` directories, although these\n+directories should eventually be deprecated.\n+\n+## Examples\n+\n+Let's start by taking a look at some examples of Ember projects organized\n+according to the proposed conventions.\n+\n+### Example Application\n+\n+A simple blogging application could be structured as follows:\n+\n+```\n+src\n+  data\n+    models\n+      author.js\n+      comment\n+        adapter.js\n+        model.js\n+        serializer.js\n+      post\n+        adapter.js\n+        model.js\n+        serializer.js\n+    transforms\n+      date.js\n+  init\n+    initializers\n+      i18n.js\n+    instance-initializers\n+      auth.js\n+  services\n+    auth.js\n+  ui\n+    components\n+      capitalize.js\n+      date-picker\n+        component.js\n+        template.hbs\n+      list-paginator\n+        component.js\n+        template.hbs\n+        paginator-control\n+          component.js\n+          template.hbs\n+    partials\n+      footer.hbs\n+    routes\n+      application\n+        template.hbs\n+      index\n+        template.hbs\n+        route.js\n+        controller.js\n+      posts\n+        -components\n+          capitalize.js\n+          titleize.js\n+          -utils\n+            strings.js\n+        post\n+          -components\n+            post-viewer\n+              component.js\n+              template.hbs\n+          edit\n+            -components\n+              post-editor\n+                post-editor-button\n+                  component.js\n+                  template.hbs\n+                calculate-post-title.js\n+                component.js\n+                template.hbs\n+            route.js\n+            template.hbs\n+          route.js\n+          template.hbs\n+        route.js\n+        template.hbs\n+    styles\n+      app.scss\n+    index.html\n+  utils\n+    md5.js\n+  main.js\n+  router.js\n+```\n+\n+### Example Engine\n+\n+An engine could provide the same blogging functionality with almost entirely the\n+same module structure as the example blog application. Only the following\n+notable changes would be needed:\n+\n+* An engine should declare its routes in `src/routes.js` instead of `src/router.js`\n+* An engine would require a `dummy` app within `tests`\n+* An engine should export an `Engine` instead of an `Application` from `src/main.js`\n+\n+### Example Addon\n+\n+Here's how the\n+[ember-power-select](https://github.com/cibernox/ember-power-select) addon could\n+be restructured:\n+\n+```\n+src\n+  styles\n+    ember-power-select.scss\n+  ui\n+    components\n+      is-selected.js\n+      main\n+        before-options\n+          component.js\n+          template.hbs\n+        options\n+          component.js\n+          template.hbs\n+        trigger\n+          component.js\n+          template.hbs\n+        component.js\n+        template.hbs\n+      multiple\n+        trigger\n+          component.js\n+          template.hbs\n+        component.js\n+        template.hbs\n+  main.js\n+```\n+\n+### Migration Tool\n+\n+As a proof of concept for the module layout described in this RFC, Robert\n+Jackson has created a [migration\n+tool](https://github.com/rwjblue/ember-module-migrator) and used it to migrate\n+the following repos:\n+\n+* [Ghost admin client](https://github.com/rwjblue/--ghost-modules-sample/tree/grouped-collections/src)\n+* [Travis client](https://github.com/rwjblue/--travis-modules-sample/tree/modules/src)\n+* [`ember new my-app`](https://github.com/rwjblue/--new-app-blueprint/tree/modules/src)\n+\n+You can also use Robert's migration tool on your own projects to gain a feel for\n+how this RFC will affect your work.\n+\n+## ES Modules\n+\n+It's important to understand how ES module paths are mapped from the file\n+system so that you can import modules from elsewhere in your project and its\n+associated dependencies.\n+\n+ES module paths will be formed from a project's package name followed by a\n+direct mapping of file paths from the project root. The file's final extension\n+(e.g. `js` or `hbs`) will be excluded because all ES modules will of course be\n+compiled into JavaScript from their original format.\n+\n+For example, the file `src/ui/components/date-picker.js` in the\n+`my-calendar` app will be exported with the module path\n+`my-calendar/src/ui/components/date-picker`.\n+\n+Within any package, you'll be able to access the package's root with `$root`\n+and the project's `src` dir with `$src`.\n+\n+These aliases will make the following module paths equivalent:\n+\n+* `my-calendar/src/ui/components/date-picker`\n+* `$root/src/ui/components/date-picker`\n+* `$src/ui/components/date-picker`\n+\n+Let's say that you want to create a new component, `date-time-picker`, which is\n+based on `date-picker`. You'll be able to import the base component from any of\n+the paths above. For example:\n+\n+```\n+import DatePicker from '$src/ui/components/date-picker';\n+```\n+\n+> Note: The above example could also use a relative path, like\n+`'./date-picker'`, which would be appropriate if the extended\n+`date-time-picker` is located close to the base `date-picker`.\n+\n+An application and its associated addons and engines will all be merged into the\n+same ES module space, as is done today. Any module can import from any other\n+module within this space, although cross-package imports should be done with\n+care.\n+\n+## Module Naming and Organization\n+\n+This section describes the conventions proposed for naming and organizing a\n+project's modules within `src`. These conventions will allow Ember CLI's\n+resolver to determine the purpose of each module at run-time. They will also\n+enable static analysis of modules to lint against errors and to prepare a\n+normalized map for efficient resolutions.\n+\n+Every resolvable module must have both a `name` and a `type`. The `type`\n+typically corresponds to the base class of the module's default export (e.g.\n+`route`, `template`, etc.).\n+\n+Modules can be grouped together with other modules of related types in\n+\"collections\". Collections are directories with type-aware resolution rules\n+which allow related modules to share a namespace. For example, the `models`\n+collection contains models, adapters, and serializers.\n+\n+Collections that are related to each other can be further organized in \"group\"\n+directories. For example, the `ui` group contains the `components`, `partials`,\n+and `routes` collections.\n+\n+Ember CLI will have a build step that normalizes modules to a common form and\n+builds a mapping between that form and the ES module path described above.\n+While building this normalized map, the build must error and provide useful\n+messages if any module naming errors are detected. Unregistered collections and\n+types should not be allowed. Also, the same normalized module path must not be\n+repeated through alternative naming forms.\n+\n+### Module Type\n+\n+The type of a module can be determined through the following file naming and\n+module export rules:\n+\n+1. `src/${type}` - typed modules named `main` (explained further below), in\n+    which default exports match the type specified by the file name.\n+2. `src/${collection}/${namespace}/${name}/${type}` - expanded collection\n+    modules, in which default exports match the type specified by the file name.\n+3. `src/${collection}/${namespace}/${name}` - in which type can be inferred\n+    based on the module's exports. Default exports must match the default\n+    type for the collection. If there is no default export, named exports will\n+    be scanned for a matching type allowed in the collection.\n+\n+Note that template precompilers will need to use default vs. named exports\n+appropriately in order to satisfy the expectations of Rules 2 and 3.\n+\n+Here are a few example applications of the module type determination rules:\n+\n+```\n+// Rule 1\n+\n+src/router (with `export default Ember.Router.extend()`)\n+=> name: 'main',\n+   type: 'router'\n+\n+// Rule 2\n+\n+src/ui/routes/posts/post/route.js (with `export default Ember.Route.extend()`)\n+=> collection: 'ui/routes',\n+   namespace: 'posts',\n+   name: 'post',\n+   type: 'route'\n+\n+src/ui/routes/posts/post/template (with `export default Ember.HTMLBars.template(COMPILED)`)\n+=> collection: 'ui/routes',\n+   namespace: 'posts',\n+   name: 'post',\n+   type: 'template'\n+\n+// Rule 3\n+\n+src/data/models/author (with `export default DS.Model.extend()`)\n+=> collection: 'data/models',\n+   name: 'author',\n+   type: 'model' (the default type for the models collection)\n+\n+src/ui/components/titleize (with `export let helper = Ember.Helper.helper(function() { })`)\n+=> collection: 'ui/components',\n+   name: 'titleize',\n+   type: 'helper'\n+\n+src/ui/components/show-title (with `export let template = Ember.HTMLBars.template(COMPILED)`)\n+=> collection: 'ui/components',\n+   name: 'show-title',\n+   type: 'template'\n+```\n+\n+### Main Modules\n+\n+Every project must have a \"main\" module, named `src/main.js`, that\n+serves as an entry point into the project.\n+\n+The main module must export an `Application`, `Engine`, or (new) `Addon` class.\n+This class must define a `modulePrefix`, which must match the node package name\n+for the project.\n+\n+The main module also declares other properties that help the Ember resolver\n+understand relationships between projects. For instance, the main module can\n+declare which modules in an addon are available to a consuming app's resolver.\n+\n+The main module of an addon can also declare a `rootName`, which is used by the\n+resolver to lookup main modules. Initially, the `rootName` will be a read-only\n+property that equals the `modulePrefix` with any `ember-` and  `ember-cli-`\n+prefixes stripped (e.g. `ember-power-select` becomes `power-select`). It's\n+possible that we may allow overrides / aliases in the future.\n+\n+Modules that appear alongside `main.js` in `src` are also considered `main`\n+modules for their respective `type`. For instance, `src/router.js` is registered\n+with a `name` of `main` and a `type` of `router`.\n+\n+### Module Collections\n+\n+Top-level namespaces within `src` serve to group modules into\n+type-aware \"collections\".\n+\n+The following rules apply to module collections and types:\n+\n+1. Each collection can contain one or more types. The types allowed\n+   in a particular collection MUST be explicitly declared.\n+2. Each type MAY exist in any number of collections.\n+3. Each type MUST have only one \"definitive collection\", which is the\n+   collection the resolver will use for resolutions if a module can't be found\n+   in the local (i.e. originating) collection.\n+4. Each collection MAY have a single \"default type\". If a module does not\n+   indicate its type through its file name, then its default export should\n+   align with the default type for its collection.\n+5. Each collection can allow \"private collections\" to be defined at a namespace.\n+   Private collections are localized additions to a top-level collection,\n+   available only from the namespace at which they're defined.\n+6. Top-level collections may be grouped for organization purposes. No\n+   resolvable modules must be placed in a group directory.\n+7. A collection can appear only once in a project (i.e. it can not be\n+   contained in multiple group directories, or in a group as well as at the\n+   top-level).\n+\n+The following collections and allowed types (rules 1 & 2) are proposed:\n+\n+* `components` - COMPONENT, HELPER, template\n+* `initializers` - INITIALIZER\n+* `instance-initializers` - INSTANCE-INITIALIZER\n+* `models` - MODEL, ADAPTER, SERIALIZER\n+* `partials` - PARTIAL\n+* `routes` - ROUTE, CONTROLLER, template\n+* `services` - SERVICE\n+* `transforms` - TRANSFORM\n+* `utils` - UTIL\n+\n+> Note: ALL CAPS indicates which collections are definitive (rule 3) for a type.\n+\n+The following default types are proposed for collections (rule 4):\n+\n+* `components` - component\n+* `initializer` - initializer\n+* `instance-initializers` - instance-initializer\n+* `models` - model\n+* `partials` - partial\n+* `routes` - route\n+* `services` - service\n+* `transforms` - transform\n+* `utils` - util\n+\n+The following private collections are allowed within collections (rule 5):\n+\n+* `components` - utils\n+* `models` - utils\n+* `initializers` - utils\n+* `instance-initializers` - utils\n+* `routes` - components, utils\n+* `services` - utils\n+* `transforms` - utils\n+\n+The following groups are proposed for collections (rule 6):\n+\n+* `data` - models, transforms\n+* `init` - initializers, instance-initializers\n+* `ui` - components, partials, routes\n+\n+The collection and type system is designed to be extensible, so that addons can\n+contribute their own collections and types. The `data` collection and its\n+corresponding types should be defined in ember-data. Liquid-fire might want to\n+define an `animations` collection and a `transition` type, and expand `routes`\n+to allow `animations` as a private collection.\n+\n+The specific format of collection and type declarations for addons is TBD.\n+\n+#### \"Components\" Collection\n+\n+This proposal broadens the scope of the term \"component\" to include all\n+template-invocable parts of Ember. This includes today's components and helpers,\n+and the future implementation of \"glimmer components\" (with angle brackets) and\n+element modifiers.\n+\n+Grouping template-invocable elements together in a single collection recognizes\n+that they already coexist in the same namespace. After all, only one helper OR\n+component can be invoked as `{{foo-bar}}`. Using a common collection will not\n+only simplify file management and searching, it will also provide implicit\n+linting against creating a helper and class-based component of the same name.\n+\n+#### Private Collections\n+\n+You may wish to make a component available in a particular template without\n+polluting the top-level `components` collection with a more local concern.\n+Private collections allow you to augment a top-level collection's contents for\n+use at a particular namespace.\n+\n+Private collections are declared as a directory sharing the name of the\n+top-level collection, prefixed with a `-`. So the top-level `routes`\n+collection could be augmented via a private `-components` collection.\n+\n+Say that you want to define a `post-viewer` component to be available only from\n+within `src/ui/routes/posts/post/template.hbs`. You could achieve this by\n+creating your component module in\n+`src/ui/routes/posts/post/-components/post-viewer.js`.\n+\n+#### Non-resolved Files\n+\n+The rules above apply to modules that are resolved, namely `*.js` and `*.hbs`\n+files. Other files that are used for documenting code, such as `*.md` and\n+`*.html` files, can be freely co-located in any directories.\n+\n+Conventions will still be used for non-resolved files that have significance\n+within an Ember project, including:\n+\n+* `src/ui/styles` - A project's stylesheets.\n+* `src/ui/index.html` - A project's html container.\n+\n+### Packages\n+\n+In-repo addons (including engines) will be placed in a new top-level `packages`\n+directory (a sibling of `src`). We can begin to use the term \"packages\" instead\n+of the rather clumsy \"in-repo addons\". This differentiation will emphasize that\n+packages are internal and addons are external to a project. Packages should be\n+seen as a lightweight way to add new namespacing within a project without the\n+overhead of a full addon.\n+\n+The `packages` directory will provide a separate space away from other library\n+modules that might be kept in `lib`, the current directory used for in-repo\n+addons. Introducing a new top-level directory will allow a clear migration path\n+for in-repo addons, in the same way that there's a clear migration path from\n+`app` to `src`.\n+\n+Inside `packages`, packages should be grouped by name. Each package can have\n+its own `index.js`, `package.json`, and `src` directory.\n+\n+## Ember Resolver Refactor\n+\n+The Ember resolver must be refactored significantly to be made aware of the\n+new `src` and `packages` directories and associated conventions.\n+\n+### Module Normalization\n+\n+As discussed above, Ember CLI will perform a normalization process for all the\n+modules in a project and its associated projects. The normalization step will\n+involve the construction of a map from each module's normalized form to its\n+corresponding ES module path. If any conflicts are detected, the process should\n+error and notify the developer.\n+\n+The Ember resolver will only look up modules in their normalized form, utilizing\n+the pre-built normalization map to resolve the actual module path.\n+\n+### Addon modules","path":"text/0000-module-unification.md","position":546,"original_position":546,"commit_id":"57dee59492c52cbcdb82d0b30071933847df0ecb","original_commit_id":"57dee59492c52cbcdb82d0b30071933847df0ecb","user":{"login":"nathanhammond","id":20542,"avatar_url":"https://avatars.githubusercontent.com/u/20542?v=3","gravatar_id":"","url":"https://api.github.com/users/nathanhammond","html_url":"https://github.com/nathanhammond","followers_url":"https://api.github.com/users/nathanhammond/followers","following_url":"https://api.github.com/users/nathanhammond/following{/other_user}","gists_url":"https://api.github.com/users/nathanhammond/gists{/gist_id}","starred_url":"https://api.github.com/users/nathanhammond/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nathanhammond/subscriptions","organizations_url":"https://api.github.com/users/nathanhammond/orgs","repos_url":"https://api.github.com/users/nathanhammond/repos","events_url":"https://api.github.com/users/nathanhammond/events{/privacy}","received_events_url":"https://api.github.com/users/nathanhammond/received_events","type":"User","site_admin":false},"body":"Can we tweak this for clarity? `main` isn't a valid component name, though I suppose that in this case it could be a helper. But then we demonstrate it as just the namespace only for using it?","created_at":"2016-05-20T23:38:23Z","updated_at":"2016-05-20T23:38:23Z","html_url":"https://github.com/emberjs/rfcs/pull/143#discussion_r64121145","pull_request_url":"https://api.github.com/repos/emberjs/rfcs/pulls/143","_links":{"self":{"href":"https://api.github.com/repos/emberjs/rfcs/pulls/comments/64121145"},"html":{"href":"https://github.com/emberjs/rfcs/pull/143#discussion_r64121145"},"pull_request":{"href":"https://api.github.com/repos/emberjs/rfcs/pulls/143"}}},"pull_request":{"url":"https://api.github.com/repos/emberjs/rfcs/pulls/143","id":69386467,"html_url":"https://github.com/emberjs/rfcs/pull/143","diff_url":"https://github.com/emberjs/rfcs/pull/143.diff","patch_url":"https://github.com/emberjs/rfcs/pull/143.patch","issue_url":"https://api.github.com/repos/emberjs/rfcs/issues/143","number":143,"state":"open","locked":false,"title":"Module Unification","user":{"login":"dgeb","id":29122,"avatar_url":"https://avatars.githubusercontent.com/u/29122?v=3","gravatar_id":"","url":"https://api.github.com/users/dgeb","html_url":"https://github.com/dgeb","followers_url":"https://api.github.com/users/dgeb/followers","following_url":"https://api.github.com/users/dgeb/following{/other_user}","gists_url":"https://api.github.com/users/dgeb/gists{/gist_id}","starred_url":"https://api.github.com/users/dgeb/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dgeb/subscriptions","organizations_url":"https://api.github.com/users/dgeb/orgs","repos_url":"https://api.github.com/users/dgeb/repos","events_url":"https://api.github.com/users/dgeb/events{/privacy}","received_events_url":"https://api.github.com/users/dgeb/received_events","type":"User","site_admin":false},"body":"[Rendered](https://github.com/dgeb/rfcs/blob/module-unification/text/0000-module-unification.md)","created_at":"2016-05-09T18:11:26Z","updated_at":"2016-05-20T23:38:23Z","closed_at":null,"merged_at":null,"merge_commit_sha":"4a44348a9bfe430a911a9f1c680d496044ed2b93","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/emberjs/rfcs/pulls/143/commits","review_comments_url":"https://api.github.com/repos/emberjs/rfcs/pulls/143/comments","review_comment_url":"https://api.github.com/repos/emberjs/rfcs/pulls/comments{/number}","comments_url":"https://api.github.com/repos/emberjs/rfcs/issues/143/comments","statuses_url":"https://api.github.com/repos/emberjs/rfcs/statuses/57dee59492c52cbcdb82d0b30071933847df0ecb","head":{"label":"dgeb:module-unification","ref":"module-unification","sha":"57dee59492c52cbcdb82d0b30071933847df0ecb","user":{"login":"dgeb","id":29122,"avatar_url":"https://avatars.githubusercontent.com/u/29122?v=3","gravatar_id":"","url":"https://api.github.com/users/dgeb","html_url":"https://github.com/dgeb","followers_url":"https://api.github.com/users/dgeb/followers","following_url":"https://api.github.com/users/dgeb/following{/other_user}","gists_url":"https://api.github.com/users/dgeb/gists{/gist_id}","starred_url":"https://api.github.com/users/dgeb/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dgeb/subscriptions","organizations_url":"https://api.github.com/users/dgeb/orgs","repos_url":"https://api.github.com/users/dgeb/repos","events_url":"https://api.github.com/users/dgeb/events{/privacy}","received_events_url":"https://api.github.com/users/dgeb/received_events","type":"User","site_admin":false},"repo":{"id":32706490,"name":"rfcs","full_name":"dgeb/rfcs","owner":{"login":"dgeb","id":29122,"avatar_url":"https://avatars.githubusercontent.com/u/29122?v=3","gravatar_id":"","url":"https://api.github.com/users/dgeb","html_url":"https://github.com/dgeb","followers_url":"https://api.github.com/users/dgeb/followers","following_url":"https://api.github.com/users/dgeb/following{/other_user}","gists_url":"https://api.github.com/users/dgeb/gists{/gist_id}","starred_url":"https://api.github.com/users/dgeb/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dgeb/subscriptions","organizations_url":"https://api.github.com/users/dgeb/orgs","repos_url":"https://api.github.com/users/dgeb/repos","events_url":"https://api.github.com/users/dgeb/events{/privacy}","received_events_url":"https://api.github.com/users/dgeb/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/dgeb/rfcs","description":"RFCs for changes to Ember","fork":true,"url":"https://api.github.com/repos/dgeb/rfcs","forks_url":"https://api.github.com/repos/dgeb/rfcs/forks","keys_url":"https://api.github.com/repos/dgeb/rfcs/keys{/key_id}","collaborators_url":"https://api.github.com/repos/dgeb/rfcs/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/dgeb/rfcs/teams","hooks_url":"https://api.github.com/repos/dgeb/rfcs/hooks","issue_events_url":"https://api.github.com/repos/dgeb/rfcs/issues/events{/number}","events_url":"https://api.github.com/repos/dgeb/rfcs/events","assignees_url":"https://api.github.com/repos/dgeb/rfcs/assignees{/user}","branches_url":"https://api.github.com/repos/dgeb/rfcs/branches{/branch}","tags_url":"https://api.github.com/repos/dgeb/rfcs/tags","blobs_url":"https://api.github.com/repos/dgeb/rfcs/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/dgeb/rfcs/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/dgeb/rfcs/git/refs{/sha}","trees_url":"https://api.github.com/repos/dgeb/rfcs/git/trees{/sha}","statuses_url":"https://api.github.com/repos/dgeb/rfcs/statuses/{sha}","languages_url":"https://api.github.com/repos/dgeb/rfcs/languages","stargazers_url":"https://api.github.com/repos/dgeb/rfcs/stargazers","contributors_url":"https://api.github.com/repos/dgeb/rfcs/contributors","subscribers_url":"https://api.github.com/repos/dgeb/rfcs/subscribers","subscription_url":"https://api.github.com/repos/dgeb/rfcs/subscription","commits_url":"https://api.github.com/repos/dgeb/rfcs/commits{/sha}","git_commits_url":"https://api.github.com/repos/dgeb/rfcs/git/commits{/sha}","comments_url":"https://api.github.com/repos/dgeb/rfcs/comments{/number}","issue_comment_url":"https://api.github.com/repos/dgeb/rfcs/issues/comments{/number}","contents_url":"https://api.github.com/repos/dgeb/rfcs/contents/{+path}","compare_url":"https://api.github.com/repos/dgeb/rfcs/compare/{base}...{head}","merges_url":"https://api.github.com/repos/dgeb/rfcs/merges","archive_url":"https://api.github.com/repos/dgeb/rfcs/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/dgeb/rfcs/downloads","issues_url":"https://api.github.com/repos/dgeb/rfcs/issues{/number}","pulls_url":"https://api.github.com/repos/dgeb/rfcs/pulls{/number}","milestones_url":"https://api.github.com/repos/dgeb/rfcs/milestones{/number}","notifications_url":"https://api.github.com/repos/dgeb/rfcs/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/dgeb/rfcs/labels{/name}","releases_url":"https://api.github.com/repos/dgeb/rfcs/releases{/id}","deployments_url":"https://api.github.com/repos/dgeb/rfcs/deployments","created_at":"2015-03-23T02:19:08Z","updated_at":"2016-05-09T18:55:23Z","pushed_at":"2016-05-17T13:13:28Z","git_url":"git://github.com/dgeb/rfcs.git","ssh_url":"git@github.com:dgeb/rfcs.git","clone_url":"https://github.com/dgeb/rfcs.git","svn_url":"https://github.com/dgeb/rfcs","homepage":null,"size":141,"stargazers_count":3,"watchers_count":3,"language":null,"has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":3,"mirror_url":null,"open_issues_count":0,"forks":3,"open_issues":0,"watchers":3,"default_branch":"master"}},"base":{"label":"emberjs:master","ref":"master","sha":"68e8c79e2bd2fb894b0ec1f3ae5acd142e09d284","user":{"login":"emberjs","id":1253363,"avatar_url":"https://avatars.githubusercontent.com/u/1253363?v=3","gravatar_id":"","url":"https://api.github.com/users/emberjs","html_url":"https://github.com/emberjs","followers_url":"https://api.github.com/users/emberjs/followers","following_url":"https://api.github.com/users/emberjs/following{/other_user}","gists_url":"https://api.github.com/users/emberjs/gists{/gist_id}","starred_url":"https://api.github.com/users/emberjs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/emberjs/subscriptions","organizations_url":"https://api.github.com/users/emberjs/orgs","repos_url":"https://api.github.com/users/emberjs/repos","events_url":"https://api.github.com/users/emberjs/events{/privacy}","received_events_url":"https://api.github.com/users/emberjs/received_events","type":"Organization","site_admin":false},"repo":{"id":22664562,"name":"rfcs","full_name":"emberjs/rfcs","owner":{"login":"emberjs","id":1253363,"avatar_url":"https://avatars.githubusercontent.com/u/1253363?v=3","gravatar_id":"","url":"https://api.github.com/users/emberjs","html_url":"https://github.com/emberjs","followers_url":"https://api.github.com/users/emberjs/followers","following_url":"https://api.github.com/users/emberjs/following{/other_user}","gists_url":"https://api.github.com/users/emberjs/gists{/gist_id}","starred_url":"https://api.github.com/users/emberjs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/emberjs/subscriptions","organizations_url":"https://api.github.com/users/emberjs/orgs","repos_url":"https://api.github.com/users/emberjs/repos","events_url":"https://api.github.com/users/emberjs/events{/privacy}","received_events_url":"https://api.github.com/users/emberjs/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/emberjs/rfcs","description":"RFCs for changes to Ember","fork":false,"url":"https://api.github.com/repos/emberjs/rfcs","forks_url":"https://api.github.com/repos/emberjs/rfcs/forks","keys_url":"https://api.github.com/repos/emberjs/rfcs/keys{/key_id}","collaborators_url":"https://api.github.com/repos/emberjs/rfcs/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/emberjs/rfcs/teams","hooks_url":"https://api.github.com/repos/emberjs/rfcs/hooks","issue_events_url":"https://api.github.com/repos/emberjs/rfcs/issues/events{/number}","events_url":"https://api.github.com/repos/emberjs/rfcs/events","assignees_url":"https://api.github.com/repos/emberjs/rfcs/assignees{/user}","branches_url":"https://api.github.com/repos/emberjs/rfcs/branches{/branch}","tags_url":"https://api.github.com/repos/emberjs/rfcs/tags","blobs_url":"https://api.github.com/repos/emberjs/rfcs/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/emberjs/rfcs/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/emberjs/rfcs/git/refs{/sha}","trees_url":"https://api.github.com/repos/emberjs/rfcs/git/trees{/sha}","statuses_url":"https://api.github.com/repos/emberjs/rfcs/statuses/{sha}","languages_url":"https://api.github.com/repos/emberjs/rfcs/languages","stargazers_url":"https://api.github.com/repos/emberjs/rfcs/stargazers","contributors_url":"https://api.github.com/repos/emberjs/rfcs/contributors","subscribers_url":"https://api.github.com/repos/emberjs/rfcs/subscribers","subscription_url":"https://api.github.com/repos/emberjs/rfcs/subscription","commits_url":"https://api.github.com/repos/emberjs/rfcs/commits{/sha}","git_commits_url":"https://api.github.com/repos/emberjs/rfcs/git/commits{/sha}","comments_url":"https://api.github.com/repos/emberjs/rfcs/comments{/number}","issue_comment_url":"https://api.github.com/repos/emberjs/rfcs/issues/comments{/number}","contents_url":"https://api.github.com/repos/emberjs/rfcs/contents/{+path}","compare_url":"https://api.github.com/repos/emberjs/rfcs/compare/{base}...{head}","merges_url":"https://api.github.com/repos/emberjs/rfcs/merges","archive_url":"https://api.github.com/repos/emberjs/rfcs/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/emberjs/rfcs/downloads","issues_url":"https://api.github.com/repos/emberjs/rfcs/issues{/number}","pulls_url":"https://api.github.com/repos/emberjs/rfcs/pulls{/number}","milestones_url":"https://api.github.com/repos/emberjs/rfcs/milestones{/number}","notifications_url":"https://api.github.com/repos/emberjs/rfcs/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/emberjs/rfcs/labels{/name}","releases_url":"https://api.github.com/repos/emberjs/rfcs/releases{/id}","deployments_url":"https://api.github.com/repos/emberjs/rfcs/deployments","created_at":"2014-08-06T00:49:22Z","updated_at":"2016-05-14T08:00:17Z","pushed_at":"2016-05-17T13:13:28Z","git_url":"git://github.com/emberjs/rfcs.git","ssh_url":"git@github.com:emberjs/rfcs.git","clone_url":"https://github.com/emberjs/rfcs.git","svn_url":"https://github.com/emberjs/rfcs","homepage":null,"size":498,"stargazers_count":422,"watchers_count":422,"language":null,"has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":117,"mirror_url":null,"open_issues_count":60,"forks":117,"open_issues":60,"watchers":422,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/emberjs/rfcs/pulls/143"},"html":{"href":"https://github.com/emberjs/rfcs/pull/143"},"issue":{"href":"https://api.github.com/repos/emberjs/rfcs/issues/143"},"comments":{"href":"https://api.github.com/repos/emberjs/rfcs/issues/143/comments"},"review_comments":{"href":"https://api.github.com/repos/emberjs/rfcs/pulls/143/comments"},"review_comment":{"href":"https://api.github.com/repos/emberjs/rfcs/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/emberjs/rfcs/pulls/143/commits"},"statuses":{"href":"https://api.github.com/repos/emberjs/rfcs/statuses/57dee59492c52cbcdb82d0b30071933847df0ecb"}}}}
{"actor":{"display_login":"nathanhammond"}}