{"action":"created","comment":{"url":"https://api.github.com/repos/GPII/gpii-express/pulls/comments/26247919","id":26247919,"diff_hunk":"@@ -0,0 +1,179 @@\n+// Express instance represented as a component\n+//\n+// Add additional routers and middleware as child components of this module\n+\"use strict\";\n+var fluid = fluid || require(\"infusion\");\n+var gpii  = fluid.registerNamespace(\"gpii\");\n+fluid.registerNamespace(\"gpii.express\");\n+\n+// Look up the path (parent, sibling, child) relationships for a node.\n+// Used in constructing the hierarchy we will use to wire together everything in our onCreate method.\n+//\n+// This does not require an invoker as it is basically a static method.\n+gpii.express.pathForComponent = function (that) {\n+    var instantiator  = fluid.getInstantiator(that);\n+    var path          = instantiator.idToPath(that.id);\n+    var segments      = fluid.model.parseEL(path);\n+    return segments;\n+};\n+\n+// Make a note of the lineage of this middleware or router component, all the way back presumably to this gpii.express\n+// instance itself.\n+//\n+// This information will be used to wire together all nested routers and any middleware dependencies they have.\n+gpii.express.registerComponentLineage = function(childComponent, expressComponent) {\n+    // Get the list of parents for this component\n+    var segments = gpii.express.pathForComponent(childComponent);\n+\n+    var childNickname  = segments[segments.length - 1];\n+\n+    var expressSegments = gpii.express.pathForComponent(expressComponent);\n+\n+    // If we only have one segment more than express, we are a child of express itself.\n+    // We need this to be able to handle cases in which express itself is a child component.\n+    if (segments.length === expressSegments.length + 1) {\n+        expressComponent.options.members.directChildrenOfInterest.push(childNickname);\n+    }\n+    // Otherwise, register the nickname of this component and its immediate parent path, each level will take care of the next highest.\n+    else if (segments.length > expressSegments.length + 1) {\n+        var parentPath = segments.slice(expressSegments.length, segments.length - 1).join(\".\");\n+        if (expressComponent.options.members.childrenByParent[parentPath]) {\n+            expressComponent.options.members.childrenByParent[parentPath].push(childNickname);\n+        }\n+        else {\n+            expressComponent.options.members.childrenByParent[parentPath] = [childNickname];\n+        }\n+    }\n+};\n+\n+// Wire a child to its immediate descendants.\n+gpii.express.connectDirectDescendants = function(that, childComponent, childPath) {\n+    var descendants =  that.options.members.childrenByParent[childPath];\n+\n+    // This component has descendants, wire them in first\n+    if (descendants !== undefined) {\n+        // Wire together one level of routers and middleware, then recurse\n+        for (var a = 0; a < descendants.length; a++) {\n+            var grandchildNickname  = descendants[a];\n+            var grandchildComponent = childComponent[grandchildNickname];\n+            if (fluid.hasGrade(grandchildComponent.options, \"gpii.express.router\")) {\n+                // We have to wire our children in with our path to preserve relative pathing, so that their router will begin with our path.\n+                childComponent.options.router.use(childComponent.options.path, grandchildComponent.options.router);\n+\n+                // Recurse from here on down.\n+                that.connectDirectDescendants(grandchildComponent, childPath + \".\" + grandchildNickname);\n+            }\n+            else if (fluid.hasGrade(grandchildComponent.options, \"gpii.express.middleware\")) {\n+                if (childComponent.options.router) {\n+                    // We have to wire our children in with our path to preserve relative pathing, so that their router will begin with our path.\n+                    childComponent.options.router.use(childComponent.options.path, grandchildComponent.getMiddlewareFunction());\n+                }\n+                else {\n+                    throw(new Error({message: \"A component must expose a router in order to work with child middleware components.\"}));\n+                }\n+            }\n+        }\n+    }\n+\n+    // After our child components are in place, wire the router to itself.\n+    //\n+    // This must be done here because we want to give children the chance to own part of the path before we take the rest over.\n+    //\n+    // The path and method have to be used here so that parameters will be parsed correctly.\n+    if (fluid.hasGrade(childComponent.options, \"gpii.express.router\")) {\n+        childComponent.options.router[childComponent.options.method](childComponent.options.path, childComponent.getRouterFunction());\n+    }\n+};\n+\n+gpii.express.init = function(that) {\n+    if (!that.options.config || !that.options.config.express) {\n+        console.error(\"Cannot initialize express because you have not supplied a 'config' option.\");\n+        return;\n+    }\n+\n+    var express  = require(\"express\");\n+    that.express = express();\n+\n+    // Wire together all routers and components, beginning with ourselves\n+    for (var a = 0; a < that.options.members.directChildrenOfInterest.length; a++) {\n+        var directChildNickname = that.options.members.directChildrenOfInterest[a];\n+        var childComponent      = that[directChildNickname];\n+        if (fluid.hasGrade(childComponent.options, \"gpii.express.router\")) {\n+            // The router has to wire its own paths to preserve methods and path variables.\n+            // We just \"use\" it at the root level, and let it do the rest.\n+            that.express.use(\"/\", childComponent.options.router);\n+        }\n+        else if (fluid.hasGrade(childComponent.options, \"gpii.express.middleware\")) {\n+            that.express.use(childComponent.getMiddlewareFunction());\n+        }\n+\n+        // Recurse from here on down.\n+        that.connectDirectDescendants(childComponent, directChildNickname);\n+    }\n+\n+    that.express.set(\"port\", that.options.config.express.port);","path":"src/js/express.js","position":114,"original_position":114,"commit_id":"60aa3444cf15dbccfa7727c957b4ac8c55bfd39f","original_commit_id":"60aa3444cf15dbccfa7727c957b4ac8c55bfd39f","user":{"login":"amb26","id":561418,"avatar_url":"https://avatars.githubusercontent.com/u/561418?v=3","gravatar_id":"","url":"https://api.github.com/users/amb26","html_url":"https://github.com/amb26","followers_url":"https://api.github.com/users/amb26/followers","following_url":"https://api.github.com/users/amb26/following{/other_user}","gists_url":"https://api.github.com/users/amb26/gists{/gist_id}","starred_url":"https://api.github.com/users/amb26/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/amb26/subscriptions","organizations_url":"https://api.github.com/users/amb26/orgs","repos_url":"https://api.github.com/users/amb26/repos","events_url":"https://api.github.com/users/amb26/events{/privacy}","received_events_url":"https://api.github.com/users/amb26/received_events","type":"User","site_admin":false},"body":"Hoist repeated reference to \"port\" to a local variable","created_at":"2015-03-11T19:42:50Z","updated_at":"2015-03-11T19:42:50Z","html_url":"https://github.com/GPII/gpii-express/pull/2#discussion_r26247919","pull_request_url":"https://api.github.com/repos/GPII/gpii-express/pulls/2","_links":{"self":{"href":"https://api.github.com/repos/GPII/gpii-express/pulls/comments/26247919"},"html":{"href":"https://github.com/GPII/gpii-express/pull/2#discussion_r26247919"},"pull_request":{"href":"https://api.github.com/repos/GPII/gpii-express/pulls/2"}}},"pull_request":{"url":"https://api.github.com/repos/GPII/gpii-express/pulls/2","id":30860001,"html_url":"https://github.com/GPII/gpii-express/pull/2","diff_url":"https://github.com/GPII/gpii-express/pull/2.diff","patch_url":"https://github.com/GPII/gpii-express/pull/2.patch","issue_url":"https://api.github.com/repos/GPII/gpii-express/issues/2","number":2,"state":"open","locked":false,"title":"Second review of gpii.express module...","user":{"login":"the-t-in-rtf","id":5765222,"avatar_url":"https://avatars.githubusercontent.com/u/5765222?v=3","gravatar_id":"","url":"https://api.github.com/users/the-t-in-rtf","html_url":"https://github.com/the-t-in-rtf","followers_url":"https://api.github.com/users/the-t-in-rtf/followers","following_url":"https://api.github.com/users/the-t-in-rtf/following{/other_user}","gists_url":"https://api.github.com/users/the-t-in-rtf/gists{/gist_id}","starred_url":"https://api.github.com/users/the-t-in-rtf/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/the-t-in-rtf/subscriptions","organizations_url":"https://api.github.com/users/the-t-in-rtf/orgs","repos_url":"https://api.github.com/users/the-t-in-rtf/repos","events_url":"https://api.github.com/users/the-t-in-rtf/events{/privacy}","received_events_url":"https://api.github.com/users/the-t-in-rtf/received_events","type":"User","site_admin":false},"body":"I have completed another round of updates since our last discussion, and am submitting my work for review.\r\n\r\nThe biggest change is that gpii.express is now responsible for wiring all middleware and components together.","created_at":"2015-03-10T15:20:27Z","updated_at":"2015-03-11T19:42:50Z","closed_at":null,"merged_at":null,"merge_commit_sha":"1a646aa9b45bc08c7617a9df92a5dda3f5af3f3c","assignee":{"login":"amb26","id":561418,"avatar_url":"https://avatars.githubusercontent.com/u/561418?v=3","gravatar_id":"","url":"https://api.github.com/users/amb26","html_url":"https://github.com/amb26","followers_url":"https://api.github.com/users/amb26/followers","following_url":"https://api.github.com/users/amb26/following{/other_user}","gists_url":"https://api.github.com/users/amb26/gists{/gist_id}","starred_url":"https://api.github.com/users/amb26/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/amb26/subscriptions","organizations_url":"https://api.github.com/users/amb26/orgs","repos_url":"https://api.github.com/users/amb26/repos","events_url":"https://api.github.com/users/amb26/events{/privacy}","received_events_url":"https://api.github.com/users/amb26/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/GPII/gpii-express/pulls/2/commits","review_comments_url":"https://api.github.com/repos/GPII/gpii-express/pulls/2/comments","review_comment_url":"https://api.github.com/repos/GPII/gpii-express/pulls/comments{/number}","comments_url":"https://api.github.com/repos/GPII/gpii-express/issues/2/comments","statuses_url":"https://api.github.com/repos/GPII/gpii-express/statuses/60aa3444cf15dbccfa7727c957b4ac8c55bfd39f","head":{"label":"the-t-in-rtf:second-review","ref":"second-review","sha":"60aa3444cf15dbccfa7727c957b4ac8c55bfd39f","user":{"login":"the-t-in-rtf","id":5765222,"avatar_url":"https://avatars.githubusercontent.com/u/5765222?v=3","gravatar_id":"","url":"https://api.github.com/users/the-t-in-rtf","html_url":"https://github.com/the-t-in-rtf","followers_url":"https://api.github.com/users/the-t-in-rtf/followers","following_url":"https://api.github.com/users/the-t-in-rtf/following{/other_user}","gists_url":"https://api.github.com/users/the-t-in-rtf/gists{/gist_id}","starred_url":"https://api.github.com/users/the-t-in-rtf/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/the-t-in-rtf/subscriptions","organizations_url":"https://api.github.com/users/the-t-in-rtf/orgs","repos_url":"https://api.github.com/users/the-t-in-rtf/repos","events_url":"https://api.github.com/users/the-t-in-rtf/events{/privacy}","received_events_url":"https://api.github.com/users/the-t-in-rtf/received_events","type":"User","site_admin":false},"repo":{"id":30924618,"name":"gpii-express","full_name":"the-t-in-rtf/gpii-express","owner":{"login":"the-t-in-rtf","id":5765222,"avatar_url":"https://avatars.githubusercontent.com/u/5765222?v=3","gravatar_id":"","url":"https://api.github.com/users/the-t-in-rtf","html_url":"https://github.com/the-t-in-rtf","followers_url":"https://api.github.com/users/the-t-in-rtf/followers","following_url":"https://api.github.com/users/the-t-in-rtf/following{/other_user}","gists_url":"https://api.github.com/users/the-t-in-rtf/gists{/gist_id}","starred_url":"https://api.github.com/users/the-t-in-rtf/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/the-t-in-rtf/subscriptions","organizations_url":"https://api.github.com/users/the-t-in-rtf/orgs","repos_url":"https://api.github.com/users/the-t-in-rtf/repos","events_url":"https://api.github.com/users/the-t-in-rtf/events{/privacy}","received_events_url":"https://api.github.com/users/the-t-in-rtf/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/the-t-in-rtf/gpii-express","description":"A fluid module to load express.js","fork":true,"url":"https://api.github.com/repos/the-t-in-rtf/gpii-express","forks_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/forks","keys_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/keys{/key_id}","collaborators_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/teams","hooks_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/hooks","issue_events_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/issues/events{/number}","events_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/events","assignees_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/assignees{/user}","branches_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/branches{/branch}","tags_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/tags","blobs_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/git/refs{/sha}","trees_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/git/trees{/sha}","statuses_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/statuses/{sha}","languages_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/languages","stargazers_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/stargazers","contributors_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/contributors","subscribers_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/subscribers","subscription_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/subscription","commits_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/commits{/sha}","git_commits_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/git/commits{/sha}","comments_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/comments{/number}","issue_comment_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/issues/comments{/number}","contents_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/contents/{+path}","compare_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/compare/{base}...{head}","merges_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/merges","archive_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/downloads","issues_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/issues{/number}","pulls_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/pulls{/number}","milestones_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/milestones{/number}","notifications_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/labels{/name}","releases_url":"https://api.github.com/repos/the-t-in-rtf/gpii-express/releases{/id}","created_at":"2015-02-17T16:02:26Z","updated_at":"2015-03-03T15:50:27Z","pushed_at":"2015-03-10T15:17:02Z","git_url":"git://github.com/the-t-in-rtf/gpii-express.git","ssh_url":"git@github.com:the-t-in-rtf/gpii-express.git","clone_url":"https://github.com/the-t-in-rtf/gpii-express.git","svn_url":"https://github.com/the-t-in-rtf/gpii-express","homepage":null,"size":163,"stargazers_count":0,"watchers_count":0,"language":"JavaScript","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"GPII:master","ref":"master","sha":"bb88b9306593c8cec5189f0227c6899b9d346a03","user":{"login":"GPII","id":1343050,"avatar_url":"https://avatars.githubusercontent.com/u/1343050?v=3","gravatar_id":"","url":"https://api.github.com/users/GPII","html_url":"https://github.com/GPII","followers_url":"https://api.github.com/users/GPII/followers","following_url":"https://api.github.com/users/GPII/following{/other_user}","gists_url":"https://api.github.com/users/GPII/gists{/gist_id}","starred_url":"https://api.github.com/users/GPII/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/GPII/subscriptions","organizations_url":"https://api.github.com/users/GPII/orgs","repos_url":"https://api.github.com/users/GPII/repos","events_url":"https://api.github.com/users/GPII/events{/privacy}","received_events_url":"https://api.github.com/users/GPII/received_events","type":"Organization","site_admin":false},"repo":{"id":30625709,"name":"gpii-express","full_name":"GPII/gpii-express","owner":{"login":"GPII","id":1343050,"avatar_url":"https://avatars.githubusercontent.com/u/1343050?v=3","gravatar_id":"","url":"https://api.github.com/users/GPII","html_url":"https://github.com/GPII","followers_url":"https://api.github.com/users/GPII/followers","following_url":"https://api.github.com/users/GPII/following{/other_user}","gists_url":"https://api.github.com/users/GPII/gists{/gist_id}","starred_url":"https://api.github.com/users/GPII/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/GPII/subscriptions","organizations_url":"https://api.github.com/users/GPII/orgs","repos_url":"https://api.github.com/users/GPII/repos","events_url":"https://api.github.com/users/GPII/events{/privacy}","received_events_url":"https://api.github.com/users/GPII/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/GPII/gpii-express","description":"A fluid module to load express.js","fork":false,"url":"https://api.github.com/repos/GPII/gpii-express","forks_url":"https://api.github.com/repos/GPII/gpii-express/forks","keys_url":"https://api.github.com/repos/GPII/gpii-express/keys{/key_id}","collaborators_url":"https://api.github.com/repos/GPII/gpii-express/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/GPII/gpii-express/teams","hooks_url":"https://api.github.com/repos/GPII/gpii-express/hooks","issue_events_url":"https://api.github.com/repos/GPII/gpii-express/issues/events{/number}","events_url":"https://api.github.com/repos/GPII/gpii-express/events","assignees_url":"https://api.github.com/repos/GPII/gpii-express/assignees{/user}","branches_url":"https://api.github.com/repos/GPII/gpii-express/branches{/branch}","tags_url":"https://api.github.com/repos/GPII/gpii-express/tags","blobs_url":"https://api.github.com/repos/GPII/gpii-express/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/GPII/gpii-express/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/GPII/gpii-express/git/refs{/sha}","trees_url":"https://api.github.com/repos/GPII/gpii-express/git/trees{/sha}","statuses_url":"https://api.github.com/repos/GPII/gpii-express/statuses/{sha}","languages_url":"https://api.github.com/repos/GPII/gpii-express/languages","stargazers_url":"https://api.github.com/repos/GPII/gpii-express/stargazers","contributors_url":"https://api.github.com/repos/GPII/gpii-express/contributors","subscribers_url":"https://api.github.com/repos/GPII/gpii-express/subscribers","subscription_url":"https://api.github.com/repos/GPII/gpii-express/subscription","commits_url":"https://api.github.com/repos/GPII/gpii-express/commits{/sha}","git_commits_url":"https://api.github.com/repos/GPII/gpii-express/git/commits{/sha}","comments_url":"https://api.github.com/repos/GPII/gpii-express/comments{/number}","issue_comment_url":"https://api.github.com/repos/GPII/gpii-express/issues/comments{/number}","contents_url":"https://api.github.com/repos/GPII/gpii-express/contents/{+path}","compare_url":"https://api.github.com/repos/GPII/gpii-express/compare/{base}...{head}","merges_url":"https://api.github.com/repos/GPII/gpii-express/merges","archive_url":"https://api.github.com/repos/GPII/gpii-express/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/GPII/gpii-express/downloads","issues_url":"https://api.github.com/repos/GPII/gpii-express/issues{/number}","pulls_url":"https://api.github.com/repos/GPII/gpii-express/pulls{/number}","milestones_url":"https://api.github.com/repos/GPII/gpii-express/milestones{/number}","notifications_url":"https://api.github.com/repos/GPII/gpii-express/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/GPII/gpii-express/labels{/name}","releases_url":"https://api.github.com/repos/GPII/gpii-express/releases{/id}","created_at":"2015-02-11T02:12:46Z","updated_at":"2015-02-11T02:12:46Z","pushed_at":"2015-02-13T16:56:06Z","git_url":"git://github.com/GPII/gpii-express.git","ssh_url":"git@github.com:GPII/gpii-express.git","clone_url":"https://github.com/GPII/gpii-express.git","svn_url":"https://github.com/GPII/gpii-express","homepage":null,"size":117,"stargazers_count":0,"watchers_count":0,"language":null,"has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":2,"mirror_url":null,"open_issues_count":1,"forks":2,"open_issues":1,"watchers":0,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/GPII/gpii-express/pulls/2"},"html":{"href":"https://github.com/GPII/gpii-express/pull/2"},"issue":{"href":"https://api.github.com/repos/GPII/gpii-express/issues/2"},"comments":{"href":"https://api.github.com/repos/GPII/gpii-express/issues/2/comments"},"review_comments":{"href":"https://api.github.com/repos/GPII/gpii-express/pulls/2/comments"},"review_comment":{"href":"https://api.github.com/repos/GPII/gpii-express/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/GPII/gpii-express/pulls/2/commits"},"statuses":{"href":"https://api.github.com/repos/GPII/gpii-express/statuses/60aa3444cf15dbccfa7727c957b4ac8c55bfd39f"}}}}