{"action":"created","comment":{"url":"https://api.github.com/repos/elastic/kibana/pulls/comments/117793546","pull_request_review_id":39524785,"id":117793546,"diff_hunk":"@@ -0,0 +1,102 @@\n+import { resolve as resolveUrl, format as formatUrl } from 'url';\n+import { pick, partial } from 'lodash';\n+\n+import { SavedObject } from './saved_object';\n+\n+const join = (...uriComponents) => (\n+  uriComponents.filter(Boolean).map(encodeURIComponent).join('/')\n+);\n+\n+export class SavedObjectsClient {\n+  constructor($http, basePath, PromiseCtor = Promise) {\n+    this._$http = $http;\n+    this._apiBaseUrl = `${basePath}/api/saved_objects/`;\n+    this._PromiseCtor = PromiseCtor;\n+  }\n+\n+  get(type, id) {\n+    if (!type || !id) {\n+      return this._PromiseCtor.reject(new Error('requires type and id'));\n+    }\n+\n+    return this._request('GET', this._getUrl([type, id])).then(resp => {\n+      return new this.ObjectClass(resp);\n+    });\n+  }\n+\n+  delete(type, id) {\n+    if (!type || !id) {\n+      return this._PromiseCtor.reject(new Error('requires type and id'));\n+    }\n+\n+    return this._request('DELETE', this._getUrl([type, id]));\n+  }\n+\n+  update(type, id, attributes, { version } = {}) {\n+    if (!type || !id || !attributes) {\n+      return this._PromiseCtor.reject(new Error('requires type, id and attributes'));\n+    }\n+\n+    const body = {\n+      attributes,\n+      version\n+    };\n+\n+    return this._request('PUT', this._getUrl([type, id]), body);\n+  }\n+\n+  create(type, body) {\n+    if (!type || !body) {\n+      return this._PromiseCtor.reject(new Error('requires type and body'));\n+    }\n+\n+    const url = this._getUrl([type]);\n+\n+    return this._request('POST', url, body);\n+  }\n+\n+  find(options = {}) {\n+    const url = this._getUrl([options.type]);\n+    const validOptions = pick(options, ['from', 'size', 'fields', 'filter']);\n+\n+    return this._request('GET', url, validOptions).then(resp => {\n+      resp.data = resp.data.map(d => new this.ObjectClass(d));\n+      return resp;\n+    });\n+  }\n+\n+  get ObjectClass() {","path":"src/ui/public/saved_objects/saved_objects_client.js","position":null,"original_position":68,"commit_id":"9eb2efc54c2391725396279ba22a04c95eab9ec2","original_commit_id":"6148eaca6d5ff1879029c16c0d12da845d80a53a","user":{"login":"spalger","id":1329312,"avatar_url":"https://avatars2.githubusercontent.com/u/1329312?v=3","gravatar_id":"","url":"https://api.github.com/users/spalger","html_url":"https://github.com/spalger","followers_url":"https://api.github.com/users/spalger/followers","following_url":"https://api.github.com/users/spalger/following{/other_user}","gists_url":"https://api.github.com/users/spalger/gists{/gist_id}","starred_url":"https://api.github.com/users/spalger/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/spalger/subscriptions","organizations_url":"https://api.github.com/users/spalger/orgs","repos_url":"https://api.github.com/users/spalger/repos","events_url":"https://api.github.com/users/spalger/events{/privacy}","received_events_url":"https://api.github.com/users/spalger/received_events","type":"User","site_admin":false},"body":"Using a getter here returns a new constructor every time `ObjectClass` is accessed. Besides being somewhat wasteful of resources it also gives the illusion that\r\n\r\n```js\r\nsavedObjectInstance instanceof savedObjectsClient.ObjectClass\r\n```\r\n\r\nwill evaluate to true. IMO, we should just have something like this:\r\n\r\n```js\r\nclass SavedObjectsClient {\r\n  // ...\r\n  createSavedObject(options) {\r\n    return new SavedObject(this, options)\r\n  }\r\n}\r\n```","created_at":"2017-05-22T16:49:04Z","updated_at":"2017-05-22T16:53:44Z","html_url":"https://github.com/elastic/kibana/pull/11632#discussion_r117793546","pull_request_url":"https://api.github.com/repos/elastic/kibana/pulls/11632","_links":{"self":{"href":"https://api.github.com/repos/elastic/kibana/pulls/comments/117793546"},"html":{"href":"https://github.com/elastic/kibana/pull/11632#discussion_r117793546"},"pull_request":{"href":"https://api.github.com/repos/elastic/kibana/pulls/11632"}}},"pull_request":{"url":"https://api.github.com/repos/elastic/kibana/pulls/11632","id":119250215,"html_url":"https://github.com/elastic/kibana/pull/11632","diff_url":"https://github.com/elastic/kibana/pull/11632.diff","patch_url":"https://github.com/elastic/kibana/pull/11632.patch","issue_url":"https://api.github.com/repos/elastic/kibana/issues/11632","number":11632,"state":"open","locked":false,"title":"Adds an API for managing saved objects","user":{"login":"tylersmalley","id":40265,"avatar_url":"https://avatars1.githubusercontent.com/u/40265?v=3","gravatar_id":"","url":"https://api.github.com/users/tylersmalley","html_url":"https://github.com/tylersmalley","followers_url":"https://api.github.com/users/tylersmalley/followers","following_url":"https://api.github.com/users/tylersmalley/following{/other_user}","gists_url":"https://api.github.com/users/tylersmalley/gists{/gist_id}","starred_url":"https://api.github.com/users/tylersmalley/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tylersmalley/subscriptions","organizations_url":"https://api.github.com/users/tylersmalley/orgs","repos_url":"https://api.github.com/users/tylersmalley/repos","events_url":"https://api.github.com/users/tylersmalley/events{/privacy}","received_events_url":"https://api.github.com/users/tylersmalley/received_events","type":"User","site_admin":false},"body":"# API Overview\r\n\r\nFor brevity, I have simplified the cURL commands to exclude the necessary headers. You will need to include the following: `-H \"Content-Type: application/json\" -H \"kbn-xsrf: 6.0.0\"`. I would also suggest adding `-i` to confirm the response headers.\r\n\r\n## Create\r\nRoute: `POST /api/saved_objects/{type?}`\r\n\r\ncURL: `curl -X POST -d '{ \"attributes\": { \"title\": \"Test pattern\" } }' http://localhost:5601/api/saved_objects/index-pattern`\r\n\r\nResponse:\r\n```json\r\n{\r\n  \"type\":\"index-pattern\",\r\n  \"id\":\"AVwXs-2htCUMy4H_zXXl\",\r\n  \"version\":1,\r\n  \"attributes\":{\r\n    \"title\":\"Test pattern\"\r\n  }\r\n}\r\n```\r\n\r\n## Read\r\nRoute: `GET /api/saved_objects/{type}/{id}`\r\n\r\ncURL: `curl \"http://localhost:5601/api/saved_objects/index-pattern/AVwXs-2htCUMy4H_zXXl\"`\r\n\r\nResponse:\r\n```json\r\n{\r\n  \"id\":\"AVwXs-2htCUMy4H_zXXl\",\r\n  \"type\":\"index-pattern\",\r\n  \"version\":1,\r\n  \"attributes\":{\r\n    \"title\":\"Test pattern\"\r\n  }\r\n}\r\n```\r\n\r\n## Update\r\nRoute: `PUT /api/saved_objects/{type}/{id}`\r\n\r\ncURL: `curl -X PUT -d '{ \"version\": 1, \"attributes\": { \"title\": \"Updated title\" } }' http://localhost:5601/api/saved_objects/index-pattern/AVwXs-2htCUMy4H_zXXl`\r\n\r\nResponse:\r\n```json\r\n{\r\n  \"id\":\"AVwXs-2htCUMy4H_zXXl\",\r\n  \"type\":\"index-pattern\",\r\n  \"version\":2,\r\n  \"attributes\":{\r\n    \"title\":\"Updated title\"\r\n  }\r\n}\r\n```\r\n\r\n## Delete\r\nRoute: `DELETE /api/saved_objects/{type}/{id}`\r\n\r\ncURL: `curl -X DELETE http://localhost:5601/api/saved_objects/index-pattern/AVwXs-2htCUMy4H_zXXl`\r\n\r\nResponse: Boolean based on success. We return an error if the document can not be found. \r\n\r\n## Find\r\nRoute: `GET /api/saved_objects/{type?}`\r\nQuery parameters (optional):\r\n* per_page: defaults to 20\r\n* page: defaults to 1\r\n* type: The type in which to limit the results to\r\n* search: Query passed to simple_query_string\r\n* searchFields: Fields to search against\r\n* fields: Fields to return\r\n\r\ncURL: `curl \"http://localhost:5601/api/saved_objects?fields=title&search=tyler\"`\r\n\r\nResponse:\r\n```json\r\n{\r\n  \"data\":[\r\n    {\r\n      \"id\":\"b7aff090-346d-11e7-9d21-53e7c9e02e64\",\r\n      \"type\":\"search\",\r\n      \"version\":1,\r\n      \"attributes\": {\r\n        \"title\":\"s1\"\r\n      }\r\n    }\r\n  ],\r\n  \"total\":1,\r\n  \"per_page\":20,\r\n  \"page\":1\r\n}\r\n```\r\n\r\nTODO:\r\n\r\n- [ ] Add sort to find\r\n- [ ] Add ids to find","created_at":"2017-05-05T20:14:02Z","updated_at":"2017-05-22T16:53:44Z","closed_at":null,"merged_at":null,"merge_commit_sha":"b771b898484aad6751dfb96f9e91d467f5fedcf6","assignee":{"login":"BigFunger","id":12193008,"avatar_url":"https://avatars2.githubusercontent.com/u/12193008?v=3","gravatar_id":"","url":"https://api.github.com/users/BigFunger","html_url":"https://github.com/BigFunger","followers_url":"https://api.github.com/users/BigFunger/followers","following_url":"https://api.github.com/users/BigFunger/following{/other_user}","gists_url":"https://api.github.com/users/BigFunger/gists{/gist_id}","starred_url":"https://api.github.com/users/BigFunger/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/BigFunger/subscriptions","organizations_url":"https://api.github.com/users/BigFunger/orgs","repos_url":"https://api.github.com/users/BigFunger/repos","events_url":"https://api.github.com/users/BigFunger/events{/privacy}","received_events_url":"https://api.github.com/users/BigFunger/received_events","type":"User","site_admin":false},"assignees":[{"login":"BigFunger","id":12193008,"avatar_url":"https://avatars2.githubusercontent.com/u/12193008?v=3","gravatar_id":"","url":"https://api.github.com/users/BigFunger","html_url":"https://github.com/BigFunger","followers_url":"https://api.github.com/users/BigFunger/followers","following_url":"https://api.github.com/users/BigFunger/following{/other_user}","gists_url":"https://api.github.com/users/BigFunger/gists{/gist_id}","starred_url":"https://api.github.com/users/BigFunger/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/BigFunger/subscriptions","organizations_url":"https://api.github.com/users/BigFunger/orgs","repos_url":"https://api.github.com/users/BigFunger/repos","events_url":"https://api.github.com/users/BigFunger/events{/privacy}","received_events_url":"https://api.github.com/users/BigFunger/received_events","type":"User","site_admin":false}],"requested_reviewers":[],"milestone":null,"commits_url":"https://api.github.com/repos/elastic/kibana/pulls/11632/commits","review_comments_url":"https://api.github.com/repos/elastic/kibana/pulls/11632/comments","review_comment_url":"https://api.github.com/repos/elastic/kibana/pulls/comments{/number}","comments_url":"https://api.github.com/repos/elastic/kibana/issues/11632/comments","statuses_url":"https://api.github.com/repos/elastic/kibana/statuses/9eb2efc54c2391725396279ba22a04c95eab9ec2","head":{"label":"tylersmalley:saved-objects-api","ref":"saved-objects-api","sha":"9eb2efc54c2391725396279ba22a04c95eab9ec2","user":{"login":"tylersmalley","id":40265,"avatar_url":"https://avatars1.githubusercontent.com/u/40265?v=3","gravatar_id":"","url":"https://api.github.com/users/tylersmalley","html_url":"https://github.com/tylersmalley","followers_url":"https://api.github.com/users/tylersmalley/followers","following_url":"https://api.github.com/users/tylersmalley/following{/other_user}","gists_url":"https://api.github.com/users/tylersmalley/gists{/gist_id}","starred_url":"https://api.github.com/users/tylersmalley/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tylersmalley/subscriptions","organizations_url":"https://api.github.com/users/tylersmalley/orgs","repos_url":"https://api.github.com/users/tylersmalley/repos","events_url":"https://api.github.com/users/tylersmalley/events{/privacy}","received_events_url":"https://api.github.com/users/tylersmalley/received_events","type":"User","site_admin":false},"repo":{"id":52817123,"name":"kibana","full_name":"tylersmalley/kibana","owner":{"login":"tylersmalley","id":40265,"avatar_url":"https://avatars1.githubusercontent.com/u/40265?v=3","gravatar_id":"","url":"https://api.github.com/users/tylersmalley","html_url":"https://github.com/tylersmalley","followers_url":"https://api.github.com/users/tylersmalley/followers","following_url":"https://api.github.com/users/tylersmalley/following{/other_user}","gists_url":"https://api.github.com/users/tylersmalley/gists{/gist_id}","starred_url":"https://api.github.com/users/tylersmalley/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tylersmalley/subscriptions","organizations_url":"https://api.github.com/users/tylersmalley/orgs","repos_url":"https://api.github.com/users/tylersmalley/repos","events_url":"https://api.github.com/users/tylersmalley/events{/privacy}","received_events_url":"https://api.github.com/users/tylersmalley/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/tylersmalley/kibana","description":"Kibana","fork":true,"url":"https://api.github.com/repos/tylersmalley/kibana","forks_url":"https://api.github.com/repos/tylersmalley/kibana/forks","keys_url":"https://api.github.com/repos/tylersmalley/kibana/keys{/key_id}","collaborators_url":"https://api.github.com/repos/tylersmalley/kibana/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/tylersmalley/kibana/teams","hooks_url":"https://api.github.com/repos/tylersmalley/kibana/hooks","issue_events_url":"https://api.github.com/repos/tylersmalley/kibana/issues/events{/number}","events_url":"https://api.github.com/repos/tylersmalley/kibana/events","assignees_url":"https://api.github.com/repos/tylersmalley/kibana/assignees{/user}","branches_url":"https://api.github.com/repos/tylersmalley/kibana/branches{/branch}","tags_url":"https://api.github.com/repos/tylersmalley/kibana/tags","blobs_url":"https://api.github.com/repos/tylersmalley/kibana/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/tylersmalley/kibana/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/tylersmalley/kibana/git/refs{/sha}","trees_url":"https://api.github.com/repos/tylersmalley/kibana/git/trees{/sha}","statuses_url":"https://api.github.com/repos/tylersmalley/kibana/statuses/{sha}","languages_url":"https://api.github.com/repos/tylersmalley/kibana/languages","stargazers_url":"https://api.github.com/repos/tylersmalley/kibana/stargazers","contributors_url":"https://api.github.com/repos/tylersmalley/kibana/contributors","subscribers_url":"https://api.github.com/repos/tylersmalley/kibana/subscribers","subscription_url":"https://api.github.com/repos/tylersmalley/kibana/subscription","commits_url":"https://api.github.com/repos/tylersmalley/kibana/commits{/sha}","git_commits_url":"https://api.github.com/repos/tylersmalley/kibana/git/commits{/sha}","comments_url":"https://api.github.com/repos/tylersmalley/kibana/comments{/number}","issue_comment_url":"https://api.github.com/repos/tylersmalley/kibana/issues/comments{/number}","contents_url":"https://api.github.com/repos/tylersmalley/kibana/contents/{+path}","compare_url":"https://api.github.com/repos/tylersmalley/kibana/compare/{base}...{head}","merges_url":"https://api.github.com/repos/tylersmalley/kibana/merges","archive_url":"https://api.github.com/repos/tylersmalley/kibana/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/tylersmalley/kibana/downloads","issues_url":"https://api.github.com/repos/tylersmalley/kibana/issues{/number}","pulls_url":"https://api.github.com/repos/tylersmalley/kibana/pulls{/number}","milestones_url":"https://api.github.com/repos/tylersmalley/kibana/milestones{/number}","notifications_url":"https://api.github.com/repos/tylersmalley/kibana/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/tylersmalley/kibana/labels{/name}","releases_url":"https://api.github.com/repos/tylersmalley/kibana/releases{/id}","deployments_url":"https://api.github.com/repos/tylersmalley/kibana/deployments","created_at":"2016-02-29T19:24:41Z","updated_at":"2016-02-29T19:24:44Z","pushed_at":"2017-05-22T14:37:34Z","git_url":"git://github.com/tylersmalley/kibana.git","ssh_url":"git@github.com:tylersmalley/kibana.git","clone_url":"https://github.com/tylersmalley/kibana.git","svn_url":"https://github.com/tylersmalley/kibana","homepage":"https://www.elastic.co/products/kibana","size":246431,"stargazers_count":0,"watchers_count":0,"language":"JavaScript","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"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":"elastic:master","ref":"master","sha":"7557c8f56314dd41140d13eca68219a63a9fc245","user":{"login":"elastic","id":6764390,"avatar_url":"https://avatars3.githubusercontent.com/u/6764390?v=3","gravatar_id":"","url":"https://api.github.com/users/elastic","html_url":"https://github.com/elastic","followers_url":"https://api.github.com/users/elastic/followers","following_url":"https://api.github.com/users/elastic/following{/other_user}","gists_url":"https://api.github.com/users/elastic/gists{/gist_id}","starred_url":"https://api.github.com/users/elastic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/elastic/subscriptions","organizations_url":"https://api.github.com/users/elastic/orgs","repos_url":"https://api.github.com/users/elastic/repos","events_url":"https://api.github.com/users/elastic/events{/privacy}","received_events_url":"https://api.github.com/users/elastic/received_events","type":"Organization","site_admin":false},"repo":{"id":7833168,"name":"kibana","full_name":"elastic/kibana","owner":{"login":"elastic","id":6764390,"avatar_url":"https://avatars3.githubusercontent.com/u/6764390?v=3","gravatar_id":"","url":"https://api.github.com/users/elastic","html_url":"https://github.com/elastic","followers_url":"https://api.github.com/users/elastic/followers","following_url":"https://api.github.com/users/elastic/following{/other_user}","gists_url":"https://api.github.com/users/elastic/gists{/gist_id}","starred_url":"https://api.github.com/users/elastic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/elastic/subscriptions","organizations_url":"https://api.github.com/users/elastic/orgs","repos_url":"https://api.github.com/users/elastic/repos","events_url":"https://api.github.com/users/elastic/events{/privacy}","received_events_url":"https://api.github.com/users/elastic/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/elastic/kibana","description":":bar_chart: Kibana analytics and search dashboard for Elasticsearch","fork":false,"url":"https://api.github.com/repos/elastic/kibana","forks_url":"https://api.github.com/repos/elastic/kibana/forks","keys_url":"https://api.github.com/repos/elastic/kibana/keys{/key_id}","collaborators_url":"https://api.github.com/repos/elastic/kibana/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/elastic/kibana/teams","hooks_url":"https://api.github.com/repos/elastic/kibana/hooks","issue_events_url":"https://api.github.com/repos/elastic/kibana/issues/events{/number}","events_url":"https://api.github.com/repos/elastic/kibana/events","assignees_url":"https://api.github.com/repos/elastic/kibana/assignees{/user}","branches_url":"https://api.github.com/repos/elastic/kibana/branches{/branch}","tags_url":"https://api.github.com/repos/elastic/kibana/tags","blobs_url":"https://api.github.com/repos/elastic/kibana/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/elastic/kibana/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/elastic/kibana/git/refs{/sha}","trees_url":"https://api.github.com/repos/elastic/kibana/git/trees{/sha}","statuses_url":"https://api.github.com/repos/elastic/kibana/statuses/{sha}","languages_url":"https://api.github.com/repos/elastic/kibana/languages","stargazers_url":"https://api.github.com/repos/elastic/kibana/stargazers","contributors_url":"https://api.github.com/repos/elastic/kibana/contributors","subscribers_url":"https://api.github.com/repos/elastic/kibana/subscribers","subscription_url":"https://api.github.com/repos/elastic/kibana/subscription","commits_url":"https://api.github.com/repos/elastic/kibana/commits{/sha}","git_commits_url":"https://api.github.com/repos/elastic/kibana/git/commits{/sha}","comments_url":"https://api.github.com/repos/elastic/kibana/comments{/number}","issue_comment_url":"https://api.github.com/repos/elastic/kibana/issues/comments{/number}","contents_url":"https://api.github.com/repos/elastic/kibana/contents/{+path}","compare_url":"https://api.github.com/repos/elastic/kibana/compare/{base}...{head}","merges_url":"https://api.github.com/repos/elastic/kibana/merges","archive_url":"https://api.github.com/repos/elastic/kibana/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/elastic/kibana/downloads","issues_url":"https://api.github.com/repos/elastic/kibana/issues{/number}","pulls_url":"https://api.github.com/repos/elastic/kibana/pulls{/number}","milestones_url":"https://api.github.com/repos/elastic/kibana/milestones{/number}","notifications_url":"https://api.github.com/repos/elastic/kibana/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/elastic/kibana/labels{/name}","releases_url":"https://api.github.com/repos/elastic/kibana/releases{/id}","deployments_url":"https://api.github.com/repos/elastic/kibana/deployments","created_at":"2013-01-26T04:00:59Z","updated_at":"2017-05-22T15:17:36Z","pushed_at":"2017-05-22T16:40:08Z","git_url":"git://github.com/elastic/kibana.git","ssh_url":"git@github.com:elastic/kibana.git","clone_url":"https://github.com/elastic/kibana.git","svn_url":"https://github.com/elastic/kibana","homepage":"https://www.elastic.co/products/kibana","size":256866,"stargazers_count":7320,"watchers_count":7320,"language":"JavaScript","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":2787,"mirror_url":null,"open_issues_count":1693,"forks":2787,"open_issues":1693,"watchers":7320,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/elastic/kibana/pulls/11632"},"html":{"href":"https://github.com/elastic/kibana/pull/11632"},"issue":{"href":"https://api.github.com/repos/elastic/kibana/issues/11632"},"comments":{"href":"https://api.github.com/repos/elastic/kibana/issues/11632/comments"},"review_comments":{"href":"https://api.github.com/repos/elastic/kibana/pulls/11632/comments"},"review_comment":{"href":"https://api.github.com/repos/elastic/kibana/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/elastic/kibana/pulls/11632/commits"},"statuses":{"href":"https://api.github.com/repos/elastic/kibana/statuses/9eb2efc54c2391725396279ba22a04c95eab9ec2"}}}}
{"actor":{"display_login":"spalger"}}