{"action":"created","comment":{"url":"https://api.github.com/repos/coveo/source.coveo.com/pulls/comments/62913738","id":62913738,"diff_hunk":"@@ -0,0 +1,356 @@\n+---\n+layout: post\n+\n+title: \"Isomorphic TypeScript, fetch, promises, ava and coverage\"\n+\n+tags:\n+  - TypeScript\n+  - ava\n+  - code coverage\n+  - isomorphic\n+\n+author:\n+  name: Pierre-Alexandre\n+  bio: Experimentation admiral (analytics & distributed systems)\n+  twitter: pastjean\n+  imageURL: https://avatars.githubusercontent.com/u/140675\n+---\n+\n+Writing API client in JavaScript is a lot of work, you have to write one for\n+Node.js and one for the browser. I found out a way to have both, on the same codebase\n+with the same API, and only changes to the build scripts. It's called isomorphic\n+code, and doing it with modern TypeScript isn't easy, but achievable.\n+\n+<!-- more -->\n+\n+TypeScript brings lots of pluses to the JavaScript world with almost mandatory\n+typings. But TypeScript code is transpiled, and to play well with other libraries\n+that aren't originally written in TypeScript needs manually written type\n+definition and some hacks to play well with other external tools, like code\n+coverage and test frameworks.\n+\n+# Isomorphic\n+\n+Isomorphic is a trendy word with a nice soul behind, that means sharing some code\n+between frontend and backend with minor or no changes. Since TypeScript can be compiled\n+to JavaScript, it can run on Node.js and in the browser. An API client sharing the\n+same code could be written with the same code everywhere.\n+\n+I want my API client to fetch resources using the same simple call everywhere.\n+\n+```js\n+const client = new coveoanalytics.analytics.Client({ token : 'YOUR-TOKEN'})\n+// Send your event\n+client.sendCustomEvent({\n+  eventType: \"dog\";\n+  eventValue: \"Hello! Yes! This is Dog!\";\n+});\n+```\n+\n+All this without having 2 codebases.\n+\n+## Window, fetch and promises\n+\n+Let's fix the main difference between Node.js and the browser.\n+\n+Getting data from the browser is done using an `XMLHttpRequest` or using the new\n+`fetch` API that is defined on the global object `window`.\n+\n+```js\n+fetch('http://localhost:80/').then( (res) => {\n+  // Do stuff with the response\n+})\n+```\n+\n+In Node.js:\n+\n+```js\n+var http = require('http');\n+http.get({\n+  hostname: 'localhost',\n+  port: 80,\n+  path: '/'\n+}, (res) => {\n+  // Do stuff with response\n+})\n+```\n+\n+First things first, the fetch API is nice, simple and returns promises. But fetch\n+isn't defined in all browsers and is not even part of Node.js standard libraries.\n+Promises aren't defined in all browsers.\n+\n+Fortunately there are nice libraries for both of these cases. Let's use them.\n+\n+```sh\n+npm install --save es6-promises isomorphic-fetch\n+```\n+\n+But wait, don't go too fast! You are in TypeScript you need the type definition\n+if you don't want to put the `any` type everywhere. Again in the console:\n+\n+```sh\n+npm install --save-dev typings\n+typings install --save --ambient isomorphic-fetch es6-promise\n+```\n+\n+Typings is a nice tool to find type definitions and it contains the type\n+definition of almost all popular JavaScript library.","path":"_posts/2016-05-11-isomorphic-typescript-ava-w-coverage.md","position":97,"original_position":97,"commit_id":"34bccea20dc9eefff03a0f47fc08f4aea9529dc9","original_commit_id":"34bccea20dc9eefff03a0f47fc08f4aea9529dc9","user":{"login":"GuiSim","id":2000390,"avatar_url":"https://avatars.githubusercontent.com/u/2000390?v=3","gravatar_id":"","url":"https://api.github.com/users/GuiSim","html_url":"https://github.com/GuiSim","followers_url":"https://api.github.com/users/GuiSim/followers","following_url":"https://api.github.com/users/GuiSim/following{/other_user}","gists_url":"https://api.github.com/users/GuiSim/gists{/gist_id}","starred_url":"https://api.github.com/users/GuiSim/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/GuiSim/subscriptions","organizations_url":"https://api.github.com/users/GuiSim/orgs","repos_url":"https://api.github.com/users/GuiSim/repos","events_url":"https://api.github.com/users/GuiSim/events{/privacy}","received_events_url":"https://api.github.com/users/GuiSim/received_events","type":"User","site_admin":false},"body":"almost all => most\r\n","created_at":"2016-05-11T19:47:39Z","updated_at":"2016-05-11T19:47:40Z","html_url":"https://github.com/coveo/source.coveo.com/pull/74#discussion_r62913738","pull_request_url":"https://api.github.com/repos/coveo/source.coveo.com/pulls/74","_links":{"self":{"href":"https://api.github.com/repos/coveo/source.coveo.com/pulls/comments/62913738"},"html":{"href":"https://github.com/coveo/source.coveo.com/pull/74#discussion_r62913738"},"pull_request":{"href":"https://api.github.com/repos/coveo/source.coveo.com/pulls/74"}}},"pull_request":{"url":"https://api.github.com/repos/coveo/source.coveo.com/pulls/74","id":69682418,"html_url":"https://github.com/coveo/source.coveo.com/pull/74","diff_url":"https://github.com/coveo/source.coveo.com/pull/74.diff","patch_url":"https://github.com/coveo/source.coveo.com/pull/74.patch","issue_url":"https://api.github.com/repos/coveo/source.coveo.com/issues/74","number":74,"state":"open","locked":false,"title":"Add isomorphic typescript post","user":{"login":"pastjean","id":140675,"avatar_url":"https://avatars.githubusercontent.com/u/140675?v=3","gravatar_id":"","url":"https://api.github.com/users/pastjean","html_url":"https://github.com/pastjean","followers_url":"https://api.github.com/users/pastjean/followers","following_url":"https://api.github.com/users/pastjean/following{/other_user}","gists_url":"https://api.github.com/users/pastjean/gists{/gist_id}","starred_url":"https://api.github.com/users/pastjean/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pastjean/subscriptions","organizations_url":"https://api.github.com/users/pastjean/orgs","repos_url":"https://api.github.com/users/pastjean/repos","events_url":"https://api.github.com/users/pastjean/events{/privacy}","received_events_url":"https://api.github.com/users/pastjean/received_events","type":"User","site_admin":false},"body":"","created_at":"2016-05-11T14:31:52Z","updated_at":"2016-05-11T19:47:40Z","closed_at":null,"merged_at":null,"merge_commit_sha":"c70444666b0d8d1febfdf1e3a67c69433040b92f","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/coveo/source.coveo.com/pulls/74/commits","review_comments_url":"https://api.github.com/repos/coveo/source.coveo.com/pulls/74/comments","review_comment_url":"https://api.github.com/repos/coveo/source.coveo.com/pulls/comments{/number}","comments_url":"https://api.github.com/repos/coveo/source.coveo.com/issues/74/comments","statuses_url":"https://api.github.com/repos/coveo/source.coveo.com/statuses/34bccea20dc9eefff03a0f47fc08f4aea9529dc9","head":{"label":"coveo:isomorphic-typescript","ref":"isomorphic-typescript","sha":"34bccea20dc9eefff03a0f47fc08f4aea9529dc9","user":{"login":"coveo","id":8632328,"avatar_url":"https://avatars.githubusercontent.com/u/8632328?v=3","gravatar_id":"","url":"https://api.github.com/users/coveo","html_url":"https://github.com/coveo","followers_url":"https://api.github.com/users/coveo/followers","following_url":"https://api.github.com/users/coveo/following{/other_user}","gists_url":"https://api.github.com/users/coveo/gists{/gist_id}","starred_url":"https://api.github.com/users/coveo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/coveo/subscriptions","organizations_url":"https://api.github.com/users/coveo/orgs","repos_url":"https://api.github.com/users/coveo/repos","events_url":"https://api.github.com/users/coveo/events{/privacy}","received_events_url":"https://api.github.com/users/coveo/received_events","type":"Organization","site_admin":false},"repo":{"id":23815317,"name":"source.coveo.com","full_name":"coveo/source.coveo.com","owner":{"login":"coveo","id":8632328,"avatar_url":"https://avatars.githubusercontent.com/u/8632328?v=3","gravatar_id":"","url":"https://api.github.com/users/coveo","html_url":"https://github.com/coveo","followers_url":"https://api.github.com/users/coveo/followers","following_url":"https://api.github.com/users/coveo/following{/other_user}","gists_url":"https://api.github.com/users/coveo/gists{/gist_id}","starred_url":"https://api.github.com/users/coveo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/coveo/subscriptions","organizations_url":"https://api.github.com/users/coveo/orgs","repos_url":"https://api.github.com/users/coveo/repos","events_url":"https://api.github.com/users/coveo/events{/privacy}","received_events_url":"https://api.github.com/users/coveo/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/coveo/source.coveo.com","description":"Our technical blog.","fork":false,"url":"https://api.github.com/repos/coveo/source.coveo.com","forks_url":"https://api.github.com/repos/coveo/source.coveo.com/forks","keys_url":"https://api.github.com/repos/coveo/source.coveo.com/keys{/key_id}","collaborators_url":"https://api.github.com/repos/coveo/source.coveo.com/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/coveo/source.coveo.com/teams","hooks_url":"https://api.github.com/repos/coveo/source.coveo.com/hooks","issue_events_url":"https://api.github.com/repos/coveo/source.coveo.com/issues/events{/number}","events_url":"https://api.github.com/repos/coveo/source.coveo.com/events","assignees_url":"https://api.github.com/repos/coveo/source.coveo.com/assignees{/user}","branches_url":"https://api.github.com/repos/coveo/source.coveo.com/branches{/branch}","tags_url":"https://api.github.com/repos/coveo/source.coveo.com/tags","blobs_url":"https://api.github.com/repos/coveo/source.coveo.com/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/coveo/source.coveo.com/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/coveo/source.coveo.com/git/refs{/sha}","trees_url":"https://api.github.com/repos/coveo/source.coveo.com/git/trees{/sha}","statuses_url":"https://api.github.com/repos/coveo/source.coveo.com/statuses/{sha}","languages_url":"https://api.github.com/repos/coveo/source.coveo.com/languages","stargazers_url":"https://api.github.com/repos/coveo/source.coveo.com/stargazers","contributors_url":"https://api.github.com/repos/coveo/source.coveo.com/contributors","subscribers_url":"https://api.github.com/repos/coveo/source.coveo.com/subscribers","subscription_url":"https://api.github.com/repos/coveo/source.coveo.com/subscription","commits_url":"https://api.github.com/repos/coveo/source.coveo.com/commits{/sha}","git_commits_url":"https://api.github.com/repos/coveo/source.coveo.com/git/commits{/sha}","comments_url":"https://api.github.com/repos/coveo/source.coveo.com/comments{/number}","issue_comment_url":"https://api.github.com/repos/coveo/source.coveo.com/issues/comments{/number}","contents_url":"https://api.github.com/repos/coveo/source.coveo.com/contents/{+path}","compare_url":"https://api.github.com/repos/coveo/source.coveo.com/compare/{base}...{head}","merges_url":"https://api.github.com/repos/coveo/source.coveo.com/merges","archive_url":"https://api.github.com/repos/coveo/source.coveo.com/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/coveo/source.coveo.com/downloads","issues_url":"https://api.github.com/repos/coveo/source.coveo.com/issues{/number}","pulls_url":"https://api.github.com/repos/coveo/source.coveo.com/pulls{/number}","milestones_url":"https://api.github.com/repos/coveo/source.coveo.com/milestones{/number}","notifications_url":"https://api.github.com/repos/coveo/source.coveo.com/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/coveo/source.coveo.com/labels{/name}","releases_url":"https://api.github.com/repos/coveo/source.coveo.com/releases{/id}","deployments_url":"https://api.github.com/repos/coveo/source.coveo.com/deployments","created_at":"2014-09-09T01:43:19Z","updated_at":"2016-02-23T18:32:47Z","pushed_at":"2016-05-11T18:48:17Z","git_url":"git://github.com/coveo/source.coveo.com.git","ssh_url":"git@github.com:coveo/source.coveo.com.git","clone_url":"https://github.com/coveo/source.coveo.com.git","svn_url":"https://github.com/coveo/source.coveo.com","homepage":"source.coveo.com","size":23194,"stargazers_count":4,"watchers_count":4,"language":"CSS","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":true,"forks_count":28,"mirror_url":null,"open_issues_count":3,"forks":28,"open_issues":3,"watchers":4,"default_branch":"gh-pages"}},"base":{"label":"coveo:gh-pages","ref":"gh-pages","sha":"6e2c7134c75444d69e5e4cacab1e4f7c0dcd200a","user":{"login":"coveo","id":8632328,"avatar_url":"https://avatars.githubusercontent.com/u/8632328?v=3","gravatar_id":"","url":"https://api.github.com/users/coveo","html_url":"https://github.com/coveo","followers_url":"https://api.github.com/users/coveo/followers","following_url":"https://api.github.com/users/coveo/following{/other_user}","gists_url":"https://api.github.com/users/coveo/gists{/gist_id}","starred_url":"https://api.github.com/users/coveo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/coveo/subscriptions","organizations_url":"https://api.github.com/users/coveo/orgs","repos_url":"https://api.github.com/users/coveo/repos","events_url":"https://api.github.com/users/coveo/events{/privacy}","received_events_url":"https://api.github.com/users/coveo/received_events","type":"Organization","site_admin":false},"repo":{"id":23815317,"name":"source.coveo.com","full_name":"coveo/source.coveo.com","owner":{"login":"coveo","id":8632328,"avatar_url":"https://avatars.githubusercontent.com/u/8632328?v=3","gravatar_id":"","url":"https://api.github.com/users/coveo","html_url":"https://github.com/coveo","followers_url":"https://api.github.com/users/coveo/followers","following_url":"https://api.github.com/users/coveo/following{/other_user}","gists_url":"https://api.github.com/users/coveo/gists{/gist_id}","starred_url":"https://api.github.com/users/coveo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/coveo/subscriptions","organizations_url":"https://api.github.com/users/coveo/orgs","repos_url":"https://api.github.com/users/coveo/repos","events_url":"https://api.github.com/users/coveo/events{/privacy}","received_events_url":"https://api.github.com/users/coveo/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/coveo/source.coveo.com","description":"Our technical blog.","fork":false,"url":"https://api.github.com/repos/coveo/source.coveo.com","forks_url":"https://api.github.com/repos/coveo/source.coveo.com/forks","keys_url":"https://api.github.com/repos/coveo/source.coveo.com/keys{/key_id}","collaborators_url":"https://api.github.com/repos/coveo/source.coveo.com/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/coveo/source.coveo.com/teams","hooks_url":"https://api.github.com/repos/coveo/source.coveo.com/hooks","issue_events_url":"https://api.github.com/repos/coveo/source.coveo.com/issues/events{/number}","events_url":"https://api.github.com/repos/coveo/source.coveo.com/events","assignees_url":"https://api.github.com/repos/coveo/source.coveo.com/assignees{/user}","branches_url":"https://api.github.com/repos/coveo/source.coveo.com/branches{/branch}","tags_url":"https://api.github.com/repos/coveo/source.coveo.com/tags","blobs_url":"https://api.github.com/repos/coveo/source.coveo.com/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/coveo/source.coveo.com/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/coveo/source.coveo.com/git/refs{/sha}","trees_url":"https://api.github.com/repos/coveo/source.coveo.com/git/trees{/sha}","statuses_url":"https://api.github.com/repos/coveo/source.coveo.com/statuses/{sha}","languages_url":"https://api.github.com/repos/coveo/source.coveo.com/languages","stargazers_url":"https://api.github.com/repos/coveo/source.coveo.com/stargazers","contributors_url":"https://api.github.com/repos/coveo/source.coveo.com/contributors","subscribers_url":"https://api.github.com/repos/coveo/source.coveo.com/subscribers","subscription_url":"https://api.github.com/repos/coveo/source.coveo.com/subscription","commits_url":"https://api.github.com/repos/coveo/source.coveo.com/commits{/sha}","git_commits_url":"https://api.github.com/repos/coveo/source.coveo.com/git/commits{/sha}","comments_url":"https://api.github.com/repos/coveo/source.coveo.com/comments{/number}","issue_comment_url":"https://api.github.com/repos/coveo/source.coveo.com/issues/comments{/number}","contents_url":"https://api.github.com/repos/coveo/source.coveo.com/contents/{+path}","compare_url":"https://api.github.com/repos/coveo/source.coveo.com/compare/{base}...{head}","merges_url":"https://api.github.com/repos/coveo/source.coveo.com/merges","archive_url":"https://api.github.com/repos/coveo/source.coveo.com/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/coveo/source.coveo.com/downloads","issues_url":"https://api.github.com/repos/coveo/source.coveo.com/issues{/number}","pulls_url":"https://api.github.com/repos/coveo/source.coveo.com/pulls{/number}","milestones_url":"https://api.github.com/repos/coveo/source.coveo.com/milestones{/number}","notifications_url":"https://api.github.com/repos/coveo/source.coveo.com/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/coveo/source.coveo.com/labels{/name}","releases_url":"https://api.github.com/repos/coveo/source.coveo.com/releases{/id}","deployments_url":"https://api.github.com/repos/coveo/source.coveo.com/deployments","created_at":"2014-09-09T01:43:19Z","updated_at":"2016-02-23T18:32:47Z","pushed_at":"2016-05-11T18:48:17Z","git_url":"git://github.com/coveo/source.coveo.com.git","ssh_url":"git@github.com:coveo/source.coveo.com.git","clone_url":"https://github.com/coveo/source.coveo.com.git","svn_url":"https://github.com/coveo/source.coveo.com","homepage":"source.coveo.com","size":23194,"stargazers_count":4,"watchers_count":4,"language":"CSS","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":true,"forks_count":28,"mirror_url":null,"open_issues_count":3,"forks":28,"open_issues":3,"watchers":4,"default_branch":"gh-pages"}},"_links":{"self":{"href":"https://api.github.com/repos/coveo/source.coveo.com/pulls/74"},"html":{"href":"https://github.com/coveo/source.coveo.com/pull/74"},"issue":{"href":"https://api.github.com/repos/coveo/source.coveo.com/issues/74"},"comments":{"href":"https://api.github.com/repos/coveo/source.coveo.com/issues/74/comments"},"review_comments":{"href":"https://api.github.com/repos/coveo/source.coveo.com/pulls/74/comments"},"review_comment":{"href":"https://api.github.com/repos/coveo/source.coveo.com/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/coveo/source.coveo.com/pulls/74/commits"},"statuses":{"href":"https://api.github.com/repos/coveo/source.coveo.com/statuses/34bccea20dc9eefff03a0f47fc08f4aea9529dc9"}}}}