diff --git a/package.json b/package.json index a67b9e2..563b332 100644 --- a/package.json +++ b/package.json @@ -116,10 +116,10 @@ "ts-jest": "^23.10.2", "ts-node": "^7.0.1", "tslint": "^5.11.0", + "tslint-config-airbnb": "^5.11.1", "tslint-config-prettier": "^1.15.0", - "tslint-config-standard": "^8.0.1", "typedoc": "^0.12.0", - "typescript": "^3.0.3" + "typescript": "~3.3.0" }, "peerDependencies": { "graphql": "^0.12.0 || ^0.13.0 || ^14.0.0" diff --git a/src/RewriteHandler.ts b/src/RewriteHandler.ts index f7b824c..4c5f876 100644 --- a/src/RewriteHandler.ts +++ b/src/RewriteHandler.ts @@ -1,6 +1,6 @@ -import Rewriter, { Variables } from './rewriters/Rewriter'; import { parse, print } from 'graphql'; -import { rewriteDoc, extractPath, rewriteResultsAtPath } from './ast'; +import { extractPath, rewriteDoc, rewriteResultsAtPath } from './ast'; +import Rewriter, { Variables } from './rewriters/Rewriter'; interface RewriterMatch { rewriter: Rewriter; @@ -17,7 +17,7 @@ export default class RewriteHandler { this.rewriters = rewriters; } - rewriteRequest(query: string, variables?: Variables) { + public rewriteRequest(query: string, variables?: Variables) { if (this.hasProcessedRequest) throw new Error('This handler has already rewritten a request'); this.hasProcessedRequest = true; const doc = parse(query); @@ -42,7 +42,7 @@ export default class RewriteHandler { return { query: print(rewrittenDoc), variables: rewrittenVariables }; } - rewriteResponse(response: any) { + public rewriteResponse(response: any) { if (this.hasProcessedResponse) throw new Error('This handler has already returned a response'); this.hasProcessedResponse = true; let rewrittenResponse = response; diff --git a/src/ast.ts b/src/ast.ts index 67ff4e5..3590826 100644 --- a/src/ast.ts +++ b/src/ast.ts @@ -1,4 +1,4 @@ -import { ASTNode, ArgumentNode, DocumentNode, VariableDefinitionNode } from 'graphql'; +import { ASTNode, DocumentNode, VariableDefinitionNode } from 'graphql'; const ignoreKeys = new Set(['loc']); @@ -52,8 +52,8 @@ export const rewriteDoc = ( (node as any)[key] = val.map(elm => { if (typeof elm === 'object') { const next: NodeAndVarDefs = { - node: elm, - variableDefinitions + variableDefinitions, + node: elm }; return walkRecursive(next, nextParents); } @@ -61,8 +61,8 @@ export const rewriteDoc = ( }); } else if (typeof val === 'object') { const next: NodeAndVarDefs = { - node: val, - variableDefinitions + variableDefinitions, + node: val }; (node as any)[key] = walkRecursive(next, nextParents); } @@ -71,8 +71,8 @@ export const rewriteDoc = ( }; const root: NodeAndVarDefs = { - node: doc, - variableDefinitions + variableDefinitions, + node: doc }; const rewrittenDoc = walkRecursive(root, []) as DocumentNode; return replaceVariableDefinitions(rewrittenDoc, variableDefinitions); @@ -115,9 +115,9 @@ export const extractPath = (parents: ReadonlyArray): ReadonlyArray arg.name.value === this.oldArgName); } - rewriteQuery({ node, variableDefinitions }: NodeAndVarDefs) { + public rewriteQuery({ node, variableDefinitions }: NodeAndVarDefs) { const newArguments = ((node as FieldNode).arguments || []).map(argument => { if (argument.name.value === this.oldArgName) { return { ...argument, name: { ...argument.name, value: this.newArgName } }; } return argument; }); - return { node: { ...node, arguments: newArguments }, variableDefinitions } as NodeAndVarDefs; + return { variableDefinitions, node: { ...node, arguments: newArguments } } as NodeAndVarDefs; } } diff --git a/src/rewriters/FieldArgTypeRewriter.ts b/src/rewriters/FieldArgTypeRewriter.ts index fc16c3a..294c0ec 100644 --- a/src/rewriters/FieldArgTypeRewriter.ts +++ b/src/rewriters/FieldArgTypeRewriter.ts @@ -1,7 +1,7 @@ -import Rewriter, { Variables, RewriterOpts } from './Rewriter'; -import { ASTNode, parseType, FieldNode, ArgumentNode, VariableNode, TypeNode } from 'graphql'; -import { nodesMatch, NodeAndVarDefs } from '../ast'; +import { ArgumentNode, ASTNode, FieldNode, parseType, TypeNode, VariableNode } from 'graphql'; +import { NodeAndVarDefs, nodesMatch } from '../ast'; import { identifyFunc } from '../utils'; +import Rewriter, { RewriterOpts, Variables } from './Rewriter'; interface FieldArgTypeRewriterOpts extends RewriterOpts { argName: string; @@ -28,7 +28,7 @@ class FieldArgTypeRewriter extends Rewriter { this.coerceVariable = options.coerceVariable || identifyFunc; } - matches(nodeAndVars: NodeAndVarDefs, parents: ASTNode[]) { + public matches(nodeAndVars: NodeAndVarDefs, parents: ASTNode[]) { if (!super.matches(nodeAndVars, parents)) return false; const node = nodeAndVars.node as FieldNode; const { variableDefinitions } = nodeAndVars; @@ -49,7 +49,7 @@ class FieldArgTypeRewriter extends Rewriter { return false; } - rewriteQuery({ node, variableDefinitions }: NodeAndVarDefs) { + public rewriteQuery({ node, variableDefinitions }: NodeAndVarDefs) { const varRefName = this.extractMatchingVarRefName(node as FieldNode); const newVarDefs = variableDefinitions.map(varDef => { if (varDef.variable.name.value !== varRefName) return varDef; @@ -58,7 +58,7 @@ class FieldArgTypeRewriter extends Rewriter { return { node, variableDefinitions: newVarDefs }; } - rewriteVariables({ node }: NodeAndVarDefs, variables: Variables) { + public rewriteVariables({ node }: NodeAndVarDefs, variables: Variables) { if (!variables) return variables; const varRefName = this.extractMatchingVarRefName(node as FieldNode); return { ...variables, [varRefName]: this.coerceVariable(variables[varRefName]) }; diff --git a/src/rewriters/FieldArgsToInputTypeRewriter.ts b/src/rewriters/FieldArgsToInputTypeRewriter.ts index 680f7e8..0f52b54 100644 --- a/src/rewriters/FieldArgsToInputTypeRewriter.ts +++ b/src/rewriters/FieldArgsToInputTypeRewriter.ts @@ -1,6 +1,6 @@ -import Rewriter, { RewriterOpts } from './Rewriter'; -import { FieldNode, ArgumentNode, ObjectFieldNode, ASTNode } from 'graphql'; +import { ArgumentNode, ASTNode, FieldNode, ObjectFieldNode } from 'graphql'; import { NodeAndVarDefs } from '../ast'; +import Rewriter, { RewriterOpts } from './Rewriter'; interface FieldArgsToInputTypeRewriterOpts extends RewriterOpts { argNames: string[]; @@ -22,7 +22,7 @@ class FieldArgsToInputTypeRewriter extends Rewriter { if (options.inputArgName) this.inputArgName = options.inputArgName; } - matches(nodeAndVars: NodeAndVarDefs, parents: ASTNode[]) { + public matches(nodeAndVars: NodeAndVarDefs, parents: ASTNode[]) { if (!super.matches(nodeAndVars, parents)) return false; const node = nodeAndVars.node as FieldNode; // is this a field with the correct fieldName and arguments? @@ -35,7 +35,7 @@ class FieldArgsToInputTypeRewriter extends Rewriter { return !!node.arguments.find(arg => this.argNames.indexOf(arg.name.value) >= 0); } - rewriteQuery({ node, variableDefinitions }: NodeAndVarDefs) { + public rewriteQuery({ node, variableDefinitions }: NodeAndVarDefs) { const argsToNest = ((node as FieldNode).arguments || []).filter( argument => this.argNames.indexOf(argument.name.value) >= 0 ); @@ -57,7 +57,7 @@ class FieldArgsToInputTypeRewriter extends Rewriter { } }; newArguments.push(inputArgument); - return { node: { ...node, arguments: newArguments }, variableDefinitions } as NodeAndVarDefs; + return { variableDefinitions, node: { ...node, arguments: newArguments } } as NodeAndVarDefs; } } diff --git a/src/rewriters/NestFieldOutputsRewriter.ts b/src/rewriters/NestFieldOutputsRewriter.ts index 801ed1c..b0dde7f 100644 --- a/src/rewriters/NestFieldOutputsRewriter.ts +++ b/src/rewriters/NestFieldOutputsRewriter.ts @@ -1,6 +1,6 @@ -import Rewriter, { RewriterOpts } from './Rewriter'; -import { FieldNode, ASTNode } from 'graphql'; +import { ASTNode, FieldNode } from 'graphql'; import { NodeAndVarDefs } from '../ast'; +import Rewriter, { RewriterOpts } from './Rewriter'; interface NestFieldOutputsRewriterOpts extends RewriterOpts { newOutputName: string; @@ -21,7 +21,7 @@ class NestFieldOutputsRewriter extends Rewriter { this.outputsToNest = options.outputsToNest; } - matches(nodeAndVars: NodeAndVarDefs, parents: ASTNode[]) { + public matches(nodeAndVars: NodeAndVarDefs, parents: ASTNode[]) { if (!super.matches(nodeAndVars, parents)) return false; const node = nodeAndVars.node as FieldNode; // is this a field with the correct selections? @@ -40,7 +40,7 @@ class NestFieldOutputsRewriter extends Rewriter { ); } - rewriteQuery(nodeAndVarDefs: NodeAndVarDefs) { + public rewriteQuery(nodeAndVarDefs: NodeAndVarDefs) { const node = nodeAndVarDefs.node as FieldNode; const { variableDefinitions } = nodeAndVarDefs; if (!node.selectionSet) return nodeAndVarDefs; @@ -60,12 +60,12 @@ class NestFieldOutputsRewriter extends Rewriter { }; newOutputs.push(nestedOutput); return { - node: { ...node, selectionSet: { ...node.selectionSet, selections: newOutputs } }, - variableDefinitions + variableDefinitions, + node: { ...node, selectionSet: { ...node.selectionSet, selections: newOutputs } } } as NodeAndVarDefs; } - rewriteResponse(response: any) { + public rewriteResponse(response: any) { if (typeof response === 'object') { // undo the nesting in the response so it matches the original query if (response[this.newOutputName] && typeof response[this.newOutputName] === 'object') { diff --git a/src/rewriters/Rewriter.ts b/src/rewriters/Rewriter.ts index dc31e12..c77f3ea 100644 --- a/src/rewriters/Rewriter.ts +++ b/src/rewriters/Rewriter.ts @@ -18,7 +18,7 @@ abstract class Rewriter { if (rootTypes) this.rootTypes = rootTypes; } - matches({ node }: NodeAndVarDefs, parents: ReadonlyArray): boolean { + public matches({ node }: NodeAndVarDefs, parents: ReadonlyArray): boolean { if (node.kind !== 'Field' || node.name.value !== this.fieldName) return false; const root = parents[0]; if ( @@ -33,15 +33,15 @@ abstract class Rewriter { return true; } - rewriteQuery(nodeAndVarDefs: NodeAndVarDefs): NodeAndVarDefs { + public rewriteQuery(nodeAndVarDefs: NodeAndVarDefs): NodeAndVarDefs { return nodeAndVarDefs; } - rewriteVariables(_nodeAndVarDefs: NodeAndVarDefs, variables: Variables): Variables { + public rewriteVariables(nodeAndVarDefs: NodeAndVarDefs, variables: Variables): Variables { return variables; } - rewriteResponse(response: any): any { + public rewriteResponse(response: any): any { return response; } } diff --git a/test/ast.test.ts b/test/ast.test.ts index 3025e5b..bd499e8 100644 --- a/test/ast.test.ts +++ b/test/ast.test.ts @@ -1,10 +1,10 @@ +import { OperationDefinitionNode, parse } from 'graphql'; import { - rewriteResultsAtPath, - nodesMatch, extractVariableDefinitions, - replaceVariableDefinitions + nodesMatch, + replaceVariableDefinitions, + rewriteResultsAtPath } from '../src/ast'; -import { parse, OperationDefinitionNode } from 'graphql'; describe('ast utils', () => { describe('rewriteResultsAtPath', () => { diff --git a/test/testUtils.ts b/test/testUtils.ts index 88f342d..2623ccc 100644 --- a/test/testUtils.ts +++ b/test/testUtils.ts @@ -1,4 +1,4 @@ import * as dedent from 'dedent-js'; export const gqlFmt = (templateStrings: TemplateStringsArray | string, ...values: any[]) => - dedent(templateStrings, ...values) + '\n'; + `${dedent(templateStrings, ...values)}\n`; diff --git a/tslint.json b/tslint.json index 398a416..8017b5b 100644 --- a/tslint.json +++ b/tslint.json @@ -1,6 +1,8 @@ { - "extends": [ - "tslint-config-standard", - "tslint-config-prettier" - ] -} \ No newline at end of file + "extends": ["tslint:recommended", "tslint-config-airbnb", "tslint-config-prettier"], + "rules": { + "interface-name": false, + "object-literal-sort-keys": false, + "no-increment-decrement": false + } +} diff --git a/yarn.lock b/yarn.lock index af1dbf9..fea5d6a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -776,6 +776,25 @@ dependencies: find-up "^2.1.0" +"@fimbul/bifrost@^0.17.0": + version "0.17.0" + resolved "https://registry.yarnpkg.com/@fimbul/bifrost/-/bifrost-0.17.0.tgz#f0383ba7e40992e3193dc87e2ddfde2ad62a9cf4" + integrity sha512-gVTkJAOef5HtN6LPmrtt5fAUmBywwlgmObsU3FBhPoNeXPLaIl2zywXkJEtvvVLQnaFmtff3x+wIj5lHRCDE3Q== + dependencies: + "@fimbul/ymir" "^0.17.0" + get-caller-file "^2.0.0" + tslib "^1.8.1" + tsutils "^3.5.0" + +"@fimbul/ymir@^0.17.0": + version "0.17.0" + resolved "https://registry.yarnpkg.com/@fimbul/ymir/-/ymir-0.17.0.tgz#4f28389b9f804d1cd202e11983af1743488b7815" + integrity sha512-xMXM9KTXRLHLVS6dnX1JhHNEkmWHcAVCQ/4+DA1KKwC/AFnGHzu/7QfQttEPgw3xplT+ILf9e3i64jrFwB3JtA== + dependencies: + inversify "^5.0.0" + reflect-metadata "^0.1.12" + tslib "^1.8.1" + "@marionebl/sander@^0.6.0": version "0.6.1" resolved "https://registry.yarnpkg.com/@marionebl/sander/-/sander-0.6.1.tgz#1958965874f24bc51be48875feb50d642fc41f7b" @@ -3358,7 +3377,7 @@ get-caller-file@^1.0.1: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== -get-caller-file@^2.0.1: +get-caller-file@^2.0.0, get-caller-file@^2.0.1: version "2.0.5" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== @@ -3923,6 +3942,11 @@ invariant@^2.2.2, invariant@^2.2.4: dependencies: loose-envify "^1.0.0" +inversify@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/inversify/-/inversify-5.0.1.tgz#500d709b1434896ce5a0d58915c4a4210e34fb6e" + integrity sha512-Ieh06s48WnEYGcqHepdsJUIJUXpwH5o5vodAX+DK2JA/gjy4EbEcQZxw+uFfzysmKjiLXGYwNG3qDZsKVMcINQ== + invert-kv@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" @@ -7019,6 +7043,11 @@ redeyed@~2.1.0: dependencies: esprima "~4.0.0" +reflect-metadata@^0.1.12: + version "0.1.13" + resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08" + integrity sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg== + regenerate-unicode-properties@^8.0.2: version "8.0.2" resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.0.2.tgz#7b38faa296252376d363558cfbda90c9ce709662" @@ -8309,24 +8338,35 @@ tslib@1.9.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.0.tgz#e37a86fda8cbbaf23a057f473c9f4dc64e5fc2e8" integrity sha512-f/qGG2tUkrISBlQZEjEqoZ3B2+npJjIf04H1wuAv9iA8i04Icp+61KRXxFdha22670NJopsZCIjhC3SnjPRKrQ== -tslib@1.9.3, tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0: +tslib@1.9.3, tslib@^1.7.1, tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ== +tslint-config-airbnb@^5.11.1: + version "5.11.1" + resolved "https://registry.yarnpkg.com/tslint-config-airbnb/-/tslint-config-airbnb-5.11.1.tgz#51a27fbb8bf24c144d064a274a71da47e7ece617" + integrity sha512-hkaittm2607vVMe8eotANGN1CimD5tor7uoY3ypg2VTtEcDB/KGWYbJOz58t8LI4cWSyWtgqYQ5F0HwKxxhlkQ== + dependencies: + tslint-consistent-codestyle "^1.14.1" + tslint-eslint-rules "^5.4.0" + tslint-microsoft-contrib "~5.2.1" + tslint-config-prettier@^1.15.0: version "1.18.0" resolved "https://registry.yarnpkg.com/tslint-config-prettier/-/tslint-config-prettier-1.18.0.tgz#75f140bde947d35d8f0d238e0ebf809d64592c37" integrity sha512-xPw9PgNPLG3iKRxmK7DWr+Ea/SzrvfHtjFt5LBl61gk2UBG/DB9kCXRjv+xyIU1rUtnayLeMUVJBcMX8Z17nDg== -tslint-config-standard@^8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/tslint-config-standard/-/tslint-config-standard-8.0.1.tgz#e4dd3128e84b0e34b51990b68715a641f2b417e4" - integrity sha512-OWG+NblgjQlVuUS/Dmq3ax2v5QDZwRx4L0kEuDi7qFY9UI6RJhhNfoCV1qI4el8Fw1c5a5BTrjQJP0/jhGXY/Q== +tslint-consistent-codestyle@^1.14.1: + version "1.15.1" + resolved "https://registry.yarnpkg.com/tslint-consistent-codestyle/-/tslint-consistent-codestyle-1.15.1.tgz#a0c5cd5a5860d40b659c490d8013c5732e02af8c" + integrity sha512-38Y3Dz4zcABe/PlPAQSGNEWPGVq0OzcIQR7SEU6dNujp/SgvhxhJOhIhI9gY4r0I3/TNtvVQwARWor9O9LPZWg== dependencies: - tslint-eslint-rules "^5.3.1" + "@fimbul/bifrost" "^0.17.0" + tslib "^1.7.1" + tsutils "^2.29.0" -tslint-eslint-rules@^5.3.1: +tslint-eslint-rules@^5.4.0: version "5.4.0" resolved "https://registry.yarnpkg.com/tslint-eslint-rules/-/tslint-eslint-rules-5.4.0.tgz#e488cc9181bf193fe5cd7bfca213a7695f1737b5" integrity sha512-WlSXE+J2vY/VPgIcqQuijMQiel+UtmXS+4nvK4ZzlDiqBfXse8FAvkNnTcYhnQyOTW5KFM+uRRGXxYhFpuBc6w== @@ -8335,6 +8375,13 @@ tslint-eslint-rules@^5.3.1: tslib "1.9.0" tsutils "^3.0.0" +tslint-microsoft-contrib@~5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/tslint-microsoft-contrib/-/tslint-microsoft-contrib-5.2.1.tgz#a6286839f800e2591d041ea2800c77487844ad81" + integrity sha512-PDYjvpo0gN9IfMULwKk0KpVOPMhU6cNoT9VwCOLeDl/QS8v8W2yspRpFFuUS7/c5EIH/n8ApMi8TxJAz1tfFUA== + dependencies: + tsutils "^2.27.2 <2.29.0" + tslint@^5.11.0: version "5.15.0" resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.15.0.tgz#6ffb180986d63afa1e531feb2a134dbf961e27d3" @@ -8354,6 +8401,13 @@ tslint@^5.11.0: tslib "^1.8.0" tsutils "^2.29.0" +"tsutils@^2.27.2 <2.29.0": + version "2.28.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.28.0.tgz#6bd71e160828f9d019b6f4e844742228f85169a1" + integrity sha512-bh5nAtW0tuhvOJnx1GLRn5ScraRLICGyJV5wJhtRWOLsxW70Kk5tZtpK3O/hW6LDnqKS9mlUMPZj9fEMJ0gxqA== + dependencies: + tslib "^1.8.1" + tsutils@^2.29.0: version "2.29.0" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.29.0.tgz#32b488501467acbedd4b85498673a0812aca0b99" @@ -8361,7 +8415,7 @@ tsutils@^2.29.0: dependencies: tslib "^1.8.1" -tsutils@^3.0.0: +tsutils@^3.0.0, tsutils@^3.5.0: version "3.10.0" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.10.0.tgz#6f1c95c94606e098592b0dff06590cf9659227d6" integrity sha512-q20XSMq7jutbGB8luhKKsQldRKWvyBO2BGqni3p4yq8Ys9bEP/xQw3KepKmMRt9gJ4lvQSScrihJrcKdKoSU7Q== @@ -8425,10 +8479,10 @@ typescript@3.0.x: resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.0.3.tgz#4853b3e275ecdaa27f78fda46dc273a7eb7fc1c8" integrity sha512-kk80vLW9iGtjMnIv11qyxLqZm20UklzuR2tL0QAnDIygIUIemcZMxlMWudl9OOt76H3ntVzcTiddQ1/pAAJMYg== -typescript@^3.0.3: - version "3.4.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.4.2.tgz#9ed4e6475d906f589200193be056f5913caed481" - integrity sha512-Og2Vn6Mk7JAuWA1hQdDQN/Ekm/SchX80VzLhjKN9ETYrIepBFAd8PkOdOTK2nKt0FCkmMZKBJvQ1dV1gIxPu/A== +typescript@~3.3.0: + version "3.3.4000" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.3.4000.tgz#76b0f89cfdbf97827e1112d64f283f1151d6adf0" + integrity sha512-jjOcCZvpkl2+z7JFn0yBOoLQyLoIkNZAs/fYJkUG6VKy6zLPHJGfQJYFHzibB6GJaF/8QrcECtlQ5cpvRHSMEA== uglify-js@^3.1.4: version "3.5.3"