{"action":"created","comment":{"url":"https://api.github.com/repos/gatsbyjs/gatsby/pulls/comments/166716160","pull_request_review_id":94824483,"id":166716160,"diff_hunk":"@@ -6,10 +6,45 @@\n \n const apis = require(`./api-ssr-docs`)\n \n-module.exports = (api, args, defaultReturn) => {\n+/**\n+ * Some apis should only be implemented once. Given a list of plugins, and an\n+ * `api` to check, this will return [] for apis that are implemented 1 or 0 times.\n+ *\n+ * For apis that have been implemented multiple times, return an array of paths\n+ * pointing to the file implementing `api`.\n+ *\n+ * @param {array} pluginList\n+ * @param {string} api\n+ */\n+const duplicatedApis = (pluginList, api) => {\n+  let implementsApi = []\n+\n+  pluginList.forEach(p => {\n+    if (p.plugin[api]) implementsApi.push(p.path)\n+  })\n+\n+  if (implementsApi.length < 2) return [] // no dupes\n+  return implementsApi // paths to dupes\n+}\n+\n+// Run the specified api in any plugins that have implemented it\n+const apiRunner = ({ api, args, defaultReturn, checkDupes = false }) => {\n   if (!apis[api]) {\n     console.log(`This API doesn't exist`, api)\n   }\n+\n+  if (checkDupes) {\n+    const dupes = duplicatedApis(plugins, api)\n+    if (dupes.length > 0) {\n+      let m = `\\nThe \"${api}\" api has been implemented multiple times. Only the last implementation will be used.`\n+      let m2 = `This is probably an error, see https://github.com/gatsbyjs/gatsby/issues/2005#issuecomment-326787567 for workarounds.`","path":"packages/gatsby/cache-dir/api-runner-ssr.js","position":36,"original_position":36,"commit_id":"d1d8e36e244b5be94486d7c4aca3a59cb72e5c60","original_commit_id":"d1d8e36e244b5be94486d7c4aca3a59cb72e5c60","user":{"login":"KyleAMathews","id":71047,"avatar_url":"https://avatars3.githubusercontent.com/u/71047?v=4","gravatar_id":"","url":"https://api.github.com/users/KyleAMathews","html_url":"https://github.com/KyleAMathews","followers_url":"https://api.github.com/users/KyleAMathews/followers","following_url":"https://api.github.com/users/KyleAMathews/following{/other_user}","gists_url":"https://api.github.com/users/KyleAMathews/gists{/gist_id}","starred_url":"https://api.github.com/users/KyleAMathews/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/KyleAMathews/subscriptions","organizations_url":"https://api.github.com/users/KyleAMathews/orgs","repos_url":"https://api.github.com/users/KyleAMathews/repos","events_url":"https://api.github.com/users/KyleAMathews/events{/privacy}","received_events_url":"https://api.github.com/users/KyleAMathews/received_events","type":"User","site_admin":false},"body":"Oh, you already said you were going to do this :-)","created_at":"2018-02-07T18:46:48Z","updated_at":"2018-02-07T18:46:48Z","html_url":"https://github.com/gatsbyjs/gatsby/pull/3889#discussion_r166716160","pull_request_url":"https://api.github.com/repos/gatsbyjs/gatsby/pulls/3889","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/gatsbyjs/gatsby/pulls/comments/166716160"},"html":{"href":"https://github.com/gatsbyjs/gatsby/pull/3889#discussion_r166716160"},"pull_request":{"href":"https://api.github.com/repos/gatsbyjs/gatsby/pulls/3889"}},"in_reply_to_id":166714656},"pull_request":{"url":"https://api.github.com/repos/gatsbyjs/gatsby/pulls/3889","id":167688587,"html_url":"https://github.com/gatsbyjs/gatsby/pull/3889","diff_url":"https://github.com/gatsbyjs/gatsby/pull/3889.diff","patch_url":"https://github.com/gatsbyjs/gatsby/pull/3889.patch","issue_url":"https://api.github.com/repos/gatsbyjs/gatsby/issues/3889","number":3889,"state":"open","locked":false,"title":"Warn when implementing apis twice","user":{"login":"m-allanson","id":381801,"avatar_url":"https://avatars1.githubusercontent.com/u/381801?v=4","gravatar_id":"","url":"https://api.github.com/users/m-allanson","html_url":"https://github.com/m-allanson","followers_url":"https://api.github.com/users/m-allanson/followers","following_url":"https://api.github.com/users/m-allanson/following{/other_user}","gists_url":"https://api.github.com/users/m-allanson/gists{/gist_id}","starred_url":"https://api.github.com/users/m-allanson/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/m-allanson/subscriptions","organizations_url":"https://api.github.com/users/m-allanson/orgs","repos_url":"https://api.github.com/users/m-allanson/repos","events_url":"https://api.github.com/users/m-allanson/events{/privacy}","received_events_url":"https://api.github.com/users/m-allanson/received_events","type":"User","site_admin":false},"body":"This has come up a whole bunch of times, see #2005, #2963, #3231, #2578 (there might be more).\r\n\r\nNow when implementing `replaceRenderer` multiple times, you'll see a warning in the console.\r\n\r\nStill to do (as a separate PR?):\r\n\r\nThe warning is output multiple times, which is a bit messy, but an improvement on no output. \r\n\r\nAdd a dedicated docs page demonstrating how to fix this. For now it points to @akadop's [comment here](https://github.com/gatsbyjs/gatsby/issues/2005#issuecomment-326787567)\r\n\r\nThe format of the message could be improved, currently it looks like:\r\n\r\n```\r\nThe \"replaceRenderer\" api has been implemented multiple times. Only the last implementation will be used.\r\nThis is probably an error, see https://github.com/gatsbyjs/gatsby/issues/2005#issuecomment-326787567 for workarounds.\r\nCheck the following files for \"replaceRenderer\" implementations:\r\n/path/to/my/splendid/website/node_modules/gatsby-plugin-styled-components/gatsby-ssr.js\r\n/path/to/my/splendid/website/gatsby-ssr.js\r\n```","created_at":"2018-02-07T13:11:43Z","updated_at":"2018-02-07T18:46:48Z","closed_at":null,"merged_at":null,"merge_commit_sha":"004680b3d3d131dd4b04982096f9c5542980a5e6","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"milestone":null,"commits_url":"https://api.github.com/repos/gatsbyjs/gatsby/pulls/3889/commits","review_comments_url":"https://api.github.com/repos/gatsbyjs/gatsby/pulls/3889/comments","review_comment_url":"https://api.github.com/repos/gatsbyjs/gatsby/pulls/comments{/number}","comments_url":"https://api.github.com/repos/gatsbyjs/gatsby/issues/3889/comments","statuses_url":"https://api.github.com/repos/gatsbyjs/gatsby/statuses/d1d8e36e244b5be94486d7c4aca3a59cb72e5c60","head":{"label":"m-allanson:topics/warn-duplicate-apis","ref":"topics/warn-duplicate-apis","sha":"d1d8e36e244b5be94486d7c4aca3a59cb72e5c60","user":{"login":"m-allanson","id":381801,"avatar_url":"https://avatars1.githubusercontent.com/u/381801?v=4","gravatar_id":"","url":"https://api.github.com/users/m-allanson","html_url":"https://github.com/m-allanson","followers_url":"https://api.github.com/users/m-allanson/followers","following_url":"https://api.github.com/users/m-allanson/following{/other_user}","gists_url":"https://api.github.com/users/m-allanson/gists{/gist_id}","starred_url":"https://api.github.com/users/m-allanson/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/m-allanson/subscriptions","organizations_url":"https://api.github.com/users/m-allanson/orgs","repos_url":"https://api.github.com/users/m-allanson/repos","events_url":"https://api.github.com/users/m-allanson/events{/privacy}","received_events_url":"https://api.github.com/users/m-allanson/received_events","type":"User","site_admin":false},"repo":{"id":105745880,"name":"gatsby","full_name":"m-allanson/gatsby","owner":{"login":"m-allanson","id":381801,"avatar_url":"https://avatars1.githubusercontent.com/u/381801?v=4","gravatar_id":"","url":"https://api.github.com/users/m-allanson","html_url":"https://github.com/m-allanson","followers_url":"https://api.github.com/users/m-allanson/followers","following_url":"https://api.github.com/users/m-allanson/following{/other_user}","gists_url":"https://api.github.com/users/m-allanson/gists{/gist_id}","starred_url":"https://api.github.com/users/m-allanson/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/m-allanson/subscriptions","organizations_url":"https://api.github.com/users/m-allanson/orgs","repos_url":"https://api.github.com/users/m-allanson/repos","events_url":"https://api.github.com/users/m-allanson/events{/privacy}","received_events_url":"https://api.github.com/users/m-allanson/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/m-allanson/gatsby","description":"⚛️📄🚀 Blazing fast static site generator for React","fork":true,"url":"https://api.github.com/repos/m-allanson/gatsby","forks_url":"https://api.github.com/repos/m-allanson/gatsby/forks","keys_url":"https://api.github.com/repos/m-allanson/gatsby/keys{/key_id}","collaborators_url":"https://api.github.com/repos/m-allanson/gatsby/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/m-allanson/gatsby/teams","hooks_url":"https://api.github.com/repos/m-allanson/gatsby/hooks","issue_events_url":"https://api.github.com/repos/m-allanson/gatsby/issues/events{/number}","events_url":"https://api.github.com/repos/m-allanson/gatsby/events","assignees_url":"https://api.github.com/repos/m-allanson/gatsby/assignees{/user}","branches_url":"https://api.github.com/repos/m-allanson/gatsby/branches{/branch}","tags_url":"https://api.github.com/repos/m-allanson/gatsby/tags","blobs_url":"https://api.github.com/repos/m-allanson/gatsby/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/m-allanson/gatsby/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/m-allanson/gatsby/git/refs{/sha}","trees_url":"https://api.github.com/repos/m-allanson/gatsby/git/trees{/sha}","statuses_url":"https://api.github.com/repos/m-allanson/gatsby/statuses/{sha}","languages_url":"https://api.github.com/repos/m-allanson/gatsby/languages","stargazers_url":"https://api.github.com/repos/m-allanson/gatsby/stargazers","contributors_url":"https://api.github.com/repos/m-allanson/gatsby/contributors","subscribers_url":"https://api.github.com/repos/m-allanson/gatsby/subscribers","subscription_url":"https://api.github.com/repos/m-allanson/gatsby/subscription","commits_url":"https://api.github.com/repos/m-allanson/gatsby/commits{/sha}","git_commits_url":"https://api.github.com/repos/m-allanson/gatsby/git/commits{/sha}","comments_url":"https://api.github.com/repos/m-allanson/gatsby/comments{/number}","issue_comment_url":"https://api.github.com/repos/m-allanson/gatsby/issues/comments{/number}","contents_url":"https://api.github.com/repos/m-allanson/gatsby/contents/{+path}","compare_url":"https://api.github.com/repos/m-allanson/gatsby/compare/{base}...{head}","merges_url":"https://api.github.com/repos/m-allanson/gatsby/merges","archive_url":"https://api.github.com/repos/m-allanson/gatsby/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/m-allanson/gatsby/downloads","issues_url":"https://api.github.com/repos/m-allanson/gatsby/issues{/number}","pulls_url":"https://api.github.com/repos/m-allanson/gatsby/pulls{/number}","milestones_url":"https://api.github.com/repos/m-allanson/gatsby/milestones{/number}","notifications_url":"https://api.github.com/repos/m-allanson/gatsby/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/m-allanson/gatsby/labels{/name}","releases_url":"https://api.github.com/repos/m-allanson/gatsby/releases{/id}","deployments_url":"https://api.github.com/repos/m-allanson/gatsby/deployments","created_at":"2017-10-04T08:20:45Z","updated_at":"2017-10-04T08:20:50Z","pushed_at":"2018-02-07T16:33:46Z","git_url":"git://github.com/m-allanson/gatsby.git","ssh_url":"git@github.com:m-allanson/gatsby.git","clone_url":"https://github.com/m-allanson/gatsby.git","svn_url":"https://github.com/m-allanson/gatsby","homepage":"https://www.gatsbyjs.org","size":311759,"stargazers_count":0,"watchers_count":0,"language":"JavaScript","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":1,"license":null,"forks":0,"open_issues":1,"watchers":0,"default_branch":"master"}},"base":{"label":"gatsbyjs:master","ref":"master","sha":"617790eb1adf1c7ffc514601d5fb8f9c1697b80f","user":{"login":"gatsbyjs","id":12551863,"avatar_url":"https://avatars1.githubusercontent.com/u/12551863?v=4","gravatar_id":"","url":"https://api.github.com/users/gatsbyjs","html_url":"https://github.com/gatsbyjs","followers_url":"https://api.github.com/users/gatsbyjs/followers","following_url":"https://api.github.com/users/gatsbyjs/following{/other_user}","gists_url":"https://api.github.com/users/gatsbyjs/gists{/gist_id}","starred_url":"https://api.github.com/users/gatsbyjs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gatsbyjs/subscriptions","organizations_url":"https://api.github.com/users/gatsbyjs/orgs","repos_url":"https://api.github.com/users/gatsbyjs/repos","events_url":"https://api.github.com/users/gatsbyjs/events{/privacy}","received_events_url":"https://api.github.com/users/gatsbyjs/received_events","type":"Organization","site_admin":false},"repo":{"id":36040894,"name":"gatsby","full_name":"gatsbyjs/gatsby","owner":{"login":"gatsbyjs","id":12551863,"avatar_url":"https://avatars1.githubusercontent.com/u/12551863?v=4","gravatar_id":"","url":"https://api.github.com/users/gatsbyjs","html_url":"https://github.com/gatsbyjs","followers_url":"https://api.github.com/users/gatsbyjs/followers","following_url":"https://api.github.com/users/gatsbyjs/following{/other_user}","gists_url":"https://api.github.com/users/gatsbyjs/gists{/gist_id}","starred_url":"https://api.github.com/users/gatsbyjs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gatsbyjs/subscriptions","organizations_url":"https://api.github.com/users/gatsbyjs/orgs","repos_url":"https://api.github.com/users/gatsbyjs/repos","events_url":"https://api.github.com/users/gatsbyjs/events{/privacy}","received_events_url":"https://api.github.com/users/gatsbyjs/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/gatsbyjs/gatsby","description":"⚛️📄🚀 Blazing fast static site generator for React","fork":false,"url":"https://api.github.com/repos/gatsbyjs/gatsby","forks_url":"https://api.github.com/repos/gatsbyjs/gatsby/forks","keys_url":"https://api.github.com/repos/gatsbyjs/gatsby/keys{/key_id}","collaborators_url":"https://api.github.com/repos/gatsbyjs/gatsby/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/gatsbyjs/gatsby/teams","hooks_url":"https://api.github.com/repos/gatsbyjs/gatsby/hooks","issue_events_url":"https://api.github.com/repos/gatsbyjs/gatsby/issues/events{/number}","events_url":"https://api.github.com/repos/gatsbyjs/gatsby/events","assignees_url":"https://api.github.com/repos/gatsbyjs/gatsby/assignees{/user}","branches_url":"https://api.github.com/repos/gatsbyjs/gatsby/branches{/branch}","tags_url":"https://api.github.com/repos/gatsbyjs/gatsby/tags","blobs_url":"https://api.github.com/repos/gatsbyjs/gatsby/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/gatsbyjs/gatsby/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/gatsbyjs/gatsby/git/refs{/sha}","trees_url":"https://api.github.com/repos/gatsbyjs/gatsby/git/trees{/sha}","statuses_url":"https://api.github.com/repos/gatsbyjs/gatsby/statuses/{sha}","languages_url":"https://api.github.com/repos/gatsbyjs/gatsby/languages","stargazers_url":"https://api.github.com/repos/gatsbyjs/gatsby/stargazers","contributors_url":"https://api.github.com/repos/gatsbyjs/gatsby/contributors","subscribers_url":"https://api.github.com/repos/gatsbyjs/gatsby/subscribers","subscription_url":"https://api.github.com/repos/gatsbyjs/gatsby/subscription","commits_url":"https://api.github.com/repos/gatsbyjs/gatsby/commits{/sha}","git_commits_url":"https://api.github.com/repos/gatsbyjs/gatsby/git/commits{/sha}","comments_url":"https://api.github.com/repos/gatsbyjs/gatsby/comments{/number}","issue_comment_url":"https://api.github.com/repos/gatsbyjs/gatsby/issues/comments{/number}","contents_url":"https://api.github.com/repos/gatsbyjs/gatsby/contents/{+path}","compare_url":"https://api.github.com/repos/gatsbyjs/gatsby/compare/{base}...{head}","merges_url":"https://api.github.com/repos/gatsbyjs/gatsby/merges","archive_url":"https://api.github.com/repos/gatsbyjs/gatsby/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/gatsbyjs/gatsby/downloads","issues_url":"https://api.github.com/repos/gatsbyjs/gatsby/issues{/number}","pulls_url":"https://api.github.com/repos/gatsbyjs/gatsby/pulls{/number}","milestones_url":"https://api.github.com/repos/gatsbyjs/gatsby/milestones{/number}","notifications_url":"https://api.github.com/repos/gatsbyjs/gatsby/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/gatsbyjs/gatsby/labels{/name}","releases_url":"https://api.github.com/repos/gatsbyjs/gatsby/releases{/id}","deployments_url":"https://api.github.com/repos/gatsbyjs/gatsby/deployments","created_at":"2015-05-21T22:43:05Z","updated_at":"2018-02-07T18:44:08Z","pushed_at":"2018-02-07T18:28:27Z","git_url":"git://github.com/gatsbyjs/gatsby.git","ssh_url":"git@github.com:gatsbyjs/gatsby.git","clone_url":"https://github.com/gatsbyjs/gatsby.git","svn_url":"https://github.com/gatsbyjs/gatsby","homepage":"https://www.gatsbyjs.org","size":313318,"stargazers_count":18545,"watchers_count":18545,"language":"JavaScript","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":1560,"mirror_url":null,"archived":false,"open_issues_count":464,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit"},"forks":1560,"open_issues":464,"watchers":18545,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/gatsbyjs/gatsby/pulls/3889"},"html":{"href":"https://github.com/gatsbyjs/gatsby/pull/3889"},"issue":{"href":"https://api.github.com/repos/gatsbyjs/gatsby/issues/3889"},"comments":{"href":"https://api.github.com/repos/gatsbyjs/gatsby/issues/3889/comments"},"review_comments":{"href":"https://api.github.com/repos/gatsbyjs/gatsby/pulls/3889/comments"},"review_comment":{"href":"https://api.github.com/repos/gatsbyjs/gatsby/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/gatsbyjs/gatsby/pulls/3889/commits"},"statuses":{"href":"https://api.github.com/repos/gatsbyjs/gatsby/statuses/d1d8e36e244b5be94486d7c4aca3a59cb72e5c60"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"KyleAMathews"}}