Mirror: The spec-compliant minimum of client-side GraphQL.
0
fork

Configure Feed

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

Fix up divergences from graphql.js

+918 -33
+2 -2
package.json
··· 1 1 { 2 2 "name": "@0no-co/graphql.web", 3 3 "description": "A spec-compliant client-side GraphQL implementation", 4 - "version": "0.1.1", 4 + "version": "0.1.2", 5 5 "author": "0no.co <hi@0no.co>", 6 6 "source": "./src/index.ts", 7 7 "main": "./dist/graphql.web", ··· 29 29 "client-side graphql" 30 30 ], 31 31 "scripts": { 32 - "test": "vitest run", 32 + "test": "vitest", 33 33 "check": "tsc", 34 34 "lint": "eslint --ext=js,ts .", 35 35 "build": "rollup -c scripts/rollup.config.mjs",
+15 -22
src/__tests__/__snapshots__/parser.test.ts.snap
··· 1 1 // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 2 3 - exports[`parse > parses the kitchen sink query 1`] = ` 3 + exports[`print > prints the kitchen sink document like graphql.js does 1`] = ` 4 4 { 5 5 "definitions": [ 6 6 { ··· 39 39 "kind": "ListValue", 40 40 "values": [ 41 41 { 42 - "kind": "FloatValue", 42 + "kind": "IntValue", 43 43 "value": "123", 44 44 }, 45 45 { 46 - "kind": "FloatValue", 46 + "kind": "IntValue", 47 47 "value": "456", 48 48 }, 49 49 ], ··· 71 71 "selectionSet": undefined, 72 72 }, 73 73 { 74 - "directives": [], 75 - "kind": "FragmentSpread", 76 - "name": { 77 - "kind": "Name", 78 - "value": "on", 79 - }, 80 - }, 81 - { 82 - "alias": undefined, 83 - "arguments": [], 84 74 "directives": [ 85 75 { 86 76 "arguments": [], ··· 91 81 }, 92 82 }, 93 83 ], 94 - "kind": "Field", 95 - "name": { 96 - "kind": "Name", 97 - "value": "User", 98 - }, 84 + "kind": "InlineFragment", 99 85 "selectionSet": { 100 86 "kind": "SelectionSet", 101 87 "selections": [ ··· 135 121 "value": "first", 136 122 }, 137 123 "value": { 138 - "kind": "FloatValue", 124 + "kind": "IntValue", 139 125 "value": "10", 140 126 }, 141 127 }, ··· 223 209 }, 224 210 ], 225 211 }, 212 + "typeCondition": { 213 + "kind": "NamedType", 214 + "name": { 215 + "kind": "Name", 216 + "value": "User", 217 + }, 218 + }, 226 219 }, 227 220 { 228 221 "directives": [ ··· 369 362 "value": "story", 370 363 }, 371 364 "value": { 372 - "kind": "FloatValue", 365 + "kind": "IntValue", 373 366 "value": "123", 374 367 }, 375 368 }, ··· 618 611 "value": "bar", 619 612 }, 620 613 "value": { 621 - "kind": "FloatValue", 614 + "kind": "IntValue", 622 615 "value": "12", 623 616 }, 624 617 }, ··· 651 644 "value": { 652 645 "block": true, 653 646 "kind": "StringValue", 654 - "value": "block string uses \\\\\\"\\"\\"", 647 + "value": "block string uses \\"\\"\\"", 655 648 }, 656 649 }, 657 650 ],
+64
src/__tests__/__snapshots__/printer.test.ts.snap
··· 1 + // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 + 3 + exports[`print > prints the kitchen sink document like graphql.js does 1`] = ` 4 + "query queryName($foo: ComplexType, $site: Site = MOBILE) @onQuery { 5 + whoever123is: node(id: [123, 456]) { 6 + id 7 + ... on User @onInlineFragment { 8 + field2 { 9 + id 10 + alias: field1(first: 10, after: $foo) @include(if: $foo) { 11 + id 12 + ...frag @onFragmentSpread 13 + } 14 + } 15 + } 16 + ... @skip(unless: $foo) { 17 + id 18 + } 19 + ... { 20 + id 21 + } 22 + } 23 + } 24 + 25 + mutation likeStory @onMutation { 26 + like(story: 123) @onField { 27 + story { 28 + id @onField 29 + } 30 + } 31 + } 32 + 33 + subscription StoryLikeSubscription($input: StoryLikeSubscribeInput) @onSubscription { 34 + storyLikeSubscribe(input: $input) { 35 + story { 36 + likers { 37 + count 38 + } 39 + likeSentence { 40 + text 41 + } 42 + } 43 + } 44 + } 45 + 46 + fragment frag on Friend @onFragmentDefinition { 47 + foo( 48 + size: $site 49 + bar: 12 50 + obj: {key: \\"value\\", block: \\"\\"\\" 51 + block string uses \\\\\\"\\"\\" 52 + \\"\\"\\"} 53 + ) 54 + } 55 + 56 + query teeny { 57 + unnamed(truthy: true, falsey: false, nullish: null) 58 + query 59 + } 60 + 61 + query tiny { 62 + __typename 63 + }" 64 + `;
+69
src/__tests__/kitchen_sink.graphql
··· 1 + # Copyright (c) 2015-present, Facebook, Inc. 2 + # 3 + # This source code is licensed under the MIT license found in the 4 + # LICENSE file in the root directory of this source tree. 5 + 6 + query queryName($foo: ComplexType, $site: Site = MOBILE) @onQuery { 7 + whoever123is: node(id: [123, 456]) { 8 + id 9 + ... on User @onInlineFragment { 10 + field2 { 11 + id 12 + alias: field1(first: 10, after: $foo) @include(if: $foo) { 13 + id 14 + ...frag @onFragmentSpread 15 + } 16 + } 17 + } 18 + ... @skip(unless: $foo) { 19 + id 20 + } 21 + ... { 22 + id 23 + } 24 + } 25 + } 26 + 27 + mutation likeStory @onMutation { 28 + like(story: 123) @onField { 29 + story { 30 + id @onField 31 + } 32 + } 33 + } 34 + 35 + subscription StoryLikeSubscription($input: StoryLikeSubscribeInput) 36 + @onSubscription { 37 + storyLikeSubscribe(input: $input) { 38 + story { 39 + likers { 40 + count 41 + } 42 + likeSentence { 43 + text 44 + } 45 + } 46 + } 47 + } 48 + 49 + fragment frag on Friend @onFragmentDefinition { 50 + foo( 51 + size: $site 52 + bar: 12 53 + obj: { 54 + key: "value" 55 + block: """ 56 + block string uses \""" 57 + """ 58 + } 59 + ) 60 + } 61 + 62 + query teeny { 63 + unnamed(truthy: true, falsey: false, nullish: null) 64 + query 65 + } 66 + 67 + query tiny { 68 + __typename 69 + }
+733
src/__tests__/kitchen_sink.json
··· 1 + { 2 + "kind": "Document", 3 + "definitions": [ 4 + { 5 + "kind": "OperationDefinition", 6 + "operation": "query", 7 + "name": { 8 + "kind": "Name", 9 + "value": "queryName" 10 + }, 11 + "variableDefinitions": [ 12 + { 13 + "kind": "VariableDefinition", 14 + "variable": { 15 + "kind": "Variable", 16 + "name": { 17 + "kind": "Name", 18 + "value": "foo" 19 + } 20 + }, 21 + "type": { 22 + "kind": "NamedType", 23 + "name": { 24 + "kind": "Name", 25 + "value": "ComplexType" 26 + } 27 + }, 28 + "directives": [] 29 + }, 30 + { 31 + "kind": "VariableDefinition", 32 + "variable": { 33 + "kind": "Variable", 34 + "name": { 35 + "kind": "Name", 36 + "value": "site" 37 + } 38 + }, 39 + "type": { 40 + "kind": "NamedType", 41 + "name": { 42 + "kind": "Name", 43 + "value": "Site" 44 + } 45 + }, 46 + "defaultValue": { 47 + "kind": "EnumValue", 48 + "value": "MOBILE" 49 + }, 50 + "directives": [] 51 + } 52 + ], 53 + "directives": [ 54 + { 55 + "kind": "Directive", 56 + "name": { 57 + "kind": "Name", 58 + "value": "onQuery" 59 + }, 60 + "arguments": [] 61 + } 62 + ], 63 + "selectionSet": { 64 + "kind": "SelectionSet", 65 + "selections": [ 66 + { 67 + "kind": "Field", 68 + "alias": { 69 + "kind": "Name", 70 + "value": "whoever123is" 71 + }, 72 + "name": { 73 + "kind": "Name", 74 + "value": "node" 75 + }, 76 + "arguments": [ 77 + { 78 + "kind": "Argument", 79 + "name": { 80 + "kind": "Name", 81 + "value": "id" 82 + }, 83 + "value": { 84 + "kind": "ListValue", 85 + "values": [ 86 + { 87 + "kind": "IntValue", 88 + "value": "123" 89 + }, 90 + { 91 + "kind": "IntValue", 92 + "value": "456" 93 + } 94 + ] 95 + } 96 + } 97 + ], 98 + "directives": [], 99 + "selectionSet": { 100 + "kind": "SelectionSet", 101 + "selections": [ 102 + { 103 + "kind": "Field", 104 + "name": { 105 + "kind": "Name", 106 + "value": "id" 107 + }, 108 + "arguments": [], 109 + "directives": [] 110 + }, 111 + { 112 + "kind": "InlineFragment", 113 + "typeCondition": { 114 + "kind": "NamedType", 115 + "name": { 116 + "kind": "Name", 117 + "value": "User" 118 + } 119 + }, 120 + "directives": [ 121 + { 122 + "kind": "Directive", 123 + "name": { 124 + "kind": "Name", 125 + "value": "onInlineFragment" 126 + }, 127 + "arguments": [] 128 + } 129 + ], 130 + "selectionSet": { 131 + "kind": "SelectionSet", 132 + "selections": [ 133 + { 134 + "kind": "Field", 135 + "name": { 136 + "kind": "Name", 137 + "value": "field2" 138 + }, 139 + "arguments": [], 140 + "directives": [], 141 + "selectionSet": { 142 + "kind": "SelectionSet", 143 + "selections": [ 144 + { 145 + "kind": "Field", 146 + "name": { 147 + "kind": "Name", 148 + "value": "id" 149 + }, 150 + "arguments": [], 151 + "directives": [] 152 + }, 153 + { 154 + "kind": "Field", 155 + "alias": { 156 + "kind": "Name", 157 + "value": "alias" 158 + }, 159 + "name": { 160 + "kind": "Name", 161 + "value": "field1" 162 + }, 163 + "arguments": [ 164 + { 165 + "kind": "Argument", 166 + "name": { 167 + "kind": "Name", 168 + "value": "first" 169 + }, 170 + "value": { 171 + "kind": "IntValue", 172 + "value": "10" 173 + } 174 + }, 175 + { 176 + "kind": "Argument", 177 + "name": { 178 + "kind": "Name", 179 + "value": "after" 180 + }, 181 + "value": { 182 + "kind": "Variable", 183 + "name": { 184 + "kind": "Name", 185 + "value": "foo" 186 + } 187 + } 188 + } 189 + ], 190 + "directives": [ 191 + { 192 + "kind": "Directive", 193 + "name": { 194 + "kind": "Name", 195 + "value": "include" 196 + }, 197 + "arguments": [ 198 + { 199 + "kind": "Argument", 200 + "name": { 201 + "kind": "Name", 202 + "value": "if" 203 + }, 204 + "value": { 205 + "kind": "Variable", 206 + "name": { 207 + "kind": "Name", 208 + "value": "foo" 209 + } 210 + } 211 + } 212 + ] 213 + } 214 + ], 215 + "selectionSet": { 216 + "kind": "SelectionSet", 217 + "selections": [ 218 + { 219 + "kind": "Field", 220 + "name": { 221 + "kind": "Name", 222 + "value": "id" 223 + }, 224 + "arguments": [], 225 + "directives": [] 226 + }, 227 + { 228 + "kind": "FragmentSpread", 229 + "name": { 230 + "kind": "Name", 231 + "value": "frag" 232 + }, 233 + "directives": [ 234 + { 235 + "kind": "Directive", 236 + "name": { 237 + "kind": "Name", 238 + "value": "onFragmentSpread" 239 + }, 240 + "arguments": [] 241 + } 242 + ] 243 + } 244 + ] 245 + } 246 + } 247 + ] 248 + } 249 + } 250 + ] 251 + } 252 + }, 253 + { 254 + "kind": "InlineFragment", 255 + "directives": [ 256 + { 257 + "kind": "Directive", 258 + "name": { 259 + "kind": "Name", 260 + "value": "skip" 261 + }, 262 + "arguments": [ 263 + { 264 + "kind": "Argument", 265 + "name": { 266 + "kind": "Name", 267 + "value": "unless" 268 + }, 269 + "value": { 270 + "kind": "Variable", 271 + "name": { 272 + "kind": "Name", 273 + "value": "foo" 274 + } 275 + } 276 + } 277 + ] 278 + } 279 + ], 280 + "selectionSet": { 281 + "kind": "SelectionSet", 282 + "selections": [ 283 + { 284 + "kind": "Field", 285 + "name": { 286 + "kind": "Name", 287 + "value": "id" 288 + }, 289 + "arguments": [], 290 + "directives": [] 291 + } 292 + ] 293 + } 294 + }, 295 + { 296 + "kind": "InlineFragment", 297 + "directives": [], 298 + "selectionSet": { 299 + "kind": "SelectionSet", 300 + "selections": [ 301 + { 302 + "kind": "Field", 303 + "name": { 304 + "kind": "Name", 305 + "value": "id" 306 + }, 307 + "arguments": [], 308 + "directives": [] 309 + } 310 + ] 311 + } 312 + } 313 + ] 314 + } 315 + } 316 + ] 317 + } 318 + }, 319 + { 320 + "kind": "OperationDefinition", 321 + "operation": "mutation", 322 + "name": { 323 + "kind": "Name", 324 + "value": "likeStory" 325 + }, 326 + "variableDefinitions": [], 327 + "directives": [ 328 + { 329 + "kind": "Directive", 330 + "name": { 331 + "kind": "Name", 332 + "value": "onMutation" 333 + }, 334 + "arguments": [] 335 + } 336 + ], 337 + "selectionSet": { 338 + "kind": "SelectionSet", 339 + "selections": [ 340 + { 341 + "kind": "Field", 342 + "name": { 343 + "kind": "Name", 344 + "value": "like" 345 + }, 346 + "arguments": [ 347 + { 348 + "kind": "Argument", 349 + "name": { 350 + "kind": "Name", 351 + "value": "story" 352 + }, 353 + "value": { 354 + "kind": "IntValue", 355 + "value": "123" 356 + } 357 + } 358 + ], 359 + "directives": [ 360 + { 361 + "kind": "Directive", 362 + "name": { 363 + "kind": "Name", 364 + "value": "onField" 365 + }, 366 + "arguments": [] 367 + } 368 + ], 369 + "selectionSet": { 370 + "kind": "SelectionSet", 371 + "selections": [ 372 + { 373 + "kind": "Field", 374 + "name": { 375 + "kind": "Name", 376 + "value": "story" 377 + }, 378 + "arguments": [], 379 + "directives": [], 380 + "selectionSet": { 381 + "kind": "SelectionSet", 382 + "selections": [ 383 + { 384 + "kind": "Field", 385 + "name": { 386 + "kind": "Name", 387 + "value": "id" 388 + }, 389 + "arguments": [], 390 + "directives": [ 391 + { 392 + "kind": "Directive", 393 + "name": { 394 + "kind": "Name", 395 + "value": "onField" 396 + }, 397 + "arguments": [] 398 + } 399 + ] 400 + } 401 + ] 402 + } 403 + } 404 + ] 405 + } 406 + } 407 + ] 408 + } 409 + }, 410 + { 411 + "kind": "OperationDefinition", 412 + "operation": "subscription", 413 + "name": { 414 + "kind": "Name", 415 + "value": "StoryLikeSubscription" 416 + }, 417 + "variableDefinitions": [ 418 + { 419 + "kind": "VariableDefinition", 420 + "variable": { 421 + "kind": "Variable", 422 + "name": { 423 + "kind": "Name", 424 + "value": "input" 425 + } 426 + }, 427 + "type": { 428 + "kind": "NamedType", 429 + "name": { 430 + "kind": "Name", 431 + "value": "StoryLikeSubscribeInput" 432 + } 433 + }, 434 + "directives": [] 435 + } 436 + ], 437 + "directives": [ 438 + { 439 + "kind": "Directive", 440 + "name": { 441 + "kind": "Name", 442 + "value": "onSubscription" 443 + }, 444 + "arguments": [] 445 + } 446 + ], 447 + "selectionSet": { 448 + "kind": "SelectionSet", 449 + "selections": [ 450 + { 451 + "kind": "Field", 452 + "name": { 453 + "kind": "Name", 454 + "value": "storyLikeSubscribe" 455 + }, 456 + "arguments": [ 457 + { 458 + "kind": "Argument", 459 + "name": { 460 + "kind": "Name", 461 + "value": "input" 462 + }, 463 + "value": { 464 + "kind": "Variable", 465 + "name": { 466 + "kind": "Name", 467 + "value": "input" 468 + } 469 + } 470 + } 471 + ], 472 + "directives": [], 473 + "selectionSet": { 474 + "kind": "SelectionSet", 475 + "selections": [ 476 + { 477 + "kind": "Field", 478 + "name": { 479 + "kind": "Name", 480 + "value": "story" 481 + }, 482 + "arguments": [], 483 + "directives": [], 484 + "selectionSet": { 485 + "kind": "SelectionSet", 486 + "selections": [ 487 + { 488 + "kind": "Field", 489 + "name": { 490 + "kind": "Name", 491 + "value": "likers" 492 + }, 493 + "arguments": [], 494 + "directives": [], 495 + "selectionSet": { 496 + "kind": "SelectionSet", 497 + "selections": [ 498 + { 499 + "kind": "Field", 500 + "name": { 501 + "kind": "Name", 502 + "value": "count" 503 + }, 504 + "arguments": [], 505 + "directives": [] 506 + } 507 + ] 508 + } 509 + }, 510 + { 511 + "kind": "Field", 512 + "name": { 513 + "kind": "Name", 514 + "value": "likeSentence" 515 + }, 516 + "arguments": [], 517 + "directives": [], 518 + "selectionSet": { 519 + "kind": "SelectionSet", 520 + "selections": [ 521 + { 522 + "kind": "Field", 523 + "name": { 524 + "kind": "Name", 525 + "value": "text" 526 + }, 527 + "arguments": [], 528 + "directives": [] 529 + } 530 + ] 531 + } 532 + } 533 + ] 534 + } 535 + } 536 + ] 537 + } 538 + } 539 + ] 540 + } 541 + }, 542 + { 543 + "kind": "FragmentDefinition", 544 + "name": { 545 + "kind": "Name", 546 + "value": "frag" 547 + }, 548 + "typeCondition": { 549 + "kind": "NamedType", 550 + "name": { 551 + "kind": "Name", 552 + "value": "Friend" 553 + } 554 + }, 555 + "directives": [ 556 + { 557 + "kind": "Directive", 558 + "name": { 559 + "kind": "Name", 560 + "value": "onFragmentDefinition" 561 + }, 562 + "arguments": [] 563 + } 564 + ], 565 + "selectionSet": { 566 + "kind": "SelectionSet", 567 + "selections": [ 568 + { 569 + "kind": "Field", 570 + "name": { 571 + "kind": "Name", 572 + "value": "foo" 573 + }, 574 + "arguments": [ 575 + { 576 + "kind": "Argument", 577 + "name": { 578 + "kind": "Name", 579 + "value": "size" 580 + }, 581 + "value": { 582 + "kind": "Variable", 583 + "name": { 584 + "kind": "Name", 585 + "value": "site" 586 + } 587 + } 588 + }, 589 + { 590 + "kind": "Argument", 591 + "name": { 592 + "kind": "Name", 593 + "value": "bar" 594 + }, 595 + "value": { 596 + "kind": "IntValue", 597 + "value": "12" 598 + } 599 + }, 600 + { 601 + "kind": "Argument", 602 + "name": { 603 + "kind": "Name", 604 + "value": "obj" 605 + }, 606 + "value": { 607 + "kind": "ObjectValue", 608 + "fields": [ 609 + { 610 + "kind": "ObjectField", 611 + "name": { 612 + "kind": "Name", 613 + "value": "key" 614 + }, 615 + "value": { 616 + "kind": "StringValue", 617 + "value": "value", 618 + "block": false 619 + } 620 + }, 621 + { 622 + "kind": "ObjectField", 623 + "name": { 624 + "kind": "Name", 625 + "value": "block" 626 + }, 627 + "value": { 628 + "kind": "StringValue", 629 + "value": "block string uses \"\"\"", 630 + "block": true 631 + } 632 + } 633 + ] 634 + } 635 + } 636 + ], 637 + "directives": [] 638 + } 639 + ] 640 + } 641 + }, 642 + { 643 + "kind": "OperationDefinition", 644 + "operation": "query", 645 + "name": { 646 + "kind": "Name", 647 + "value": "teeny" 648 + }, 649 + "variableDefinitions": [], 650 + "directives": [], 651 + "selectionSet": { 652 + "kind": "SelectionSet", 653 + "selections": [ 654 + { 655 + "kind": "Field", 656 + "name": { 657 + "kind": "Name", 658 + "value": "unnamed" 659 + }, 660 + "arguments": [ 661 + { 662 + "kind": "Argument", 663 + "name": { 664 + "kind": "Name", 665 + "value": "truthy" 666 + }, 667 + "value": { 668 + "kind": "BooleanValue", 669 + "value": true 670 + } 671 + }, 672 + { 673 + "kind": "Argument", 674 + "name": { 675 + "kind": "Name", 676 + "value": "falsey" 677 + }, 678 + "value": { 679 + "kind": "BooleanValue", 680 + "value": false 681 + } 682 + }, 683 + { 684 + "kind": "Argument", 685 + "name": { 686 + "kind": "Name", 687 + "value": "nullish" 688 + }, 689 + "value": { 690 + "kind": "NullValue" 691 + } 692 + } 693 + ], 694 + "directives": [] 695 + }, 696 + { 697 + "kind": "Field", 698 + "name": { 699 + "kind": "Name", 700 + "value": "query" 701 + }, 702 + "arguments": [], 703 + "directives": [] 704 + } 705 + ] 706 + } 707 + }, 708 + { 709 + "kind": "OperationDefinition", 710 + "operation": "query", 711 + "name": { 712 + "kind": "Name", 713 + "value": "tiny" 714 + }, 715 + "variableDefinitions": [], 716 + "directives": [], 717 + "selectionSet": { 718 + "kind": "SelectionSet", 719 + "selections": [ 720 + { 721 + "kind": "Field", 722 + "name": { 723 + "kind": "Name", 724 + "value": "__typename" 725 + }, 726 + "arguments": [], 727 + "directives": [] 728 + } 729 + ] 730 + } 731 + } 732 + ] 733 + }
+7 -4
src/__tests__/parser.test.ts
··· 1 1 import { describe, it, expect } from 'vitest'; 2 2 import { readFileSync } from 'fs'; 3 3 4 + import { parse as graphql_parse } from 'graphql'; 4 5 import { parse } from '../parser'; 5 6 6 - describe('parse', () => { 7 - it('parses the kitchen sink query', () => { 7 + describe('print', () => { 8 + it('prints the kitchen sink document like graphql.js does', () => { 8 9 const sink = readFileSync(__dirname + '/../../benchmark/kitchen_sink.graphql', { encoding: 'utf8' }); 9 - expect(parse(sink)).toMatchSnapshot(); 10 - }) 10 + const doc = parse(sink); 11 + expect(doc).toMatchSnapshot(); 12 + expect(doc).toEqual(graphql_parse(sink, { noLocation: true })); 13 + }); 11 14 });
+14
src/__tests__/printer.test.ts
··· 1 + import { describe, it, expect } from 'vitest'; 2 + import { readFileSync } from 'fs'; 3 + 4 + import { print as graphql_print } from 'graphql'; 5 + import { print } from '../printer'; 6 + 7 + describe('print', () => { 8 + it('prints the kitchen sink document like graphql.js does', () => { 9 + const sink = JSON.parse(readFileSync(__dirname + '/kitchen_sink.json', { encoding: 'utf8' })); 10 + const doc = print(sink); 11 + expect(doc).toMatchSnapshot(); 12 + expect(doc).toEqual(graphql_print(sink)); 13 + }); 14 + });
+5 -3
src/parser.ts
··· 41 41 } 42 42 for (let i = firstNonEmptyLine; i <= lastNonEmptyLine; i++) { 43 43 if (i !== firstNonEmptyLine) out += '\n'; 44 - out += lines[i].slice(commonIndent); 44 + out += lines[i].slice(commonIndent).replace(/\\"""/g, '"""'); 45 45 } 46 46 return out; 47 47 } ··· 68 68 const boolRe = /true|false/y; 69 69 const variableRe = /\$[_\w][_\d\w]*/y; 70 70 const intRe = /[-]?\d+/y; 71 - const floatRe = /[-]?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?/y; 71 + const floatRe = /(?:[-]?\d+)?(?:\.\d+)(?:[eE][+-]?\d+)?/y; 72 72 const complexStringRe = /\\/g; 73 73 const blockStringRe = /"""(?:[\s\S]+(?="""))?"""/y; 74 74 const stringRe = /"(?:[^"\r\n]+)?"/y; ··· 310 310 ignored(); 311 311 if (advance(fragmentSpreadRe)) { 312 312 ignored(); 313 + const _idx = idx; 313 314 let _name: ast.NameNode | undefined; 314 - if (_name = name()) { 315 + if ((_name = name()) && _name.value !== 'on') { 315 316 return { 316 317 kind: Kind.FRAGMENT_SPREAD, 317 318 name: _name, 318 319 directives: directives(false), 319 320 }; 320 321 } else { 322 + idx = _idx; 321 323 const _typeCondition = typeCondition(); 322 324 const _directives = directives(false); 323 325 const _selectionSet = selectionSet();
+9 -2
src/printer.ts
··· 13 13 array: ReadonlyArray<T> | undefined | null 14 14 ): array is ReadonlyArray<T> => !!(array && array.length); 15 15 16 + const MAX_LINE_LENGTH = 80; 17 + 16 18 export function print(node: ASTNode): string { 17 19 let out: string; 18 20 switch (node.kind) { ··· 43 45 44 46 case Kind.FIELD: 45 47 out = (node.alias ? print(node.alias) + ': ' : '') + node.name.value 46 - if (hasItems(node.arguments)) 47 - out += '(' + node.arguments.map(print).join(', ') + ')'; 48 + if (hasItems(node.arguments)) { 49 + const args = node.arguments.map(print); 50 + const argsLine = out + '(' + args.join(', ') + ')'; 51 + out = argsLine.length > MAX_LINE_LENGTH 52 + ? out + '(\n ' + args.join('\n').replace(/\n/g, '\n ') + '\n)' 53 + : argsLine; 54 + } 48 55 if (hasItems(node.directives)) 49 56 out += ' ' + node.directives.map(print).join(' '); 50 57 return node.selectionSet