{"action":"created","comment":{"url":"https://api.github.com/repos/eslint/typescript-eslint-parser/pulls/comments/232136256","pull_request_review_id":173266512,"id":232136256,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIzMjEzNjI1Ng==","diff_hunk":"@@ -0,0 +1,355 @@\n+/**\n+ * @fileoverview Tests for TypeScript-specific scope analysis\n+ * @author Toru Nagashima <https://github.com/mysticatea>\n+ */\n+\"use strict\";\n+\n+const assert = require(\"assert\");\n+const fs = require(\"fs\");\n+const path = require(\"path\");\n+const { Linter } = require(\"eslint\");\n+const parser = require(\"../..\");\n+\n+/** Reference resolver. */\n+class ReferenceResolver {\n+    constructor() {\n+        this.map = new Map();\n+    }\n+\n+    resolve(obj, properties) {\n+        const resolved = Object.assign({ $id: this.map.size }, properties);\n+        this.map.set(obj, resolved);\n+        return resolved;\n+    }\n+\n+    ref(obj) {\n+        if (typeof obj !== \"object\" || obj === null) {\n+            return obj;\n+        }\n+\n+        const { map } = this;\n+        return {\n+            get $ref() {\n+                return map.get(obj).$id;\n+            }\n+        };\n+    }\n+}\n+\n+/**\n+ * Convert a given node object to JSON object.\n+ * This saves only type and range to know what the node is.\n+ * @param {ASTNode} node The AST node object.\n+ * @returns {Object} The object that can be used for JSON.stringify.\n+ */\n+function nodeToJSON(node) {\n+    if (!node) {\n+        return node;\n+    }\n+\n+    const { type, name, range } = node;\n+    if (node.type === \"Identifier\") {\n+        return { type, name, range };\n+    }\n+    return { type, range };\n+}\n+\n+/**\n+ * Convert a given variable object to JSON object.\n+ * @param {Variable} variable The eslint-scope's variable object.\n+ * @param {ReferenceResolver} resolver The reference resolver.\n+ * @returns {Object} The object that can be used for JSON.stringify.\n+ */\n+function variableToJSON(variable, resolver) {\n+    const { name, eslintUsed } = variable;\n+    const defs = variable.defs.map(d => ({\n+        type: d.type,\n+        name: nodeToJSON(d.name),\n+        node: nodeToJSON(d.node),\n+        parent: nodeToJSON(d.parent)\n+    }));\n+    const identifiers = variable.identifiers.map(nodeToJSON);\n+    const references = variable.references.map(resolver.ref, resolver);\n+    const scope = resolver.ref(variable.scope);\n+\n+    return resolver.resolve(variable, {\n+        name,\n+        defs,\n+        identifiers,\n+        references,\n+        scope,\n+        eslintUsed\n+    });\n+}\n+\n+/**\n+ * Convert a given reference object to JSON object.\n+ * @param {Reference} reference The eslint-scope's reference object.\n+ * @param {ReferenceResolver} resolver The reference resolver.\n+ * @returns {Object} The object that can be used for JSON.stringify.\n+ */\n+function referenceToJSON(reference, resolver) {\n+    const kind = `${reference.isRead() ? \"r\" : \"\"}${reference.isWrite() ? \"w\" : \"\"}`;\n+    const from = resolver.ref(reference.from);\n+    const identifier = nodeToJSON(reference.identifier);\n+    const writeExpr = nodeToJSON(reference.writeExpr);\n+    const resolved = resolver.ref(reference.resolved);\n+\n+    return resolver.resolve(reference, {\n+        kind,\n+        from,\n+        identifier,\n+        writeExpr,\n+        resolved\n+    });\n+}\n+\n+/**\n+ * Convert a given scope object to JSON object.\n+ * @param {Scope} scope The eslint-scope's scope object.\n+ * @param {ReferenceResolver} resolver The reference resolver.\n+ * @returns {Object} The object that can be used for JSON.stringify.\n+ */\n+function scopeToJSON(scope, resolver = new ReferenceResolver()) {\n+    const { type, functionExpressionScope, isStrict } = scope;\n+    const block = nodeToJSON(scope.block);\n+    const variables = scope.variables.map(v => variableToJSON(v, resolver));\n+    const references = scope.references.map(r => referenceToJSON(r, resolver));\n+    const variableMap = Array.from(scope.set.entries()).reduce((map, [name, variable]) => {\n+        map[name] = resolver.ref(variable);\n+        return map;\n+    }, {});\n+    const throughReferences = scope.through.map(resolver.ref, resolver);\n+    const variableScope = resolver.ref(scope.variableScope);\n+    const upperScope = resolver.ref(scope.upper);\n+    const childScopes = scope.childScopes.map(c => scopeToJSON(c, resolver));\n+\n+    return resolver.resolve(scope, {\n+        type,\n+        functionExpressionScope,\n+        isStrict,\n+        block,\n+        variables,\n+        references,\n+        variableMap,\n+        throughReferences,\n+        variableScope,\n+        upperScope,\n+        childScopes\n+    });\n+}\n+\n+describe(\"TypeScript scope analysis\", () => {\n+    const root = \"tests/fixtures/scope-analysis\";\n+    const files = fs.readdirSync(root).map(filename => path.join(root, filename).replace(/\\\\/g, \"/\"));\n+\n+    for (const filePath of files) {\n+        test(filePath, () => {\n+            const code = fs.readFileSync(filePath, \"utf8\");\n+            const { scopeManager } = parser.parseForESLint(code, {\n+                loc: true,\n+                range: true,\n+                tokens: true,\n+                ecmaFeatures: {}\n+            });\n+            const { globalScope } = scopeManager;\n+\n+            // Do the postprocess to test.\n+            // https://github.com/eslint/eslint/blob/4fe328787dd02d7a1f6fc21167f6175c860825e3/lib/linter.js#L222\n+            globalScope.through = globalScope.through.filter(reference => {\n+                const name = reference.identifier.name;\n+                const variable = globalScope.set.get(name);\n+                if (variable) {\n+                    reference.resolved = variable;\n+                    variable.references.push(reference);\n+                    return false;\n+                }\n+                return true;\n+            });\n+\n+            const scopeTree = scopeToJSON(globalScope);\n+            expect(scopeTree).toMatchSnapshot();\n+        });\n+    }\n+\n+    const linter = new Linter();\n+    linter.defineParser(\"typescript-eslint-parser\", parser);\n+\n+    test(\"https://github.com/eslint/typescript-eslint-parser/issues/416\", () => {\n+        const code = `\n+export type SomeThing = {\n+    id: string;\n+}\n+`;\n+        const config = {\n+            parser: \"typescript-eslint-parser\",\n+            rules: {\n+                \"no-undef\": \"error\"\n+            }\n+        };\n+        const messages = linter.verify(code, config, { filename: \"issue416.ts\" });\n+\n+        assert.deepStrictEqual(messages, []);\n+    });\n+\n+    test(\"https://github.com/eslint/typescript-eslint-parser/issues/435\", () => {\n+        const code = `\n+interface Foo {\n+    bar: string\n+}\n+const bar = 'blah'\n+`;\n+        const config = {\n+            parser: \"typescript-eslint-parser\",\n+            rules: {\n+                \"no-use-before-define\": \"error\"\n+            }\n+        };\n+        const messages = linter.verify(code, config, { filename: \"issue435.ts\" });\n+\n+        assert.deepStrictEqual(messages, []);\n+    });\n+\n+    test(\"https://github.com/eslint/typescript-eslint-parser/issues/437\", () => {\n+        const code = `\n+interface Runnable {\n+  run (): Result\n+  toString (): string\n+}\n+`;\n+        const config = {\n+            parser: \"typescript-eslint-parser\",\n+            rules: {\n+                \"no-undef\": \"error\"\n+            }\n+        };\n+        const messages = linter.verify(code, config, { filename: \"issue437.ts\" });\n+\n+        assert.deepStrictEqual(messages, []);\n+    });\n+\n+    test(\"https://github.com/eslint/typescript-eslint-parser/issues/443\", () => {\n+        const code = `\n+const Foo = 1;\n+type Foo = 1;\n+`;\n+        const config = {\n+            parser: \"typescript-eslint-parser\",\n+            rules: {\n+                \"no-redeclare\": \"error\"\n+            }\n+        };\n+        const messages = linter.verify(code, config, { filename: \"issue443.ts\" });\n+\n+        assert.deepStrictEqual(messages, []);\n+    });\n+\n+    test(\"https://github.com/eslint/typescript-eslint-parser/issues/459\", () => {\n+        const code = `\n+type foo = any;\n+function bar(foo: any) {}\n+`;\n+        const config = {\n+            parser: \"typescript-eslint-parser\",\n+            rules: {\n+                \"no-shadow\": \"error\"\n+            }\n+        };\n+        const messages = linter.verify(code, config, { filename: \"issue.ts\" });\n+\n+        assert.deepStrictEqual(messages, []);\n+    });\n+\n+    test(\"https://github.com/eslint/typescript-eslint-parser/issues/466\", () => {\n+        const code = `\n+/*globals document, selector */\n+const links = document.querySelectorAll( selector ) as NodeListOf<HTMLElement>\n+`;\n+        const config = {\n+            parser: \"typescript-eslint-parser\",\n+            rules: {\n+                \"no-undef\": \"error\"\n+            }\n+        };\n+        const messages = linter.verify(code, config, { filename: \"issue.ts\" });\n+\n+        assert.deepStrictEqual(messages, []);\n+    });\n+\n+    test(\"https://github.com/eslint/typescript-eslint-parser/issues/471\", () => {\n+        const code = `\n+class X {\n+  field = {}\n+}\n+`;\n+        const config = {\n+            parser: \"typescript-eslint-parser\",\n+            rules: {\n+                \"no-undef\": \"error\"\n+            }\n+        };\n+        const messages = linter.verify(code, config, { filename: \"issue.ts\" });\n+\n+        assert.deepStrictEqual(messages, []);\n+    });\n+\n+    test(\"https://github.com/eslint/typescript-eslint-parser/issues/487\", () => {\n+        const code = `\n+export default class Test {\n+    private status: string;\n+    getStatus() {\n+        return this.status;\n+    }\n+}\n+`;\n+        const config = {\n+            parser: \"typescript-eslint-parser\",\n+            rules: {\n+                \"no-restricted-globals\": [\"error\", \"status\"]\n+            }\n+        };\n+        const messages = linter.verify(code, config, { filename: \"issue.ts\" });\n+\n+        assert.deepStrictEqual(messages, []);\n+    });\n+\n+    test(\"https://github.com/eslint/typescript-eslint-parser/issues/535\", () => {\n+        const code = `\n+function foo({ bar }: { bar: string }) {\n+    console.log(bar);\n+}\n+`;\n+        const config = {\n+            parser: \"typescript-eslint-parser\",\n+            rules: {\n+                \"no-dupe-args\": \"error\",\n+                \"no-redeclare\": \"error\"\n+            }\n+        };\n+        const messages = linter.verify(code, config, { filename: \"issue.ts\" });\n+\n+        assert.deepStrictEqual(messages, []);\n+    });\n+\n+    test(\"https://github.com/eslint/typescript-eslint-parser/issues/535\", () => {\n+        const code = `\n+import {\n+  observable,\n+} from 'mobx';\n+\n+export default class ListModalStore {\n+  @observable\n+  orderList: IObservableArray<BizPurchaseOrderTO> = observable([]);\n+}\n+`;\n+        const config = {\n+            parser: \"typescript-eslint-parser\",\n+            rules: {\n+                \"no-unused-vars\": \"error\"\n+            }\n+        };\n+        const messages = linter.verify(code, config, { filename: \"issue.ts\" });\n+\n+        assert.deepStrictEqual(messages, []);","path":"tests/lib/scope-analysis.js","position":353,"original_position":353,"commit_id":"044563be23b54a82dd8dc4f8449d325789595c72","original_commit_id":"044563be23b54a82dd8dc4f8449d325789595c72","user":{"login":"JamesHenry","id":900523,"node_id":"MDQ6VXNlcjkwMDUyMw==","avatar_url":"https://avatars1.githubusercontent.com/u/900523?v=4","gravatar_id":"","url":"https://api.github.com/users/JamesHenry","html_url":"https://github.com/JamesHenry","followers_url":"https://api.github.com/users/JamesHenry/followers","following_url":"https://api.github.com/users/JamesHenry/following{/other_user}","gists_url":"https://api.github.com/users/JamesHenry/gists{/gist_id}","starred_url":"https://api.github.com/users/JamesHenry/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JamesHenry/subscriptions","organizations_url":"https://api.github.com/users/JamesHenry/orgs","repos_url":"https://api.github.com/users/JamesHenry/repos","events_url":"https://api.github.com/users/JamesHenry/events{/privacy}","received_events_url":"https://api.github.com/users/JamesHenry/received_events","type":"User","site_admin":false},"body":"How come you are frequently using `assert` rather than jest's `expect()` within the jest `test()` blocks?\r\n\r\nI can't say I have ever seen or done this so just calling it out in case there is any chance it is masking some issues/causing false positives...","created_at":"2018-11-09T03:49:52Z","updated_at":"2018-11-09T03:49:52Z","html_url":"https://github.com/eslint/typescript-eslint-parser/pull/540#discussion_r232136256","pull_request_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/pulls/540","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/eslint/typescript-eslint-parser/pulls/comments/232136256"},"html":{"href":"https://github.com/eslint/typescript-eslint-parser/pull/540#discussion_r232136256"},"pull_request":{"href":"https://api.github.com/repos/eslint/typescript-eslint-parser/pulls/540"}}},"pull_request":{"url":"https://api.github.com/repos/eslint/typescript-eslint-parser/pulls/540","id":228324052,"node_id":"MDExOlB1bGxSZXF1ZXN0MjI4MzI0MDUy","html_url":"https://github.com/eslint/typescript-eslint-parser/pull/540","diff_url":"https://github.com/eslint/typescript-eslint-parser/pull/540.diff","patch_url":"https://github.com/eslint/typescript-eslint-parser/pull/540.patch","issue_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/issues/540","number":540,"state":"open","locked":false,"title":"Update: add proper scope analysis (fixes #535)","user":{"login":"mysticatea","id":1937871,"node_id":"MDQ6VXNlcjE5Mzc4NzE=","avatar_url":"https://avatars2.githubusercontent.com/u/1937871?v=4","gravatar_id":"","url":"https://api.github.com/users/mysticatea","html_url":"https://github.com/mysticatea","followers_url":"https://api.github.com/users/mysticatea/followers","following_url":"https://api.github.com/users/mysticatea/following{/other_user}","gists_url":"https://api.github.com/users/mysticatea/gists{/gist_id}","starred_url":"https://api.github.com/users/mysticatea/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mysticatea/subscriptions","organizations_url":"https://api.github.com/users/mysticatea/orgs","repos_url":"https://api.github.com/users/mysticatea/repos","events_url":"https://api.github.com/users/mysticatea/events{/privacy}","received_events_url":"https://api.github.com/users/mysticatea/received_events","type":"User","site_admin":false},"body":"This PR adds proper scope analysis by returning [`scopeManager`](https://eslint.org/docs/developer-guide/working-with-custom-parsers) object from `parseForESLint` function.\r\n\r\nThe `scopeManager` doesn't contain any types. I think that we can provide `parserServices` to get types, but I don't contain it in this PR.\r\n\r\n<details>\r\n<summary>This fixes #416, #435, #437, #443, #459, #466, #471, #476, #487, #535, #536, and #545.</summary>\r\n\r\n- Fixes #435\r\n- Fixes #437\r\n- Fixes #443\r\n- Fixes #459\r\n- Fixes #466\r\n- Fixes #471\r\n- Fixes #476\r\n- Fixes #487\r\n- Fixes #535\r\n- Fixes #536\r\n- Fixes #545\r\n\r\n</details>","created_at":"2018-11-05T11:42:20Z","updated_at":"2018-11-09T03:49:52Z","closed_at":null,"merged_at":null,"merge_commit_sha":"00d9594b0c15087866ea8a546a75357730ebb877","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[{"id":295591815,"node_id":"MDU6TGFiZWwyOTU1OTE4MTU=","url":"https://api.github.com/repos/eslint/typescript-eslint-parser/labels/bug","name":"bug","color":"fc2929","default":true}],"milestone":null,"commits_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/pulls/540/commits","review_comments_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/pulls/540/comments","review_comment_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/pulls/comments{/number}","comments_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/issues/540/comments","statuses_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/statuses/044563be23b54a82dd8dc4f8449d325789595c72","head":{"label":"eslint:fix-scope-analysis","ref":"fix-scope-analysis","sha":"044563be23b54a82dd8dc4f8449d325789595c72","user":{"login":"eslint","id":6019716,"node_id":"MDEyOk9yZ2FuaXphdGlvbjYwMTk3MTY=","avatar_url":"https://avatars3.githubusercontent.com/u/6019716?v=4","gravatar_id":"","url":"https://api.github.com/users/eslint","html_url":"https://github.com/eslint","followers_url":"https://api.github.com/users/eslint/followers","following_url":"https://api.github.com/users/eslint/following{/other_user}","gists_url":"https://api.github.com/users/eslint/gists{/gist_id}","starred_url":"https://api.github.com/users/eslint/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/eslint/subscriptions","organizations_url":"https://api.github.com/users/eslint/orgs","repos_url":"https://api.github.com/users/eslint/repos","events_url":"https://api.github.com/users/eslint/events{/privacy}","received_events_url":"https://api.github.com/users/eslint/received_events","type":"Organization","site_admin":false},"repo":{"id":47434220,"node_id":"MDEwOlJlcG9zaXRvcnk0NzQzNDIyMA==","name":"typescript-eslint-parser","full_name":"eslint/typescript-eslint-parser","private":false,"owner":{"login":"eslint","id":6019716,"node_id":"MDEyOk9yZ2FuaXphdGlvbjYwMTk3MTY=","avatar_url":"https://avatars3.githubusercontent.com/u/6019716?v=4","gravatar_id":"","url":"https://api.github.com/users/eslint","html_url":"https://github.com/eslint","followers_url":"https://api.github.com/users/eslint/followers","following_url":"https://api.github.com/users/eslint/following{/other_user}","gists_url":"https://api.github.com/users/eslint/gists{/gist_id}","starred_url":"https://api.github.com/users/eslint/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/eslint/subscriptions","organizations_url":"https://api.github.com/users/eslint/orgs","repos_url":"https://api.github.com/users/eslint/repos","events_url":"https://api.github.com/users/eslint/events{/privacy}","received_events_url":"https://api.github.com/users/eslint/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/eslint/typescript-eslint-parser","description":"An ESLint custom parser which leverages TypeScript ESTree to allow for ESLint to lint TypeScript source code.","fork":false,"url":"https://api.github.com/repos/eslint/typescript-eslint-parser","forks_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/forks","keys_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/keys{/key_id}","collaborators_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/teams","hooks_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/hooks","issue_events_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/issues/events{/number}","events_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/events","assignees_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/assignees{/user}","branches_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/branches{/branch}","tags_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/tags","blobs_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/git/refs{/sha}","trees_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/git/trees{/sha}","statuses_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/statuses/{sha}","languages_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/languages","stargazers_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/stargazers","contributors_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/contributors","subscribers_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/subscribers","subscription_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/subscription","commits_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/commits{/sha}","git_commits_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/git/commits{/sha}","comments_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/comments{/number}","issue_comment_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/issues/comments{/number}","contents_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/contents/{+path}","compare_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/compare/{base}...{head}","merges_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/merges","archive_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/downloads","issues_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/issues{/number}","pulls_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/pulls{/number}","milestones_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/milestones{/number}","notifications_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/labels{/name}","releases_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/releases{/id}","deployments_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/deployments","created_at":"2015-12-04T23:36:41Z","updated_at":"2018-11-09T03:01:51Z","pushed_at":"2018-11-09T03:01:49Z","git_url":"git://github.com/eslint/typescript-eslint-parser.git","ssh_url":"git@github.com:eslint/typescript-eslint-parser.git","clone_url":"https://github.com/eslint/typescript-eslint-parser.git","svn_url":"https://github.com/eslint/typescript-eslint-parser","homepage":"","size":2512,"stargazers_count":792,"watchers_count":792,"language":"JavaScript","has_issues":true,"has_projects":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":77,"mirror_url":null,"archived":false,"open_issues_count":37,"license":{"key":"other","name":"Other","spdx_id":"NOASSERTION","url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":77,"open_issues":37,"watchers":792,"default_branch":"master"}},"base":{"label":"eslint:master","ref":"master","sha":"a9d932adfe128c0e58c350bfee678feebc8780d9","user":{"login":"eslint","id":6019716,"node_id":"MDEyOk9yZ2FuaXphdGlvbjYwMTk3MTY=","avatar_url":"https://avatars3.githubusercontent.com/u/6019716?v=4","gravatar_id":"","url":"https://api.github.com/users/eslint","html_url":"https://github.com/eslint","followers_url":"https://api.github.com/users/eslint/followers","following_url":"https://api.github.com/users/eslint/following{/other_user}","gists_url":"https://api.github.com/users/eslint/gists{/gist_id}","starred_url":"https://api.github.com/users/eslint/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/eslint/subscriptions","organizations_url":"https://api.github.com/users/eslint/orgs","repos_url":"https://api.github.com/users/eslint/repos","events_url":"https://api.github.com/users/eslint/events{/privacy}","received_events_url":"https://api.github.com/users/eslint/received_events","type":"Organization","site_admin":false},"repo":{"id":47434220,"node_id":"MDEwOlJlcG9zaXRvcnk0NzQzNDIyMA==","name":"typescript-eslint-parser","full_name":"eslint/typescript-eslint-parser","private":false,"owner":{"login":"eslint","id":6019716,"node_id":"MDEyOk9yZ2FuaXphdGlvbjYwMTk3MTY=","avatar_url":"https://avatars3.githubusercontent.com/u/6019716?v=4","gravatar_id":"","url":"https://api.github.com/users/eslint","html_url":"https://github.com/eslint","followers_url":"https://api.github.com/users/eslint/followers","following_url":"https://api.github.com/users/eslint/following{/other_user}","gists_url":"https://api.github.com/users/eslint/gists{/gist_id}","starred_url":"https://api.github.com/users/eslint/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/eslint/subscriptions","organizations_url":"https://api.github.com/users/eslint/orgs","repos_url":"https://api.github.com/users/eslint/repos","events_url":"https://api.github.com/users/eslint/events{/privacy}","received_events_url":"https://api.github.com/users/eslint/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/eslint/typescript-eslint-parser","description":"An ESLint custom parser which leverages TypeScript ESTree to allow for ESLint to lint TypeScript source code.","fork":false,"url":"https://api.github.com/repos/eslint/typescript-eslint-parser","forks_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/forks","keys_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/keys{/key_id}","collaborators_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/teams","hooks_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/hooks","issue_events_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/issues/events{/number}","events_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/events","assignees_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/assignees{/user}","branches_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/branches{/branch}","tags_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/tags","blobs_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/git/refs{/sha}","trees_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/git/trees{/sha}","statuses_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/statuses/{sha}","languages_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/languages","stargazers_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/stargazers","contributors_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/contributors","subscribers_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/subscribers","subscription_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/subscription","commits_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/commits{/sha}","git_commits_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/git/commits{/sha}","comments_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/comments{/number}","issue_comment_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/issues/comments{/number}","contents_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/contents/{+path}","compare_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/compare/{base}...{head}","merges_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/merges","archive_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/downloads","issues_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/issues{/number}","pulls_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/pulls{/number}","milestones_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/milestones{/number}","notifications_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/labels{/name}","releases_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/releases{/id}","deployments_url":"https://api.github.com/repos/eslint/typescript-eslint-parser/deployments","created_at":"2015-12-04T23:36:41Z","updated_at":"2018-11-09T03:01:51Z","pushed_at":"2018-11-09T03:01:49Z","git_url":"git://github.com/eslint/typescript-eslint-parser.git","ssh_url":"git@github.com:eslint/typescript-eslint-parser.git","clone_url":"https://github.com/eslint/typescript-eslint-parser.git","svn_url":"https://github.com/eslint/typescript-eslint-parser","homepage":"","size":2512,"stargazers_count":792,"watchers_count":792,"language":"JavaScript","has_issues":true,"has_projects":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":77,"mirror_url":null,"archived":false,"open_issues_count":37,"license":{"key":"other","name":"Other","spdx_id":"NOASSERTION","url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":77,"open_issues":37,"watchers":792,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/eslint/typescript-eslint-parser/pulls/540"},"html":{"href":"https://github.com/eslint/typescript-eslint-parser/pull/540"},"issue":{"href":"https://api.github.com/repos/eslint/typescript-eslint-parser/issues/540"},"comments":{"href":"https://api.github.com/repos/eslint/typescript-eslint-parser/issues/540/comments"},"review_comments":{"href":"https://api.github.com/repos/eslint/typescript-eslint-parser/pulls/540/comments"},"review_comment":{"href":"https://api.github.com/repos/eslint/typescript-eslint-parser/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/eslint/typescript-eslint-parser/pulls/540/commits"},"statuses":{"href":"https://api.github.com/repos/eslint/typescript-eslint-parser/statuses/044563be23b54a82dd8dc4f8449d325789595c72"}},"author_association":"MEMBER"}}
{"actor":{"display_login":"JamesHenry"}}