{"action":"created","comment":{"url":"https://api.github.com/repos/Polymer/prpl-server-node/pulls/comments/115561596","pull_request_review_id":37100472,"id":115561596,"diff_hunk":"@@ -0,0 +1,117 @@\n+/**\n+ * @license\n+ * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.\n+ * This code may only be used under the BSD style license found at\n+ * http://polymer.github.io/LICENSE.txt\n+ * The complete set of authors may be found at\n+ * http://polymer.github.io/AUTHORS.txt\n+ * The complete set of contributors may be found at\n+ * http://polymer.github.io/CONTRIBUTORS.txt\n+ * Code distributed by Google as part of the polymer project is also\n+ * subject to an additional IP rights grant found at\n+ * http://polymer.github.io/PATENTS.txt\n+ */\n+\n+import {UAParser} from 'ua-parser-js';\n+\n+/**\n+ * A browser feature.\n+ */\n+export type Capability =\n+    // ECMAScript 2015 (aka ES6).\n+    'es2015' |\n+    // HTTP/2 Server Push.\n+    'push';\n+\n+/**\n+ * Return a capability map for the given user agent string.\n+ */\n+export function capabilities(userAgent: string):\n+    {[key in Capability]: boolean} {\n+  const ua = new UAParser(userAgent);\n+  const supports = browserCapabilities[ua.getBrowser().name];","path":"src/capabilities.ts","position":32,"original_position":32,"commit_id":"64c549c3ba2d527fb857a5e3f5f559d930c7bce5","original_commit_id":"64c549c3ba2d527fb857a5e3f5f559d930c7bce5","user":{"login":"justinfagnani","id":522948,"avatar_url":"https://avatars3.githubusercontent.com/u/522948?v=3","gravatar_id":"","url":"https://api.github.com/users/justinfagnani","html_url":"https://github.com/justinfagnani","followers_url":"https://api.github.com/users/justinfagnani/followers","following_url":"https://api.github.com/users/justinfagnani/following{/other_user}","gists_url":"https://api.github.com/users/justinfagnani/gists{/gist_id}","starred_url":"https://api.github.com/users/justinfagnani/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/justinfagnani/subscriptions","organizations_url":"https://api.github.com/users/justinfagnani/orgs","repos_url":"https://api.github.com/users/justinfagnani/repos","events_url":"https://api.github.com/users/justinfagnani/events{/privacy}","received_events_url":"https://api.github.com/users/justinfagnani/received_events","type":"User","site_admin":false},"body":"How about a function like:\r\n\r\n```ts\r\nfunction testPredicates<K, T>(predicates: Map<K, (T) => boolean>, o: T): Set<K> {\r\n  const passedTests = [];\r\n  for (const [key, predicate] of predicates.entries()) {\r\n    if (predicate(o)) {\r\n      passedTests.push(key);\r\n    }\r\n  }\r\n  return new Set(passedTests);\r\n}\r\n```\r\nand \r\n\r\n```ts\r\nreturn testPredicates(browserCapabilities.get(ua.getBrowser().name) || new Map(), ua);\r\n```\r\n\r\nThis doesn't make it any shorter obviously, but it supports any predicates in the configuration.","created_at":"2017-05-09T18:12:44Z","updated_at":"2017-05-09T18:13:02Z","html_url":"https://github.com/Polymer/prpl-server-node/pull/5#discussion_r115561596","pull_request_url":"https://api.github.com/repos/Polymer/prpl-server-node/pulls/5","_links":{"self":{"href":"https://api.github.com/repos/Polymer/prpl-server-node/pulls/comments/115561596"},"html":{"href":"https://github.com/Polymer/prpl-server-node/pull/5#discussion_r115561596"},"pull_request":{"href":"https://api.github.com/repos/Polymer/prpl-server-node/pulls/5"}}},"pull_request":{"url":"https://api.github.com/repos/Polymer/prpl-server-node/pulls/5","id":119601891,"html_url":"https://github.com/Polymer/prpl-server-node/pull/5","diff_url":"https://github.com/Polymer/prpl-server-node/pull/5.diff","patch_url":"https://github.com/Polymer/prpl-server-node/pull/5.patch","issue_url":"https://api.github.com/repos/Polymer/prpl-server-node/issues/5","number":5,"state":"open","locked":false,"title":"Add a library for mapping user agents to browser capabilities.","user":{"login":"aomarks","id":48894,"avatar_url":"https://avatars3.githubusercontent.com/u/48894?v=3","gravatar_id":"","url":"https://api.github.com/users/aomarks","html_url":"https://github.com/aomarks","followers_url":"https://api.github.com/users/aomarks/followers","following_url":"https://api.github.com/users/aomarks/following{/other_user}","gists_url":"https://api.github.com/users/aomarks/gists{/gist_id}","starred_url":"https://api.github.com/users/aomarks/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aomarks/subscriptions","organizations_url":"https://api.github.com/users/aomarks/orgs","repos_url":"https://api.github.com/users/aomarks/repos","events_url":"https://api.github.com/users/aomarks/events{/privacy}","received_events_url":"https://api.github.com/users/aomarks/received_events","type":"User","site_admin":false},"body":"A more complicated version of the ES2015 sniffer in Polyserve.\r\n\r\nThe idea is to use these capabilities as annotations on builds. E.g. to decide what build to serve, we take an ordered list of builds, and choose the first one for which all tagged capability requirements are satisfied.\r\n\r\nKnows about ES2015 and HTTP/2 Push. Later we can add e.g. Custom Elements as a capability here, and use that to choose the Polyfill serverside.","created_at":"2017-05-09T07:49:06Z","updated_at":"2017-05-09T18:13:02Z","closed_at":null,"merged_at":null,"merge_commit_sha":"cb22897fb2d194decf2a3cf31d55df03fa42cdb2","assignee":null,"assignees":[],"requested_reviewers":[{"login":"usergenic","id":578,"avatar_url":"https://avatars1.githubusercontent.com/u/578?v=3","gravatar_id":"","url":"https://api.github.com/users/usergenic","html_url":"https://github.com/usergenic","followers_url":"https://api.github.com/users/usergenic/followers","following_url":"https://api.github.com/users/usergenic/following{/other_user}","gists_url":"https://api.github.com/users/usergenic/gists{/gist_id}","starred_url":"https://api.github.com/users/usergenic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/usergenic/subscriptions","organizations_url":"https://api.github.com/users/usergenic/orgs","repos_url":"https://api.github.com/users/usergenic/repos","events_url":"https://api.github.com/users/usergenic/events{/privacy}","received_events_url":"https://api.github.com/users/usergenic/received_events","type":"User","site_admin":false},{"login":"rictic","id":1659,"avatar_url":"https://avatars0.githubusercontent.com/u/1659?v=3","gravatar_id":"","url":"https://api.github.com/users/rictic","html_url":"https://github.com/rictic","followers_url":"https://api.github.com/users/rictic/followers","following_url":"https://api.github.com/users/rictic/following{/other_user}","gists_url":"https://api.github.com/users/rictic/gists{/gist_id}","starred_url":"https://api.github.com/users/rictic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rictic/subscriptions","organizations_url":"https://api.github.com/users/rictic/orgs","repos_url":"https://api.github.com/users/rictic/repos","events_url":"https://api.github.com/users/rictic/events{/privacy}","received_events_url":"https://api.github.com/users/rictic/received_events","type":"User","site_admin":false},{"login":"FredKSchott","id":622227,"avatar_url":"https://avatars2.githubusercontent.com/u/622227?v=3","gravatar_id":"","url":"https://api.github.com/users/FredKSchott","html_url":"https://github.com/FredKSchott","followers_url":"https://api.github.com/users/FredKSchott/followers","following_url":"https://api.github.com/users/FredKSchott/following{/other_user}","gists_url":"https://api.github.com/users/FredKSchott/gists{/gist_id}","starred_url":"https://api.github.com/users/FredKSchott/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/FredKSchott/subscriptions","organizations_url":"https://api.github.com/users/FredKSchott/orgs","repos_url":"https://api.github.com/users/FredKSchott/repos","events_url":"https://api.github.com/users/FredKSchott/events{/privacy}","received_events_url":"https://api.github.com/users/FredKSchott/received_events","type":"User","site_admin":false}],"milestone":null,"commits_url":"https://api.github.com/repos/Polymer/prpl-server-node/pulls/5/commits","review_comments_url":"https://api.github.com/repos/Polymer/prpl-server-node/pulls/5/comments","review_comment_url":"https://api.github.com/repos/Polymer/prpl-server-node/pulls/comments{/number}","comments_url":"https://api.github.com/repos/Polymer/prpl-server-node/issues/5/comments","statuses_url":"https://api.github.com/repos/Polymer/prpl-server-node/statuses/64c549c3ba2d527fb857a5e3f5f559d930c7bce5","head":{"label":"Polymer:capabilities","ref":"capabilities","sha":"64c549c3ba2d527fb857a5e3f5f559d930c7bce5","user":{"login":"Polymer","id":2159051,"avatar_url":"https://avatars0.githubusercontent.com/u/2159051?v=3","gravatar_id":"","url":"https://api.github.com/users/Polymer","html_url":"https://github.com/Polymer","followers_url":"https://api.github.com/users/Polymer/followers","following_url":"https://api.github.com/users/Polymer/following{/other_user}","gists_url":"https://api.github.com/users/Polymer/gists{/gist_id}","starred_url":"https://api.github.com/users/Polymer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Polymer/subscriptions","organizations_url":"https://api.github.com/users/Polymer/orgs","repos_url":"https://api.github.com/users/Polymer/repos","events_url":"https://api.github.com/users/Polymer/events{/privacy}","received_events_url":"https://api.github.com/users/Polymer/received_events","type":"Organization","site_admin":false},"repo":{"id":90314488,"name":"prpl-server-node","full_name":"Polymer/prpl-server-node","owner":{"login":"Polymer","id":2159051,"avatar_url":"https://avatars0.githubusercontent.com/u/2159051?v=3","gravatar_id":"","url":"https://api.github.com/users/Polymer","html_url":"https://github.com/Polymer","followers_url":"https://api.github.com/users/Polymer/followers","following_url":"https://api.github.com/users/Polymer/following{/other_user}","gists_url":"https://api.github.com/users/Polymer/gists{/gist_id}","starred_url":"https://api.github.com/users/Polymer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Polymer/subscriptions","organizations_url":"https://api.github.com/users/Polymer/orgs","repos_url":"https://api.github.com/users/Polymer/repos","events_url":"https://api.github.com/users/Polymer/events{/privacy}","received_events_url":"https://api.github.com/users/Polymer/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Polymer/prpl-server-node","description":"Node implementation of the PRPL pattern for serving Progressive Web Apps","fork":false,"url":"https://api.github.com/repos/Polymer/prpl-server-node","forks_url":"https://api.github.com/repos/Polymer/prpl-server-node/forks","keys_url":"https://api.github.com/repos/Polymer/prpl-server-node/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Polymer/prpl-server-node/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Polymer/prpl-server-node/teams","hooks_url":"https://api.github.com/repos/Polymer/prpl-server-node/hooks","issue_events_url":"https://api.github.com/repos/Polymer/prpl-server-node/issues/events{/number}","events_url":"https://api.github.com/repos/Polymer/prpl-server-node/events","assignees_url":"https://api.github.com/repos/Polymer/prpl-server-node/assignees{/user}","branches_url":"https://api.github.com/repos/Polymer/prpl-server-node/branches{/branch}","tags_url":"https://api.github.com/repos/Polymer/prpl-server-node/tags","blobs_url":"https://api.github.com/repos/Polymer/prpl-server-node/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Polymer/prpl-server-node/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Polymer/prpl-server-node/git/refs{/sha}","trees_url":"https://api.github.com/repos/Polymer/prpl-server-node/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Polymer/prpl-server-node/statuses/{sha}","languages_url":"https://api.github.com/repos/Polymer/prpl-server-node/languages","stargazers_url":"https://api.github.com/repos/Polymer/prpl-server-node/stargazers","contributors_url":"https://api.github.com/repos/Polymer/prpl-server-node/contributors","subscribers_url":"https://api.github.com/repos/Polymer/prpl-server-node/subscribers","subscription_url":"https://api.github.com/repos/Polymer/prpl-server-node/subscription","commits_url":"https://api.github.com/repos/Polymer/prpl-server-node/commits{/sha}","git_commits_url":"https://api.github.com/repos/Polymer/prpl-server-node/git/commits{/sha}","comments_url":"https://api.github.com/repos/Polymer/prpl-server-node/comments{/number}","issue_comment_url":"https://api.github.com/repos/Polymer/prpl-server-node/issues/comments{/number}","contents_url":"https://api.github.com/repos/Polymer/prpl-server-node/contents/{+path}","compare_url":"https://api.github.com/repos/Polymer/prpl-server-node/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Polymer/prpl-server-node/merges","archive_url":"https://api.github.com/repos/Polymer/prpl-server-node/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Polymer/prpl-server-node/downloads","issues_url":"https://api.github.com/repos/Polymer/prpl-server-node/issues{/number}","pulls_url":"https://api.github.com/repos/Polymer/prpl-server-node/pulls{/number}","milestones_url":"https://api.github.com/repos/Polymer/prpl-server-node/milestones{/number}","notifications_url":"https://api.github.com/repos/Polymer/prpl-server-node/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Polymer/prpl-server-node/labels{/name}","releases_url":"https://api.github.com/repos/Polymer/prpl-server-node/releases{/id}","deployments_url":"https://api.github.com/repos/Polymer/prpl-server-node/deployments","created_at":"2017-05-04T22:16:42Z","updated_at":"2017-05-09T15:00:09Z","pushed_at":"2017-05-09T07:54:14Z","git_url":"git://github.com/Polymer/prpl-server-node.git","ssh_url":"git@github.com:Polymer/prpl-server-node.git","clone_url":"https://github.com/Polymer/prpl-server-node.git","svn_url":"https://github.com/Polymer/prpl-server-node","homepage":null,"size":30,"stargazers_count":18,"watchers_count":18,"language":"TypeScript","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":2,"forks":0,"open_issues":2,"watchers":18,"default_branch":"master"}},"base":{"label":"Polymer:master","ref":"master","sha":"297155734cecb2628e98303103f113c28f1d0d3d","user":{"login":"Polymer","id":2159051,"avatar_url":"https://avatars0.githubusercontent.com/u/2159051?v=3","gravatar_id":"","url":"https://api.github.com/users/Polymer","html_url":"https://github.com/Polymer","followers_url":"https://api.github.com/users/Polymer/followers","following_url":"https://api.github.com/users/Polymer/following{/other_user}","gists_url":"https://api.github.com/users/Polymer/gists{/gist_id}","starred_url":"https://api.github.com/users/Polymer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Polymer/subscriptions","organizations_url":"https://api.github.com/users/Polymer/orgs","repos_url":"https://api.github.com/users/Polymer/repos","events_url":"https://api.github.com/users/Polymer/events{/privacy}","received_events_url":"https://api.github.com/users/Polymer/received_events","type":"Organization","site_admin":false},"repo":{"id":90314488,"name":"prpl-server-node","full_name":"Polymer/prpl-server-node","owner":{"login":"Polymer","id":2159051,"avatar_url":"https://avatars0.githubusercontent.com/u/2159051?v=3","gravatar_id":"","url":"https://api.github.com/users/Polymer","html_url":"https://github.com/Polymer","followers_url":"https://api.github.com/users/Polymer/followers","following_url":"https://api.github.com/users/Polymer/following{/other_user}","gists_url":"https://api.github.com/users/Polymer/gists{/gist_id}","starred_url":"https://api.github.com/users/Polymer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Polymer/subscriptions","organizations_url":"https://api.github.com/users/Polymer/orgs","repos_url":"https://api.github.com/users/Polymer/repos","events_url":"https://api.github.com/users/Polymer/events{/privacy}","received_events_url":"https://api.github.com/users/Polymer/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Polymer/prpl-server-node","description":"Node implementation of the PRPL pattern for serving Progressive Web Apps","fork":false,"url":"https://api.github.com/repos/Polymer/prpl-server-node","forks_url":"https://api.github.com/repos/Polymer/prpl-server-node/forks","keys_url":"https://api.github.com/repos/Polymer/prpl-server-node/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Polymer/prpl-server-node/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Polymer/prpl-server-node/teams","hooks_url":"https://api.github.com/repos/Polymer/prpl-server-node/hooks","issue_events_url":"https://api.github.com/repos/Polymer/prpl-server-node/issues/events{/number}","events_url":"https://api.github.com/repos/Polymer/prpl-server-node/events","assignees_url":"https://api.github.com/repos/Polymer/prpl-server-node/assignees{/user}","branches_url":"https://api.github.com/repos/Polymer/prpl-server-node/branches{/branch}","tags_url":"https://api.github.com/repos/Polymer/prpl-server-node/tags","blobs_url":"https://api.github.com/repos/Polymer/prpl-server-node/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Polymer/prpl-server-node/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Polymer/prpl-server-node/git/refs{/sha}","trees_url":"https://api.github.com/repos/Polymer/prpl-server-node/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Polymer/prpl-server-node/statuses/{sha}","languages_url":"https://api.github.com/repos/Polymer/prpl-server-node/languages","stargazers_url":"https://api.github.com/repos/Polymer/prpl-server-node/stargazers","contributors_url":"https://api.github.com/repos/Polymer/prpl-server-node/contributors","subscribers_url":"https://api.github.com/repos/Polymer/prpl-server-node/subscribers","subscription_url":"https://api.github.com/repos/Polymer/prpl-server-node/subscription","commits_url":"https://api.github.com/repos/Polymer/prpl-server-node/commits{/sha}","git_commits_url":"https://api.github.com/repos/Polymer/prpl-server-node/git/commits{/sha}","comments_url":"https://api.github.com/repos/Polymer/prpl-server-node/comments{/number}","issue_comment_url":"https://api.github.com/repos/Polymer/prpl-server-node/issues/comments{/number}","contents_url":"https://api.github.com/repos/Polymer/prpl-server-node/contents/{+path}","compare_url":"https://api.github.com/repos/Polymer/prpl-server-node/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Polymer/prpl-server-node/merges","archive_url":"https://api.github.com/repos/Polymer/prpl-server-node/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Polymer/prpl-server-node/downloads","issues_url":"https://api.github.com/repos/Polymer/prpl-server-node/issues{/number}","pulls_url":"https://api.github.com/repos/Polymer/prpl-server-node/pulls{/number}","milestones_url":"https://api.github.com/repos/Polymer/prpl-server-node/milestones{/number}","notifications_url":"https://api.github.com/repos/Polymer/prpl-server-node/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Polymer/prpl-server-node/labels{/name}","releases_url":"https://api.github.com/repos/Polymer/prpl-server-node/releases{/id}","deployments_url":"https://api.github.com/repos/Polymer/prpl-server-node/deployments","created_at":"2017-05-04T22:16:42Z","updated_at":"2017-05-09T15:00:09Z","pushed_at":"2017-05-09T07:54:14Z","git_url":"git://github.com/Polymer/prpl-server-node.git","ssh_url":"git@github.com:Polymer/prpl-server-node.git","clone_url":"https://github.com/Polymer/prpl-server-node.git","svn_url":"https://github.com/Polymer/prpl-server-node","homepage":null,"size":30,"stargazers_count":18,"watchers_count":18,"language":"TypeScript","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":2,"forks":0,"open_issues":2,"watchers":18,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/Polymer/prpl-server-node/pulls/5"},"html":{"href":"https://github.com/Polymer/prpl-server-node/pull/5"},"issue":{"href":"https://api.github.com/repos/Polymer/prpl-server-node/issues/5"},"comments":{"href":"https://api.github.com/repos/Polymer/prpl-server-node/issues/5/comments"},"review_comments":{"href":"https://api.github.com/repos/Polymer/prpl-server-node/pulls/5/comments"},"review_comment":{"href":"https://api.github.com/repos/Polymer/prpl-server-node/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/Polymer/prpl-server-node/pulls/5/commits"},"statuses":{"href":"https://api.github.com/repos/Polymer/prpl-server-node/statuses/64c549c3ba2d527fb857a5e3f5f559d930c7bce5"}}}}
{"actor":{"display_login":"justinfagnani"}}