Mirror: TypeScript LSP plugin that finds GraphQL documents in your code and provides diagnostics, auto-complete and hover-information.
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

add prettier

+785 -261
+4
.husky/pre-commit
··· 1 + #!/usr/bin/env sh 2 + . "$(dirname -- "$0")/_/husky.sh" 3 + 4 + pnpm lint-staged
+14 -2
package.json
··· 4 4 "description": "https://github.com/microsoft/TypeScript/wiki/Writing-a-Language-Service-Plugin", 5 5 "main": "src/index.js", 6 6 "scripts": { 7 - "test": "echo \"Error: no test specified\" && exit 1" 7 + "test": "echo \"Error: no test specified\" && exit 1", 8 + "prepare": "husky install" 8 9 }, 9 10 "repository": { 10 11 "type": "git", ··· 17 18 "url": "https://github.com/JoviDeCroock/GraphQLSP/issues" 18 19 }, 19 20 "homepage": "https://github.com/JoviDeCroock/GraphQLSP#readme", 21 + "prettier": { 22 + "singleQuote": true, 23 + "arrowParens": "avoid", 24 + "trailingComma": "es5" 25 + }, 26 + "lint-staged": { 27 + "*.{ts,json,md}": "prettier --write" 28 + }, 20 29 "devDependencies": { 21 - "@types/node": "^18.15.11", 22 30 "@changesets/cli": "^2.26.1", 23 31 "@changesets/get-github-info": "^0.5.2", 32 + "@types/node": "^18.15.11", 24 33 "dotenv": "^16.0.3", 25 34 "graphql": "^16.5.0", 35 + "husky": "^8.0.3", 36 + "lint-staged": "^13.2.1", 37 + "prettier": "^2.8.7", 26 38 "typescript": "^5.0.0" 27 39 }, 28 40 "dependencies": {
+363 -3
pnpm-lock.yaml
··· 33 33 graphql: 34 34 specifier: ^16.5.0 35 35 version: 16.5.0 36 + husky: 37 + specifier: ^8.0.3 38 + version: 8.0.3 39 + lint-staged: 40 + specifier: ^13.2.1 41 + version: 13.2.1 42 + prettier: 43 + specifier: ^2.8.7 44 + version: 2.8.7 36 45 typescript: 37 46 specifier: ^5.0.0 38 47 version: 5.0.4 ··· 1093 1102 resolution: {integrity: sha512-KQf+QAMWKMrtBMsB8/24w53tEsxllMj6TuA80TT/5igJalLI/zm0L3oXRbIAl4Ohfc85gyHX/jhMwsVkmhLU4A==} 1094 1103 dev: true 1095 1104 1105 + /aggregate-error@3.1.0: 1106 + resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} 1107 + engines: {node: '>=8'} 1108 + dependencies: 1109 + clean-stack: 2.2.0 1110 + indent-string: 4.0.0 1111 + dev: true 1112 + 1096 1113 /ansi-colors@4.1.3: 1097 1114 resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} 1098 1115 engines: {node: '>=6'} 1116 + dev: true 1117 + 1118 + /ansi-escapes@4.3.2: 1119 + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} 1120 + engines: {node: '>=8'} 1121 + dependencies: 1122 + type-fest: 0.21.3 1099 1123 dev: true 1100 1124 1101 1125 /ansi-regex@5.0.1: 1102 1126 resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} 1103 1127 engines: {node: '>=8'} 1104 1128 1129 + /ansi-regex@6.0.1: 1130 + resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} 1131 + engines: {node: '>=12'} 1132 + dev: true 1133 + 1105 1134 /ansi-styles@3.2.1: 1106 1135 resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} 1107 1136 engines: {node: '>=4'} ··· 1113 1142 engines: {node: '>=8'} 1114 1143 dependencies: 1115 1144 color-convert: 2.0.1 1145 + 1146 + /ansi-styles@6.2.1: 1147 + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} 1148 + engines: {node: '>=12'} 1149 + dev: true 1116 1150 1117 1151 /argparse@1.0.10: 1118 1152 resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} ··· 1150 1184 /asap@2.0.6: 1151 1185 resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} 1152 1186 dev: false 1187 + 1188 + /astral-regex@2.0.0: 1189 + resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} 1190 + engines: {node: '>=8'} 1191 + dev: true 1153 1192 1154 1193 /auto-bind@4.0.0: 1155 1194 resolution: {integrity: sha512-Hdw8qdNiqdJ8LqT0iK0sVzkFbzg6fhnQqqfWhBDxcHZvU75+B+ayzTy8x+k5Ix0Y92XOhOUlx74ps+bA6BeYMQ==} ··· 1304 1343 ansi-styles: 4.3.0 1305 1344 supports-color: 7.2.0 1306 1345 1346 + /chalk@5.2.0: 1347 + resolution: {integrity: sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==} 1348 + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} 1349 + dev: true 1350 + 1307 1351 /change-case-all@1.0.15: 1308 1352 resolution: {integrity: sha512-3+GIFhk3sNuvFAJKU46o26OdzudQlPNBCu1ZQi3cMeMHhty1bhDxu2WrEilVNYaGvqUtR1VSigFcJOiS13dRhQ==} 1309 1353 dependencies: ··· 1345 1389 engines: {node: '>=8'} 1346 1390 dev: true 1347 1391 1392 + /clean-stack@2.2.0: 1393 + resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} 1394 + engines: {node: '>=6'} 1395 + dev: true 1396 + 1397 + /cli-cursor@3.1.0: 1398 + resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} 1399 + engines: {node: '>=8'} 1400 + dependencies: 1401 + restore-cursor: 3.1.0 1402 + dev: true 1403 + 1404 + /cli-truncate@2.1.0: 1405 + resolution: {integrity: sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==} 1406 + engines: {node: '>=8'} 1407 + dependencies: 1408 + slice-ansi: 3.0.0 1409 + string-width: 4.2.3 1410 + dev: true 1411 + 1412 + /cli-truncate@3.1.0: 1413 + resolution: {integrity: sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==} 1414 + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 1415 + dependencies: 1416 + slice-ansi: 5.0.0 1417 + string-width: 5.1.2 1418 + dev: true 1419 + 1348 1420 /cliui@6.0.0: 1349 1421 resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} 1350 1422 dependencies: ··· 1383 1455 /color-name@1.1.4: 1384 1456 resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} 1385 1457 1458 + /colorette@2.0.19: 1459 + resolution: {integrity: sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==} 1460 + dev: true 1461 + 1462 + /commander@10.0.0: 1463 + resolution: {integrity: sha512-zS5PnTI22FIRM6ylNW8G4Ap0IEOyk62fhLSD0+uHRT9McRCLGpkVNvao4bjimpK/GShynyQkFFxHhwMcETmduA==} 1464 + engines: {node: '>=14'} 1465 + dev: true 1466 + 1386 1467 /common-tags@1.8.2: 1387 1468 resolution: {integrity: sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==} 1388 1469 engines: {node: '>=4.0.0'} ··· 1420 1501 which: 1.3.1 1421 1502 dev: true 1422 1503 1504 + /cross-spawn@7.0.3: 1505 + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} 1506 + engines: {node: '>= 8'} 1507 + dependencies: 1508 + path-key: 3.1.1 1509 + shebang-command: 2.0.0 1510 + which: 2.0.2 1511 + dev: true 1512 + 1423 1513 /csv-generate@3.4.3: 1424 1514 resolution: {integrity: sha512-w/T+rqR0vwvHqWs/1ZyMDWtHHSJaN06klRqJXBEpDJaM/+dZkso0OKh1VcuuYvK3XM53KysVNq8Ko/epCK8wOw==} 1425 1515 dev: true ··· 1456 1546 optional: true 1457 1547 dependencies: 1458 1548 ms: 2.1.2 1459 - dev: false 1460 1549 1461 1550 /decamelize-keys@1.1.1: 1462 1551 resolution: {integrity: sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==} ··· 1513 1602 engines: {node: '>=12'} 1514 1603 dev: true 1515 1604 1605 + /eastasianwidth@0.2.0: 1606 + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} 1607 + dev: true 1608 + 1516 1609 /electron-to-chromium@1.4.284: 1517 1610 resolution: {integrity: sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==} 1518 1611 dev: false 1519 1612 1520 1613 /emoji-regex@8.0.0: 1521 1614 resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} 1615 + 1616 + /emoji-regex@9.2.2: 1617 + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} 1618 + dev: true 1522 1619 1523 1620 /enquirer@2.3.6: 1524 1621 resolution: {integrity: sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==} ··· 1609 1706 resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} 1610 1707 engines: {node: '>=4'} 1611 1708 hasBin: true 1709 + dev: true 1710 + 1711 + /execa@7.1.1: 1712 + resolution: {integrity: sha512-wH0eMf/UXckdUYnO21+HDztteVv05rq2GXksxT4fCGeHkBhw1DROXh40wcjMcRqDOWE7iPJ4n3M7e2+YFP+76Q==} 1713 + engines: {node: ^14.18.0 || ^16.14.0 || >=18.0.0} 1714 + dependencies: 1715 + cross-spawn: 7.0.3 1716 + get-stream: 6.0.1 1717 + human-signals: 4.3.1 1718 + is-stream: 3.0.0 1719 + merge-stream: 2.0.0 1720 + npm-run-path: 5.1.0 1721 + onetime: 6.0.0 1722 + signal-exit: 3.0.7 1723 + strip-final-newline: 3.0.0 1612 1724 dev: true 1613 1725 1614 1726 /extendable-error@0.1.7: ··· 1757 1869 has-symbols: 1.0.3 1758 1870 dev: true 1759 1871 1872 + /get-stream@6.0.1: 1873 + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} 1874 + engines: {node: '>=10'} 1875 + dev: true 1876 + 1760 1877 /get-symbol-description@1.0.0: 1761 1878 resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} 1762 1879 engines: {node: '>= 0.4'} ··· 1908 2025 resolution: {integrity: sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw==} 1909 2026 dev: true 1910 2027 2028 + /human-signals@4.3.1: 2029 + resolution: {integrity: sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==} 2030 + engines: {node: '>=14.18.0'} 2031 + dev: true 2032 + 2033 + /husky@8.0.3: 2034 + resolution: {integrity: sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==} 2035 + engines: {node: '>=14'} 2036 + hasBin: true 2037 + dev: true 2038 + 1911 2039 /iconv-lite@0.4.24: 1912 2040 resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} 1913 2041 engines: {node: '>=0.10.0'} ··· 2029 2157 resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} 2030 2158 engines: {node: '>=8'} 2031 2159 2160 + /is-fullwidth-code-point@4.0.0: 2161 + resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} 2162 + engines: {node: '>=12'} 2163 + dev: true 2164 + 2032 2165 /is-glob@4.0.3: 2033 2166 resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} 2034 2167 engines: {node: '>=0.10.0'} ··· 2085 2218 call-bind: 1.0.2 2086 2219 dev: true 2087 2220 2221 + /is-stream@3.0.0: 2222 + resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} 2223 + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 2224 + dev: true 2225 + 2088 2226 /is-string@1.0.7: 2089 2227 resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} 2090 2228 engines: {node: '>= 0.4'} ··· 2187 2325 engines: {node: '>=6'} 2188 2326 dev: true 2189 2327 2328 + /lilconfig@2.1.0: 2329 + resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} 2330 + engines: {node: '>=10'} 2331 + dev: true 2332 + 2190 2333 /lines-and-columns@1.2.4: 2191 2334 resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} 2192 2335 dev: true 2193 2336 2337 + /lint-staged@13.2.1: 2338 + resolution: {integrity: sha512-8gfzinVXoPfga5Dz/ZOn8I2GOhf81Wvs+KwbEXQn/oWZAvCVS2PivrXfVbFJc93zD16uC0neS47RXHIjXKYZQw==} 2339 + engines: {node: ^14.13.1 || >=16.0.0} 2340 + hasBin: true 2341 + dependencies: 2342 + chalk: 5.2.0 2343 + cli-truncate: 3.1.0 2344 + commander: 10.0.0 2345 + debug: 4.3.4 2346 + execa: 7.1.1 2347 + lilconfig: 2.1.0 2348 + listr2: 5.0.8 2349 + micromatch: 4.0.5 2350 + normalize-path: 3.0.0 2351 + object-inspect: 1.12.3 2352 + pidtree: 0.6.0 2353 + string-argv: 0.3.1 2354 + yaml: 2.2.1 2355 + transitivePeerDependencies: 2356 + - enquirer 2357 + - supports-color 2358 + dev: true 2359 + 2360 + /listr2@5.0.8: 2361 + resolution: {integrity: sha512-mC73LitKHj9w6v30nLNGPetZIlfpUniNSsxxrbaPcWOjDb92SHPzJPi/t+v1YC/lxKz/AJ9egOjww0qUuFxBpA==} 2362 + engines: {node: ^14.13.1 || >=16.0.0} 2363 + peerDependencies: 2364 + enquirer: '>= 2.3.0 < 3' 2365 + peerDependenciesMeta: 2366 + enquirer: 2367 + optional: true 2368 + dependencies: 2369 + cli-truncate: 2.1.0 2370 + colorette: 2.0.19 2371 + log-update: 4.0.0 2372 + p-map: 4.0.0 2373 + rfdc: 1.3.0 2374 + rxjs: 7.8.0 2375 + through: 2.3.8 2376 + wrap-ansi: 7.0.0 2377 + dev: true 2378 + 2194 2379 /load-yaml-file@0.2.0: 2195 2380 resolution: {integrity: sha512-OfCBkGEw4nN6JLtgRidPX6QxjBQGQf72q3si2uvqyFEMbycSFFHwAZeXx6cJgFM9wmLrf9zBwCP3Ivqa+LLZPw==} 2196 2381 engines: {node: '>=6'} ··· 2222 2407 resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} 2223 2408 dev: false 2224 2409 2410 + /log-update@4.0.0: 2411 + resolution: {integrity: sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==} 2412 + engines: {node: '>=10'} 2413 + dependencies: 2414 + ansi-escapes: 4.3.2 2415 + cli-cursor: 3.1.0 2416 + slice-ansi: 4.0.0 2417 + wrap-ansi: 6.2.0 2418 + dev: true 2419 + 2225 2420 /loose-envify@1.4.0: 2226 2421 resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} 2227 2422 hasBin: true ··· 2280 2475 yargs-parser: 18.1.3 2281 2476 dev: true 2282 2477 2478 + /merge-stream@2.0.0: 2479 + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} 2480 + dev: true 2481 + 2283 2482 /merge2@1.4.1: 2284 2483 resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} 2285 2484 engines: {node: '>= 8'} ··· 2293 2492 picomatch: 2.3.1 2294 2493 dev: true 2295 2494 2495 + /mimic-fn@2.1.0: 2496 + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} 2497 + engines: {node: '>=6'} 2498 + dev: true 2499 + 2500 + /mimic-fn@4.0.0: 2501 + resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} 2502 + engines: {node: '>=12'} 2503 + dev: true 2504 + 2296 2505 /min-indent@1.0.1: 2297 2506 resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} 2298 2507 engines: {node: '>=4'} ··· 2320 2529 2321 2530 /ms@2.1.2: 2322 2531 resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} 2323 - dev: false 2324 2532 2325 2533 /no-case@3.0.4: 2326 2534 resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} ··· 2357 2565 validate-npm-package-license: 3.0.4 2358 2566 dev: true 2359 2567 2568 + /normalize-path@3.0.0: 2569 + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} 2570 + engines: {node: '>=0.10.0'} 2571 + dev: true 2572 + 2573 + /npm-run-path@5.1.0: 2574 + resolution: {integrity: sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==} 2575 + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 2576 + dependencies: 2577 + path-key: 4.0.0 2578 + dev: true 2579 + 2360 2580 /nullthrows@1.1.1: 2361 2581 resolution: {integrity: sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==} 2362 2582 dev: false ··· 2391 2611 wrappy: 1.0.2 2392 2612 dev: false 2393 2613 2614 + /onetime@5.1.2: 2615 + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} 2616 + engines: {node: '>=6'} 2617 + dependencies: 2618 + mimic-fn: 2.1.0 2619 + dev: true 2620 + 2621 + /onetime@6.0.0: 2622 + resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} 2623 + engines: {node: '>=12'} 2624 + dependencies: 2625 + mimic-fn: 4.0.0 2626 + dev: true 2627 + 2394 2628 /os-tmpdir@1.0.2: 2395 2629 resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} 2396 2630 engines: {node: '>=0.10.0'} ··· 2438 2672 engines: {node: '>=6'} 2439 2673 dev: true 2440 2674 2675 + /p-map@4.0.0: 2676 + resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} 2677 + engines: {node: '>=10'} 2678 + dependencies: 2679 + aggregate-error: 3.1.0 2680 + dev: true 2681 + 2441 2682 /p-try@2.2.0: 2442 2683 resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} 2443 2684 engines: {node: '>=6'} ··· 2491 2732 engines: {node: '>=0.10.0'} 2492 2733 dev: false 2493 2734 2735 + /path-key@3.1.1: 2736 + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} 2737 + engines: {node: '>=8'} 2738 + dev: true 2739 + 2740 + /path-key@4.0.0: 2741 + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} 2742 + engines: {node: '>=12'} 2743 + dev: true 2744 + 2494 2745 /path-parse@1.0.7: 2495 2746 resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} 2496 2747 dev: true ··· 2519 2770 /picomatch@2.3.1: 2520 2771 resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} 2521 2772 engines: {node: '>=8.6'} 2773 + dev: true 2774 + 2775 + /pidtree@0.6.0: 2776 + resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==} 2777 + engines: {node: '>=0.10'} 2778 + hasBin: true 2522 2779 dev: true 2523 2780 2524 2781 /pify@4.0.1: ··· 2648 2905 supports-preserve-symlinks-flag: 1.0.0 2649 2906 dev: true 2650 2907 2908 + /restore-cursor@3.1.0: 2909 + resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} 2910 + engines: {node: '>=8'} 2911 + dependencies: 2912 + onetime: 5.1.2 2913 + signal-exit: 3.0.7 2914 + dev: true 2915 + 2651 2916 /reusify@1.0.4: 2652 2917 resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} 2653 2918 engines: {iojs: '>=1.0.0', node: '>=0.10.0'} 2654 2919 dev: true 2655 2920 2921 + /rfdc@1.3.0: 2922 + resolution: {integrity: sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==} 2923 + dev: true 2924 + 2656 2925 /run-parallel@1.2.0: 2657 2926 resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} 2658 2927 dependencies: 2659 2928 queue-microtask: 1.2.3 2660 2929 dev: true 2661 2930 2931 + /rxjs@7.8.0: 2932 + resolution: {integrity: sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==} 2933 + dependencies: 2934 + tslib: 2.4.1 2935 + dev: true 2936 + 2662 2937 /safe-regex-test@1.0.0: 2663 2938 resolution: {integrity: sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==} 2664 2939 dependencies: ··· 2703 2978 shebang-regex: 1.0.0 2704 2979 dev: true 2705 2980 2981 + /shebang-command@2.0.0: 2982 + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} 2983 + engines: {node: '>=8'} 2984 + dependencies: 2985 + shebang-regex: 3.0.0 2986 + dev: true 2987 + 2706 2988 /shebang-regex@1.0.0: 2707 2989 resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==} 2708 2990 engines: {node: '>=0.10.0'} 2709 2991 dev: true 2710 2992 2993 + /shebang-regex@3.0.0: 2994 + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} 2995 + engines: {node: '>=8'} 2996 + dev: true 2997 + 2711 2998 /side-channel@1.0.4: 2712 2999 resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} 2713 3000 dependencies: ··· 2729 3016 engines: {node: '>=8'} 2730 3017 dev: true 2731 3018 3019 + /slice-ansi@3.0.0: 3020 + resolution: {integrity: sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==} 3021 + engines: {node: '>=8'} 3022 + dependencies: 3023 + ansi-styles: 4.3.0 3024 + astral-regex: 2.0.0 3025 + is-fullwidth-code-point: 3.0.0 3026 + dev: true 3027 + 3028 + /slice-ansi@4.0.0: 3029 + resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} 3030 + engines: {node: '>=10'} 3031 + dependencies: 3032 + ansi-styles: 4.3.0 3033 + astral-regex: 2.0.0 3034 + is-fullwidth-code-point: 3.0.0 3035 + dev: true 3036 + 3037 + /slice-ansi@5.0.0: 3038 + resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} 3039 + engines: {node: '>=12'} 3040 + dependencies: 3041 + ansi-styles: 6.2.1 3042 + is-fullwidth-code-point: 4.0.0 3043 + dev: true 3044 + 2732 3045 /smartwrap@2.0.2: 2733 3046 resolution: {integrity: sha512-vCsKNQxb7PnCNd2wY1WClWifAc2lwqsG8OaswpJkVJsvMGcnEntdTCDajZCkk93Ay1U3t/9puJmb525Rg5MZBA==} 2734 3047 engines: {node: '>=6'} ··· 2794 3107 mixme: 0.5.9 2795 3108 dev: true 2796 3109 3110 + /string-argv@0.3.1: 3111 + resolution: {integrity: sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==} 3112 + engines: {node: '>=0.6.19'} 3113 + dev: true 3114 + 2797 3115 /string-width@4.2.3: 2798 3116 resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} 2799 3117 engines: {node: '>=8'} ··· 2801 3119 emoji-regex: 8.0.0 2802 3120 is-fullwidth-code-point: 3.0.0 2803 3121 strip-ansi: 6.0.1 3122 + 3123 + /string-width@5.1.2: 3124 + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} 3125 + engines: {node: '>=12'} 3126 + dependencies: 3127 + eastasianwidth: 0.2.0 3128 + emoji-regex: 9.2.2 3129 + strip-ansi: 7.0.1 3130 + dev: true 2804 3131 2805 3132 /string.prototype.trim@1.2.7: 2806 3133 resolution: {integrity: sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==} ··· 2833 3160 dependencies: 2834 3161 ansi-regex: 5.0.1 2835 3162 3163 + /strip-ansi@7.0.1: 3164 + resolution: {integrity: sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==} 3165 + engines: {node: '>=12'} 3166 + dependencies: 3167 + ansi-regex: 6.0.1 3168 + dev: true 3169 + 2836 3170 /strip-bom@3.0.0: 2837 3171 resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} 2838 3172 engines: {node: '>=4'} 3173 + dev: true 3174 + 3175 + /strip-final-newline@3.0.0: 3176 + resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} 3177 + engines: {node: '>=12'} 2839 3178 dev: true 2840 3179 2841 3180 /strip-indent@3.0.0: ··· 2873 3212 engines: {node: '>=8'} 2874 3213 dev: true 2875 3214 3215 + /through@2.3.8: 3216 + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} 3217 + dev: true 3218 + 2876 3219 /title-case@3.0.3: 2877 3220 resolution: {integrity: sha512-e1zGYRvbffpcHIrnuqT0Dh+gEJtDaxDSoG4JAIpq4oDFyooziLBIiYQv0GBT4FUAnUop5uZ1hiIAj7oAF6sOCA==} 2878 3221 dependencies: ··· 2908 3251 2909 3252 /tslib@2.4.1: 2910 3253 resolution: {integrity: sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==} 2911 - dev: false 2912 3254 2913 3255 /tty-table@4.2.1: 2914 3256 resolution: {integrity: sha512-xz0uKo+KakCQ+Dxj1D/tKn2FSyreSYWzdkL/BYhgN6oMW808g8QRMuh1atAV9fjTPbWBjfbkKQpI/5rEcnAc7g==} ··· 2926 3268 2927 3269 /type-fest@0.13.1: 2928 3270 resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==} 3271 + engines: {node: '>=10'} 3272 + dev: true 3273 + 3274 + /type-fest@0.21.3: 3275 + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} 2929 3276 engines: {node: '>=10'} 2930 3277 dev: true 2931 3278 ··· 3070 3417 isexe: 2.0.0 3071 3418 dev: true 3072 3419 3420 + /which@2.0.2: 3421 + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} 3422 + engines: {node: '>= 8'} 3423 + hasBin: true 3424 + dependencies: 3425 + isexe: 2.0.0 3426 + dev: true 3427 + 3073 3428 /wrap-ansi@6.2.0: 3074 3429 resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} 3075 3430 engines: {node: '>=8'} ··· 3101 3456 3102 3457 /yallist@2.1.2: 3103 3458 resolution: {integrity: sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==} 3459 + dev: true 3460 + 3461 + /yaml@2.2.1: 3462 + resolution: {integrity: sha512-e0WHiYql7+9wr4cWMx3TVQrNwejKaEe7/rHNmQmqRjazfOP5W8PB6Jpebb5o6fIapbz9o9+2ipcaTM2ZwDI6lw==} 3463 + engines: {node: '>= 14'} 3104 3464 dev: true 3105 3465 3106 3466 /yargs-parser@18.1.3:
+6 -4
src/cursor.ts
··· 1 - import { IPosition } from "graphql-language-service"; 1 + import { IPosition } from 'graphql-language-service'; 2 2 3 3 export class Cursor implements IPosition { 4 4 line: number; ··· 18 18 } 19 19 20 20 lessThanOrEqualTo(position: IPosition) { 21 - return this.line < position.line || 22 - (this.line === position.line && this.character <= position.character); 21 + return ( 22 + this.line < position.line || 23 + (this.line === position.line && this.character <= position.character) 24 + ); 23 25 } 24 - } 26 + }
+24 -15
src/getSchema.ts
··· 1 - import { GraphQLSchema, buildSchema, buildClientSchema } from 'graphql' 2 - import path from 'path' 3 - import fs from 'fs' 1 + import { GraphQLSchema, buildSchema, buildClientSchema } from 'graphql'; 2 + import path from 'path'; 3 + import fs from 'fs'; 4 4 5 - export const loadSchema = (root: string, schema: string): { current: GraphQLSchema | null } => { 6 - const ref: { current: GraphQLSchema | null } = { current: null } 5 + export const loadSchema = ( 6 + root: string, 7 + schema: string 8 + ): { current: GraphQLSchema | null } => { 9 + const ref: { current: GraphQLSchema | null } = { current: null }; 7 10 const isJson = schema.endsWith('json'); 8 - const resolvedPath = path.resolve(path.dirname(root), schema) 9 - const contents = fs.readFileSync(resolvedPath, 'utf-8') 11 + const resolvedPath = path.resolve(path.dirname(root), schema); 12 + const contents = fs.readFileSync(resolvedPath, 'utf-8'); 10 13 11 14 fs.watchFile(resolvedPath, () => { 12 - const contents = fs.readFileSync(resolvedPath, 'utf-8') 13 - const parsedSchema = isJson ? buildClientSchema(JSON.parse(contents)) : buildSchema(contents) 14 - ref.current = isJson ? buildClientSchema(JSON.parse(contents)) : buildSchema(contents) 15 - return ref 16 - }) 15 + const contents = fs.readFileSync(resolvedPath, 'utf-8'); 16 + const parsedSchema = isJson 17 + ? buildClientSchema(JSON.parse(contents)) 18 + : buildSchema(contents); 19 + ref.current = isJson 20 + ? buildClientSchema(JSON.parse(contents)) 21 + : buildSchema(contents); 22 + return ref; 23 + }); 17 24 18 - ref.current = isJson ? buildClientSchema(JSON.parse(contents)) : buildSchema(contents) 25 + ref.current = isJson 26 + ? buildClientSchema(JSON.parse(contents)) 27 + : buildSchema(contents); 19 28 20 - return ref 21 - } 29 + return ref; 30 + };
+218 -142
src/index.ts
··· 1 - import ts from "typescript/lib/tsserverlibrary"; 2 - import { isNoSubstitutionTemplateLiteral, ScriptElementKind, isIdentifier, isTaggedTemplateExpression, isToken, isTemplateExpression, isImportTypeNode, ImportTypeNode } from "typescript"; 3 - import { getHoverInformation, getAutocompleteSuggestions, getDiagnostics, Diagnostic } from 'graphql-language-service' 4 - import { parse, Kind, FragmentDefinitionNode, OperationDefinitionNode } from 'graphql' 1 + import ts from 'typescript/lib/tsserverlibrary'; 2 + import { 3 + isNoSubstitutionTemplateLiteral, 4 + ScriptElementKind, 5 + isIdentifier, 6 + isTaggedTemplateExpression, 7 + isToken, 8 + isTemplateExpression, 9 + isImportTypeNode, 10 + ImportTypeNode, 11 + } from 'typescript'; 12 + import { 13 + getHoverInformation, 14 + getAutocompleteSuggestions, 15 + getDiagnostics, 16 + Diagnostic, 17 + } from 'graphql-language-service'; 18 + import { 19 + parse, 20 + Kind, 21 + FragmentDefinitionNode, 22 + OperationDefinitionNode, 23 + } from 'graphql'; 5 24 import fs from 'fs'; 6 25 7 - import { Cursor } from "./cursor"; 8 - import { loadSchema } from "./getSchema"; 9 - import { getToken } from "./token"; 10 - import { findAllTaggedTemplateNodes, findNode, getSource } from "./utils"; 11 - import { resolveTemplate } from "./resolve"; 12 - import { generateTypedDocumentNodes } from "./types/generate"; 26 + import { Cursor } from './cursor'; 27 + import { loadSchema } from './getSchema'; 28 + import { getToken } from './token'; 29 + import { findAllTaggedTemplateNodes, findNode, getSource } from './utils'; 30 + import { resolveTemplate } from './resolve'; 31 + import { generateTypedDocumentNodes } from './types/generate'; 13 32 14 33 function createBasicDecorator(info: ts.server.PluginCreateInfo) { 15 34 const proxy: ts.LanguageService = Object.create(null); 16 - for (let k of Object.keys(info.languageService) as Array<keyof ts.LanguageService>) { 35 + for (let k of Object.keys(info.languageService) as Array< 36 + keyof ts.LanguageService 37 + >) { 17 38 const x = info.languageService[k]!; 18 39 // @ts-expect-error - JS runtime trickery which is tricky to type tersely 19 40 proxy[k] = (...args: Array<{}>) => x.apply(info.languageService, args); ··· 23 44 } 24 45 25 46 function create(info: ts.server.PluginCreateInfo) { 26 - const logger = (msg: string) => info.project.projectService.logger.info(`[ts-graphql-plugin] ${msg}`); 47 + const logger = (msg: string) => 48 + info.project.projectService.logger.info(`[ts-graphql-plugin] ${msg}`); 27 49 logger('config: ' + JSON.stringify(info.config)); 28 50 if (!info.config.schema) { 29 51 throw new Error('Please provide a GraphQL Schema!'); 30 52 } 31 53 32 - info.project.projectService.logger.info( 33 - "Setting up the GraphQL Plugin" 34 - ); 54 + info.project.projectService.logger.info('Setting up the GraphQL Plugin'); 35 55 36 56 const tagTemplate = info.config.template || 'gql'; 37 57 const scalars = info.config.scalars || {}; ··· 43 63 const schema = loadSchema(info.project.getProjectName(), info.config.schema); 44 64 45 65 proxy.getSemanticDiagnostics = (filename: string): ts.Diagnostic[] => { 46 - const originalDiagnostics = info.languageService.getSemanticDiagnostics(filename) 47 - const source = getSource(info, filename) 48 - if (!source) return originalDiagnostics 66 + const originalDiagnostics = 67 + info.languageService.getSemanticDiagnostics(filename); 68 + const source = getSource(info, filename); 69 + if (!source) return originalDiagnostics; 49 70 50 - const nodes = findAllTaggedTemplateNodes(source) 71 + const nodes = findAllTaggedTemplateNodes(source); 51 72 52 73 const texts = nodes.map(node => { 53 74 if (isNoSubstitutionTemplateLiteral(node) || isTemplateExpression(node)) { 54 75 if (isTaggedTemplateExpression(node.parent)) { 55 - node = node.parent 76 + node = node.parent; 56 77 } else { 57 - return undefined 78 + return undefined; 58 79 } 59 80 } 60 81 82 + return resolveTemplate(node, filename, info); 83 + }); 61 84 62 - return resolveTemplate(node, filename, info) 63 - }) 64 - 65 - const diagnostics = nodes.map(x => { 66 - let node = x; 67 - if (isNoSubstitutionTemplateLiteral(node) || isTemplateExpression(node)) { 68 - if (isTaggedTemplateExpression(node.parent)) { 69 - node = node.parent 70 - } else { 71 - return undefined 85 + const diagnostics = nodes 86 + .map(x => { 87 + let node = x; 88 + if ( 89 + isNoSubstitutionTemplateLiteral(node) || 90 + isTemplateExpression(node) 91 + ) { 92 + if (isTaggedTemplateExpression(node.parent)) { 93 + node = node.parent; 94 + } else { 95 + return undefined; 96 + } 72 97 } 73 - } 74 98 75 - const text = resolveTemplate(node, filename, info) 76 - const lines = text.split('\n') 99 + const text = resolveTemplate(node, filename, info); 100 + const lines = text.split('\n'); 77 101 78 - let startingPosition = node.pos + (tagTemplate.length + 1) 79 - const graphQLDiagnostics = getDiagnostics(text, schema.current).map(x => { 80 - const { start, end } = x.range; 102 + let startingPosition = node.pos + (tagTemplate.length + 1); 103 + const graphQLDiagnostics = getDiagnostics(text, schema.current).map( 104 + x => { 105 + const { start, end } = x.range; 81 106 82 - // We add the start.line to account for newline characters which are 83 - // split out 84 - let startChar = startingPosition + start.line 85 - for (let i = 0; i <= start.line; i++) { 86 - if (i === start.line) startChar += start.character 87 - else startChar += lines[i].length 88 - } 107 + // We add the start.line to account for newline characters which are 108 + // split out 109 + let startChar = startingPosition + start.line; 110 + for (let i = 0; i <= start.line; i++) { 111 + if (i === start.line) startChar += start.character; 112 + else startChar += lines[i].length; 113 + } 89 114 90 - let endChar = startingPosition + end.line 91 - for (let i = 0; i <= end.line; i++) { 92 - if (i === end.line) endChar += end.character 93 - else endChar += lines[i].length 94 - } 115 + let endChar = startingPosition + end.line; 116 + for (let i = 0; i <= end.line; i++) { 117 + if (i === end.line) endChar += end.character; 118 + else endChar += lines[i].length; 119 + } 95 120 96 - // We add 1 to the start because the range is exclusive of start.character 97 - return { ...x, start: startChar + 1, length: endChar - startChar } 98 - }) 121 + // We add 1 to the start because the range is exclusive of start.character 122 + return { ...x, start: startChar + 1, length: endChar - startChar }; 123 + } 124 + ); 99 125 100 - const parsed = parse(text); 126 + const parsed = parse(text); 101 127 102 - if (parsed.definitions.some(x => x.kind === Kind.OPERATION_DEFINITION)) { 103 - const op = parsed.definitions.find(x => x.kind === Kind.OPERATION_DEFINITION) as OperationDefinitionNode 104 - if (!op.name) { 105 - graphQLDiagnostics.push({ 106 - message: 'Operation needs a name for types to be generated.', 107 - start: node.pos, 108 - length: x.getText().length, 109 - range: {} as any, 110 - severity: 2, 111 - } as any) 128 + if ( 129 + parsed.definitions.some(x => x.kind === Kind.OPERATION_DEFINITION) 130 + ) { 131 + const op = parsed.definitions.find( 132 + x => x.kind === Kind.OPERATION_DEFINITION 133 + ) as OperationDefinitionNode; 134 + if (!op.name) { 135 + graphQLDiagnostics.push({ 136 + message: 'Operation needs a name for types to be generated.', 137 + start: node.pos, 138 + length: x.getText().length, 139 + range: {} as any, 140 + severity: 2, 141 + } as any); 142 + } 112 143 } 113 - } 114 144 115 - return graphQLDiagnostics; 116 - }).flat().filter(Boolean) as Array<Diagnostic & { length: number; start: number }> 145 + return graphQLDiagnostics; 146 + }) 147 + .flat() 148 + .filter(Boolean) as Array<Diagnostic & { length: number; start: number }>; 117 149 118 150 const newDiagnostics = diagnostics.map(diag => { 119 151 const result: ts.Diagnostic = { 120 152 file: source, 121 153 length: diag.length, 122 154 start: diag.start, 123 - category: diag.severity === 2 ? ts.DiagnosticCategory.Warning : ts.DiagnosticCategory.Error, 155 + category: 156 + diag.severity === 2 157 + ? ts.DiagnosticCategory.Warning 158 + : ts.DiagnosticCategory.Error, 124 159 code: 51001, 125 160 messageText: diag.message.split('\n')[0], 126 - } 161 + }; 127 162 128 163 return result; 129 - }) 164 + }); 130 165 131 166 if (!newDiagnostics.length) { 132 167 try { 133 168 const parts = source.fileName.split('/'); 134 169 const name = parts[parts.length - 1]; 135 170 const nameParts = name.split('.'); 136 - nameParts[nameParts.length - 1] = 'generated.ts' 137 - parts[parts.length - 1] = nameParts.join('.') 171 + nameParts[nameParts.length - 1] = 'generated.ts'; 172 + parts[parts.length - 1] = nameParts.join('.'); 138 173 const contents = fs.readFileSync(filename, 'utf-8'); 139 174 const currentText = source.getFullText(); 140 - 175 + 141 176 if (contents !== currentText) { 142 - return [ 143 - ...newDiagnostics, 144 - ...originalDiagnostics 145 - ] 177 + return [...newDiagnostics, ...originalDiagnostics]; 146 178 } 147 179 148 - generateTypedDocumentNodes(schema.current, parts.join('/'), texts.join('\n'), scalars).then(() => { 180 + generateTypedDocumentNodes( 181 + schema.current, 182 + parts.join('/'), 183 + texts.join('\n'), 184 + scalars 185 + ).then(() => { 149 186 nodes.forEach((node, i) => { 150 187 const queryText = texts[i] || ''; 151 188 const parsed = parse(queryText); 152 - const isFragment = parsed.definitions.every(x => x.kind === Kind.FRAGMENT_DEFINITION); 189 + const isFragment = parsed.definitions.every( 190 + x => x.kind === Kind.FRAGMENT_DEFINITION 191 + ); 153 192 let name = ''; 154 193 155 194 if (isFragment) { 156 - const fragmentNode = parsed.definitions[0] as FragmentDefinitionNode; 195 + const fragmentNode = parsed 196 + .definitions[0] as FragmentDefinitionNode; 157 197 name = fragmentNode.name.value; 158 198 } else { 159 - const operationNode = parsed.definitions[0] as OperationDefinitionNode; 199 + const operationNode = parsed 200 + .definitions[0] as OperationDefinitionNode; 160 201 name = operationNode.name?.value || ''; 161 202 } 162 - 203 + 163 204 if (!name) return; 164 - 205 + 165 206 name = name.charAt(0).toUpperCase() + name.slice(1); 166 207 const parentChildren = node.parent.getChildren(); 167 208 168 - const exportName = isFragment ? `${name}FragmentDoc` : `${name}Document`; 169 - const imp = ` as typeof import('./${nameParts.join('.').replace('.ts', '')}').${exportName}`; 170 - 209 + const exportName = isFragment 210 + ? `${name}FragmentDoc` 211 + : `${name}Document`; 212 + const imp = ` as typeof import('./${nameParts 213 + .join('.') 214 + .replace('.ts', '')}').${exportName}`; 215 + 171 216 // This checks whether one of the children is an import-type 172 217 // which is a short-circuit if there is no as 173 - const typeImport = parentChildren.find(x => isImportTypeNode(x)) as ImportTypeNode 218 + const typeImport = parentChildren.find(x => 219 + isImportTypeNode(x) 220 + ) as ImportTypeNode; 174 221 if (typeImport && typeImport.getText().includes(exportName)) return; 175 - 222 + 176 223 const span = { length: 1, start: node.end }; 177 - const text = source.text.substring(0, span.start) + imp + source.text.substring(span.start + span.length, source.text.length); 178 - const scriptInfo = info.project.projectService.getScriptInfo(filename); 224 + const text = 225 + source.text.substring(0, span.start) + 226 + imp + 227 + source.text.substring( 228 + span.start + span.length, 229 + source.text.length 230 + ); 231 + const scriptInfo = 232 + info.project.projectService.getScriptInfo(filename); 179 233 const snapshot = scriptInfo!.getSnapshot(); 180 - 234 + 181 235 // TODO: potential optimisation is to write only one script-update 182 - source.update(text, { span, newLength: imp.length }) 236 + source.update(text, { span, newLength: imp.length }); 183 237 scriptInfo!.editContent(0, snapshot.getLength(), text); 184 238 info.languageServiceHost.writeFile!(source.fileName, text); 185 239 scriptInfo!.registerFileUpdate(); ··· 188 242 // that would be a win. If not we should check if we can figure it out through 189 243 // the script-info whether there are unsaved changes and not run this 190 244 // scriptInfo!.open(text); 191 - }) 245 + }); 192 246 }); 193 247 } catch (e) {} 194 248 } 195 249 196 - return [ 197 - ...newDiagnostics, 198 - ...originalDiagnostics 199 - ] 200 - } 250 + return [...newDiagnostics, ...originalDiagnostics]; 251 + }; 201 252 202 253 proxy.getCompletionsAtPosition = ( 203 254 filename: string, ··· 213 264 isMemberCompletion: false, 214 265 isNewIdentifierLocation: false, 215 266 entries: [], 216 - } 217 - 218 - const source = getSource(info, filename) 219 - if (!source) return originalCompletions 267 + }; 268 + 269 + const source = getSource(info, filename); 270 + if (!source) return originalCompletions; 220 271 221 - let node = findNode(source, cursorPosition) 272 + let node = findNode(source, cursorPosition); 222 273 if (!node) return originalCompletions; 223 274 224 - while (isNoSubstitutionTemplateLiteral(node) || isToken(node) || isTemplateExpression(node)) { 225 - node = node.parent 275 + while ( 276 + isNoSubstitutionTemplateLiteral(node) || 277 + isToken(node) || 278 + isTemplateExpression(node) 279 + ) { 280 + node = node.parent; 226 281 } 227 282 228 283 if (isTaggedTemplateExpression(node)) { 229 284 const { template, tag } = node; 230 - if (!isIdentifier(tag) || tag.text !== tagTemplate) return originalCompletions; 285 + if (!isIdentifier(tag) || tag.text !== tagTemplate) 286 + return originalCompletions; 231 287 232 - const text = resolveTemplate(node, filename, info) 233 - const foundToken = getToken(template, cursorPosition) 288 + const text = resolveTemplate(node, filename, info); 289 + const foundToken = getToken(template, cursorPosition); 234 290 235 - if (!foundToken || !schema.current) return originalCompletions 291 + if (!foundToken || !schema.current) return originalCompletions; 236 292 237 - const suggestions = getAutocompleteSuggestions(schema.current, text, new Cursor(foundToken.line, foundToken.start)) 293 + const suggestions = getAutocompleteSuggestions( 294 + schema.current, 295 + text, 296 + new Cursor(foundToken.line, foundToken.start) 297 + ); 238 298 239 - let fragments: Array<FragmentDefinitionNode> = [] 299 + let fragments: Array<FragmentDefinitionNode> = []; 240 300 try { 241 301 const parsed = parse(text); 242 - fragments = parsed.definitions.filter(x => x.kind === Kind.FRAGMENT_DEFINITION) as Array<FragmentDefinitionNode> 302 + fragments = parsed.definitions.filter( 303 + x => x.kind === Kind.FRAGMENT_DEFINITION 304 + ) as Array<FragmentDefinitionNode>; 243 305 } catch (e) {} 244 306 245 307 const result: ts.WithMetadata<ts.CompletionInfo> = { ··· 247 309 isMemberCompletion: false, 248 310 isNewIdentifierLocation: false, 249 311 // TODO: check whether we can add descriptions to the entries 250 - entries: [...suggestions.map(suggestion => ({ 251 - kind: ScriptElementKind.variableElement, 252 - name: suggestion.label, 253 - kindModifiers: 'declare', 254 - sortText: suggestion.sortText || '0', 255 - })), ...fragments.map(fragment => ({ 256 - kind: ScriptElementKind.variableElement, 257 - name: fragment.name.value, 258 - insertText: '...' + fragment.name.value, 259 - kindModifiers: 'declare', 260 - sortText: '0', 261 - })), ...originalCompletions.entries], 262 - } 263 - return result 312 + entries: [ 313 + ...suggestions.map(suggestion => ({ 314 + kind: ScriptElementKind.variableElement, 315 + name: suggestion.label, 316 + kindModifiers: 'declare', 317 + sortText: suggestion.sortText || '0', 318 + })), 319 + ...fragments.map(fragment => ({ 320 + kind: ScriptElementKind.variableElement, 321 + name: fragment.name.value, 322 + insertText: '...' + fragment.name.value, 323 + kindModifiers: 'declare', 324 + sortText: '0', 325 + })), 326 + ...originalCompletions.entries, 327 + ], 328 + }; 329 + return result; 264 330 } else { 265 - return originalCompletions 331 + return originalCompletions; 266 332 } 267 - } 333 + }; 268 334 269 335 proxy.getQuickInfoAtPosition = (filename: string, cursorPosition: number) => { 270 336 const originalInfo = info.languageService.getQuickInfoAtPosition( 271 337 filename, 272 338 cursorPosition 273 - ) 274 - 275 - const source = getSource(info, filename) 276 - if (!source) return originalInfo 339 + ); 340 + 341 + const source = getSource(info, filename); 342 + if (!source) return originalInfo; 277 343 278 - let node = findNode(source, cursorPosition) 344 + let node = findNode(source, cursorPosition); 279 345 if (!node) return originalInfo; 280 346 281 - while (isNoSubstitutionTemplateLiteral(node) || isToken(node) || isTemplateExpression(node)) { 282 - node = node.parent 347 + while ( 348 + isNoSubstitutionTemplateLiteral(node) || 349 + isToken(node) || 350 + isTemplateExpression(node) 351 + ) { 352 + node = node.parent; 283 353 } 284 354 285 355 if (isTaggedTemplateExpression(node)) { 286 356 const { template, tag } = node; 287 357 if (!isIdentifier(tag) || tag.text !== tagTemplate) return originalInfo; 288 358 289 - const text = resolveTemplate(node, filename, info) 290 - const foundToken = getToken(template, cursorPosition) 359 + const text = resolveTemplate(node, filename, info); 360 + const foundToken = getToken(template, cursorPosition); 291 361 292 - if (!foundToken || !schema.current) return originalInfo 362 + if (!foundToken || !schema.current) return originalInfo; 293 363 294 - const hoverInfo = getHoverInformation(schema.current, text, new Cursor(foundToken.line, foundToken.start)) 364 + const hoverInfo = getHoverInformation( 365 + schema.current, 366 + text, 367 + new Cursor(foundToken.line, foundToken.start) 368 + ); 295 369 const result: ts.QuickInfo = { 296 370 kind: ts.ScriptElementKind.string, 297 371 textSpan: { 298 372 start: cursorPosition, 299 - length: 1 373 + length: 1, 300 374 }, 301 375 kindModifiers: '', 302 - displayParts: Array.isArray(hoverInfo) ? hoverInfo.map(item => ({ kind: '', text: item as string })) : [{ kind: '', text: hoverInfo as string }] 376 + displayParts: Array.isArray(hoverInfo) 377 + ? hoverInfo.map(item => ({ kind: '', text: item as string })) 378 + : [{ kind: '', text: hoverInfo as string }], 303 379 }; 304 380 305 381 return result; 306 382 } else { 307 - return originalInfo 383 + return originalInfo; 308 384 } 309 - } 385 + }; 310 386 311 387 logger('proxy: ' + JSON.stringify(proxy)); 312 388
+60 -24
src/resolve.ts
··· 1 - import { isAsExpression, isIdentifier, isNoSubstitutionTemplateLiteral, isTaggedTemplateExpression, NoSubstitutionTemplateLiteral, TaggedTemplateExpression, TemplateExpression, TemplateLiteral } from "typescript"; 2 - import ts from "typescript/lib/tsserverlibrary"; 3 - import { findNode, getSource } from "./utils"; 1 + import { 2 + isAsExpression, 3 + isIdentifier, 4 + isNoSubstitutionTemplateLiteral, 5 + isTaggedTemplateExpression, 6 + NoSubstitutionTemplateLiteral, 7 + TaggedTemplateExpression, 8 + TemplateExpression, 9 + TemplateLiteral, 10 + } from 'typescript'; 11 + import ts from 'typescript/lib/tsserverlibrary'; 12 + import { findNode, getSource } from './utils'; 4 13 5 - export function resolveTemplate(node: TaggedTemplateExpression, filename: string, info: ts.server.PluginCreateInfo): string { 6 - let templateText = node.template.getText().slice(1, -1) 7 - if (isNoSubstitutionTemplateLiteral(node.template) || node.template.templateSpans.length === 0) { 8 - return templateText 14 + export function resolveTemplate( 15 + node: TaggedTemplateExpression, 16 + filename: string, 17 + info: ts.server.PluginCreateInfo 18 + ): string { 19 + let templateText = node.template.getText().slice(1, -1); 20 + if ( 21 + isNoSubstitutionTemplateLiteral(node.template) || 22 + node.template.templateSpans.length === 0 23 + ) { 24 + return templateText; 9 25 } 10 26 11 27 node.template.templateSpans.forEach(span => { 12 28 if (isIdentifier(span.expression)) { 13 - const definitions = info.languageService.getDefinitionAtPosition(filename, span.expression.getStart()); 14 - if (!definitions) return 15 - const def = definitions[0] 16 - const src = getSource(info, def.fileName) 17 - if (!src) return 18 - const node = findNode(src, def.textSpan.start) 19 - if (!node || !node.parent) return 29 + const definitions = info.languageService.getDefinitionAtPosition( 30 + filename, 31 + span.expression.getStart() 32 + ); 33 + if (!definitions) return; 34 + const def = definitions[0]; 35 + const src = getSource(info, def.fileName); 36 + if (!src) return; 37 + const node = findNode(src, def.textSpan.start); 38 + if (!node || !node.parent) return; 20 39 21 - const parent = node.parent 40 + const parent = node.parent; 22 41 if (ts.isVariableDeclaration(parent)) { 23 - if (parent.initializer && isTaggedTemplateExpression(parent.initializer)) { 24 - const text = resolveTemplate(parent.initializer, def.fileName, info) 25 - templateText = templateText.replace('${' + span.expression.escapedText + '}', text) 26 - } else if (parent.initializer && isAsExpression(parent.initializer) && isTaggedTemplateExpression(parent.initializer.expression)) { 27 - const text = resolveTemplate(parent.initializer.expression, def.fileName, info) 28 - templateText = templateText.replace('${' + span.expression.escapedText + '}', text) 42 + if ( 43 + parent.initializer && 44 + isTaggedTemplateExpression(parent.initializer) 45 + ) { 46 + const text = resolveTemplate(parent.initializer, def.fileName, info); 47 + templateText = templateText.replace( 48 + '${' + span.expression.escapedText + '}', 49 + text 50 + ); 51 + } else if ( 52 + parent.initializer && 53 + isAsExpression(parent.initializer) && 54 + isTaggedTemplateExpression(parent.initializer.expression) 55 + ) { 56 + const text = resolveTemplate( 57 + parent.initializer.expression, 58 + def.fileName, 59 + info 60 + ); 61 + templateText = templateText.replace( 62 + '${' + span.expression.escapedText + '}', 63 + text 64 + ); 29 65 } 30 66 } 31 67 } 32 - }) 68 + }); 33 69 34 - return templateText 35 - } 70 + return templateText; 71 + }
+21 -14
src/token.ts
··· 1 - import ts from "typescript/lib/tsserverlibrary"; 2 - import { onlineParser, State, CharacterStream } from "graphql-language-service"; 1 + import ts from 'typescript/lib/tsserverlibrary'; 2 + import { onlineParser, State, CharacterStream } from 'graphql-language-service'; 3 3 4 4 export interface Token { 5 5 start: number; 6 6 end: number; 7 7 string: string; 8 - tokenKind: string 9 - line: number 10 - state: State 8 + tokenKind: string; 9 + line: number; 10 + state: State; 11 11 } 12 12 13 - export const getToken = (template: ts.TemplateLiteral, cursorPosition: number): Token | undefined => { 13 + export const getToken = ( 14 + template: ts.TemplateLiteral, 15 + cursorPosition: number 16 + ): Token | undefined => { 14 17 const text = template.getText().slice(1, -1); 15 - const input = text.split('\n') 18 + const input = text.split('\n'); 16 19 const parser = onlineParser(); 17 20 const state = parser.startState(); 18 21 let cPos = template.pos + 1; ··· 22 25 const lPos = cPos; 23 26 const stream = new CharacterStream(input[i]); 24 27 while (!stream.eol()) { 25 - const token = parser.token(stream, state) 28 + const token = parser.token(stream, state); 26 29 const string = stream.current(); 27 30 28 - if (string && lPos + stream.getStartOfToken() <= cursorPosition && lPos + stream.getCurrentPosition() >= cursorPosition) { 31 + if ( 32 + string && 33 + lPos + stream.getStartOfToken() <= cursorPosition && 34 + lPos + stream.getCurrentPosition() >= cursorPosition 35 + ) { 29 36 foundToken = { 30 37 line: i, 31 38 start: stream.getStartOfToken() + 1, 32 39 end: stream.getCurrentPosition(), 33 40 string, 34 41 state, 35 - tokenKind: token 36 - } 42 + tokenKind: token, 43 + }; 37 44 break; 38 45 } 39 46 } 40 47 41 - cPos += input[i].length + 1 48 + cPos += input[i].length + 1; 42 49 } 43 50 44 - return foundToken 45 - } 51 + return foundToken; 52 + };
+52 -47
src/types/generate.ts
··· 1 - import fs from 'fs' 2 - import path from 'path' 3 - import { printSchema, parse, GraphQLSchema } from 'graphql' 4 - import { codegen } from '@graphql-codegen/core' 5 - import * as typescriptPlugin from '@graphql-codegen/typescript' 6 - import * as typescriptOperationsPlugin from '@graphql-codegen/typescript-operations' 7 - import * as typedDocumentNodePlugin from '@graphql-codegen/typed-document-node' 1 + import fs from 'fs'; 2 + import path from 'path'; 3 + import { printSchema, parse, GraphQLSchema } from 'graphql'; 4 + import { codegen } from '@graphql-codegen/core'; 5 + import * as typescriptPlugin from '@graphql-codegen/typescript'; 6 + import * as typescriptOperationsPlugin from '@graphql-codegen/typescript-operations'; 7 + import * as typedDocumentNodePlugin from '@graphql-codegen/typed-document-node'; 8 8 9 - export const generateTypedDocumentNodes = async (schema: GraphQLSchema | null, outputFile: string, doc: string, scalars: Record<string, unknown>) => { 10 - if (!schema) return; 9 + export const generateTypedDocumentNodes = async ( 10 + schema: GraphQLSchema | null, 11 + outputFile: string, 12 + doc: string, 13 + scalars: Record<string, unknown> 14 + ) => { 15 + if (!schema) return; 11 16 12 - const config = { 13 - documents: [ 14 - { 15 - location: 'operation.graphql', 16 - document: parse(doc), 17 - }, 18 - ], 19 - config: { 20 - scalars, 21 - // nonOptionalTypename: true, 22 - // avoidOptionals, worth looking into 23 - enumsAsTypes: true, 24 - dedupeOperationSuffix: true, 25 - dedupeFragments: true, 26 - }, 27 - // used by a plugin internally, although the 'typescript' plugin currently 28 - // returns the string output, rather than writing to a file 29 - filename: outputFile, 30 - schema: parse(printSchema(schema)), 31 - plugins: [ 32 - // TODO: there's optimisations to be had here where we move the typescript and typescript-operations 33 - // to a global __generated__ folder and import from it. 34 - { 'typescript': {} }, 35 - { 'typescript-operations': {} }, 36 - { 'typed-document-node': {} }, 37 - ], 38 - pluginMap: { 39 - typescript: typescriptPlugin, 40 - 'typescript-operations': typescriptOperationsPlugin, 41 - 'typed-document-node': typedDocumentNodePlugin 42 - } 43 - } 17 + const config = { 18 + documents: [ 19 + { 20 + location: 'operation.graphql', 21 + document: parse(doc), 22 + }, 23 + ], 24 + config: { 25 + scalars, 26 + // nonOptionalTypename: true, 27 + // avoidOptionals, worth looking into 28 + enumsAsTypes: true, 29 + dedupeOperationSuffix: true, 30 + dedupeFragments: true, 31 + }, 32 + // used by a plugin internally, although the 'typescript' plugin currently 33 + // returns the string output, rather than writing to a file 34 + filename: outputFile, 35 + schema: parse(printSchema(schema)), 36 + plugins: [ 37 + // TODO: there's optimisations to be had here where we move the typescript and typescript-operations 38 + // to a global __generated__ folder and import from it. 39 + { typescript: {} }, 40 + { 'typescript-operations': {} }, 41 + { 'typed-document-node': {} }, 42 + ], 43 + pluginMap: { 44 + typescript: typescriptPlugin, 45 + 'typescript-operations': typescriptOperationsPlugin, 46 + 'typed-document-node': typedDocumentNodePlugin, 47 + }, 48 + }; 44 49 45 - // @ts-ignore 46 - const output = await codegen(config) 47 - fs.writeFile(path.join(outputFile), output, 'utf8', (err) => { 48 - console.error(err) 49 - }) 50 - } 50 + // @ts-ignore 51 + const output = await codegen(config); 52 + fs.writeFile(path.join(outputFile), output, 'utf8', err => { 53 + console.error(err); 54 + }); 55 + };
+23 -10
src/utils.ts
··· 1 - import ts from "typescript/lib/tsserverlibrary"; 2 - import { isNoSubstitutionTemplateLiteral, isTaggedTemplateExpression } from "typescript"; 1 + import ts from 'typescript/lib/tsserverlibrary'; 2 + import { 3 + isNoSubstitutionTemplateLiteral, 4 + isTaggedTemplateExpression, 5 + } from 'typescript'; 3 6 4 - export function findNode(sourceFile: ts.SourceFile, position: number): ts.Node | undefined { 7 + export function findNode( 8 + sourceFile: ts.SourceFile, 9 + position: number 10 + ): ts.Node | undefined { 5 11 function find(node: ts.Node): ts.Node | undefined { 6 12 if (position >= node.getStart() && position < node.getEnd()) { 7 13 return ts.forEachChild(node, find) || node; ··· 10 16 return find(sourceFile); 11 17 } 12 18 13 - export function findAllTaggedTemplateNodes(sourceFile: ts.SourceFile): Array<ts.TaggedTemplateExpression | ts.NoSubstitutionTemplateLiteral> { 14 - const result: Array<ts.TaggedTemplateExpression | ts.NoSubstitutionTemplateLiteral> = []; 19 + export function findAllTaggedTemplateNodes( 20 + sourceFile: ts.SourceFile 21 + ): Array<ts.TaggedTemplateExpression | ts.NoSubstitutionTemplateLiteral> { 22 + const result: Array< 23 + ts.TaggedTemplateExpression | ts.NoSubstitutionTemplateLiteral 24 + > = []; 15 25 function find(node: ts.Node) { 16 - if (isTaggedTemplateExpression(node) || isNoSubstitutionTemplateLiteral(node)) { 26 + if ( 27 + isTaggedTemplateExpression(node) || 28 + isNoSubstitutionTemplateLiteral(node) 29 + ) { 17 30 result.push(node); 18 31 return; 19 32 } else { ··· 26 39 27 40 export function getSource(info: ts.server.PluginCreateInfo, filename: string) { 28 41 const program = info.languageService.getProgram(); 29 - if (!program) return undefined 42 + if (!program) return undefined; 30 43 31 - const source = program.getSourceFile(filename) 32 - if (!source) return undefined 44 + const source = program.getSourceFile(filename); 45 + if (!source) return undefined; 33 46 34 - return source 47 + return source; 35 48 }