@@ -56,6 +56,8 @@ const QueryRootType = new GraphQLObjectType({
5656} ) ;
5757
5858const TestSchema = new GraphQLSchema ( {
59+ experimentalDefer : true ,
60+ experimentalStream : true ,
5961 query : QueryRootType ,
6062 mutation : new GraphQLObjectType ( {
6163 name : 'MutationRoot' ,
@@ -1022,6 +1024,54 @@ function runTests(server: Server) {
10221024 errors : [ { message : 'Must provide query string.' } ] ,
10231025 } ) ;
10241026 } ) ;
1027+
1028+ it ( 'allows for streaming results with @defer' , async ( ) => {
1029+ const app = server ( ) ;
1030+
1031+ app . post (
1032+ urlString ( ) ,
1033+ graphqlHTTP ( {
1034+ schema : TestSchema ,
1035+ } ) ,
1036+ ) ;
1037+
1038+ const req = app
1039+ . request ( )
1040+ . post ( urlString ( ) )
1041+ . send ( {
1042+ query :
1043+ '{ ...frag @defer(label: "deferLabel") } fragment frag on QueryRoot { test(who: "World") }' ,
1044+ } )
1045+ . parse ( ( res , cb ) => {
1046+ res . on ( 'data' , ( data ) => {
1047+ res . text = `${ res . text || '' } ${ data . toString ( 'utf8' ) as string } ` ;
1048+ } ) ;
1049+ res . on ( 'end' , ( err ) => {
1050+ cb ( err , null ) ;
1051+ } ) ;
1052+ } ) ;
1053+
1054+ const response = await req ;
1055+ expect ( response . text ) . to . equal (
1056+ [
1057+ '' ,
1058+ '---' ,
1059+ 'Content-Type: application/json; charset=utf-8' ,
1060+ 'Content-Length: 26' ,
1061+ '' ,
1062+ '{"data":{},"hasNext":true}' ,
1063+ '' ,
1064+ '---' ,
1065+ 'Content-Type: application/json; charset=utf-8' ,
1066+ 'Content-Length: 78' ,
1067+ '' ,
1068+ '{"data":{"test":"Hello World"},"path":[],"label":"deferLabel","hasNext":false}' ,
1069+ '' ,
1070+ '-----' ,
1071+ '' ,
1072+ ] . join ( '\r\n' ) ,
1073+ ) ;
1074+ } ) ;
10251075 } ) ;
10261076
10271077 describe ( 'Pretty printing' , ( ) => {
@@ -1104,6 +1154,62 @@ function runTests(server: Server) {
11041154
11051155 expect ( unprettyResponse . text ) . to . equal ( '{"data":{"test":"Hello World"}}' ) ;
11061156 } ) ;
1157+ it ( 'supports pretty printing async iterable requests' , async ( ) => {
1158+ const app = server ( ) ;
1159+
1160+ app . post (
1161+ urlString ( ) ,
1162+ graphqlHTTP ( {
1163+ schema : TestSchema ,
1164+ pretty : true ,
1165+ } ) ,
1166+ ) ;
1167+
1168+ const req = app
1169+ . request ( )
1170+ . post ( urlString ( ) )
1171+ . send ( {
1172+ query :
1173+ '{ ...frag @defer } fragment frag on QueryRoot { test(who: "World") }' ,
1174+ } )
1175+ . parse ( ( res , cb ) => {
1176+ res . on ( 'data' , ( data ) => {
1177+ res . text = `${ res . text || '' } ${ data . toString ( 'utf8' ) as string } ` ;
1178+ } ) ;
1179+ res . on ( 'end' , ( err ) => {
1180+ cb ( err , null ) ;
1181+ } ) ;
1182+ } ) ;
1183+
1184+ const response = await req ;
1185+ expect ( response . text ) . to . equal (
1186+ [
1187+ '' ,
1188+ '---' ,
1189+ 'Content-Type: application/json; charset=utf-8' ,
1190+ 'Content-Length: 35' ,
1191+ '' ,
1192+ [ '{' , ' "data": {},' , ' "hasNext": true' , '}' ] . join ( '\n' ) ,
1193+ '' ,
1194+ '---' ,
1195+ 'Content-Type: application/json; charset=utf-8' ,
1196+ 'Content-Length: 79' ,
1197+ '' ,
1198+ [
1199+ '{' ,
1200+ ' "data": {' ,
1201+ ' "test": "Hello World"' ,
1202+ ' },' ,
1203+ ' "path": [],' ,
1204+ ' "hasNext": false' ,
1205+ '}' ,
1206+ ] . join ( '\n' ) ,
1207+ '' ,
1208+ '-----' ,
1209+ '' ,
1210+ ] . join ( '\r\n' ) ,
1211+ ) ;
1212+ } ) ;
11071213 } ) ;
11081214
11091215 it ( 'will send request and response when using thunk' , async ( ) => {
@@ -1224,6 +1330,108 @@ function runTests(server: Server) {
12241330 } ) ;
12251331 } ) ;
12261332
1333+ it ( 'allows for custom error formatting in initial payload of async iterator' , async ( ) => {
1334+ const app = server ( ) ;
1335+
1336+ app . post (
1337+ urlString ( ) ,
1338+ graphqlHTTP ( {
1339+ schema : TestSchema ,
1340+ customFormatErrorFn ( error ) {
1341+ return { message : 'Custom error format: ' + error . message } ;
1342+ } ,
1343+ } ) ,
1344+ ) ;
1345+
1346+ const req = app
1347+ . request ( )
1348+ . post ( urlString ( ) )
1349+ . send ( {
1350+ query :
1351+ '{ thrower, ...frag @defer } fragment frag on QueryRoot { test(who: "World") }' ,
1352+ } )
1353+ . parse ( ( res , cb ) => {
1354+ res . on ( 'data' , ( data ) => {
1355+ res . text = `${ res . text || '' } ${ data . toString ( 'utf8' ) as string } ` ;
1356+ } ) ;
1357+ res . on ( 'end' , ( err ) => {
1358+ cb ( err , null ) ;
1359+ } ) ;
1360+ } ) ;
1361+
1362+ const response = await req ;
1363+ expect ( response . text ) . to . equal (
1364+ [
1365+ '' ,
1366+ '---' ,
1367+ 'Content-Type: application/json; charset=utf-8' ,
1368+ 'Content-Length: 94' ,
1369+ '' ,
1370+ '{"errors":[{"message":"Custom error format: Throws!"}],"data":{"thrower":null},"hasNext":true}' ,
1371+ '' ,
1372+ '---' ,
1373+ 'Content-Type: application/json; charset=utf-8' ,
1374+ 'Content-Length: 57' ,
1375+ '' ,
1376+ '{"data":{"test":"Hello World"},"path":[],"hasNext":false}' ,
1377+ '' ,
1378+ '-----' ,
1379+ '' ,
1380+ ] . join ( '\r\n' ) ,
1381+ ) ;
1382+ } ) ;
1383+
1384+ it ( 'allows for custom error formatting in subsequent payloads of async iterator' , async ( ) => {
1385+ const app = server ( ) ;
1386+
1387+ app . post (
1388+ urlString ( ) ,
1389+ graphqlHTTP ( {
1390+ schema : TestSchema ,
1391+ customFormatErrorFn ( error ) {
1392+ return { message : 'Custom error format: ' + error . message } ;
1393+ } ,
1394+ } ) ,
1395+ ) ;
1396+
1397+ const req = app
1398+ . request ( )
1399+ . post ( urlString ( ) )
1400+ . send ( {
1401+ query :
1402+ '{ test(who: "World"), ...frag @defer } fragment frag on QueryRoot { thrower }' ,
1403+ } )
1404+ . parse ( ( res , cb ) => {
1405+ res . on ( 'data' , ( data ) => {
1406+ res . text = `${ res . text || '' } ${ data . toString ( 'utf8' ) as string } ` ;
1407+ } ) ;
1408+ res . on ( 'end' , ( err ) => {
1409+ cb ( err , null ) ;
1410+ } ) ;
1411+ } ) ;
1412+
1413+ const response = await req ;
1414+ expect ( response . text ) . to . equal (
1415+ [
1416+ '' ,
1417+ '---' ,
1418+ 'Content-Type: application/json; charset=utf-8' ,
1419+ 'Content-Length: 46' ,
1420+ '' ,
1421+ '{"data":{"test":"Hello World"},"hasNext":true}' ,
1422+ '' ,
1423+ '---' ,
1424+ 'Content-Type: application/json; charset=utf-8' ,
1425+ 'Content-Length: 105' ,
1426+ '' ,
1427+ '{"data":{"thrower":null},"path":[],"errors":[{"message":"Custom error format: Throws!"}],"hasNext":false}' ,
1428+ '' ,
1429+ '-----' ,
1430+ '' ,
1431+ ] . join ( '\r\n' ) ,
1432+ ) ;
1433+ } ) ;
1434+
12271435 it ( 'allows for custom error formatting to elaborate' , async ( ) => {
12281436 const app = server ( ) ;
12291437
@@ -2215,6 +2423,57 @@ function runTests(server: Server) {
22152423 } ) ;
22162424 } ) ;
22172425
2426+ it ( 'allows for custom extensions in initial and subsequent payloads of async iterator' , async ( ) => {
2427+ const app = server ( ) ;
2428+
2429+ app . post (
2430+ urlString ( ) ,
2431+ graphqlHTTP ( {
2432+ schema : TestSchema ,
2433+ extensions ( { result } ) {
2434+ return { preservedResult : { ...result } } ;
2435+ } ,
2436+ } ) ,
2437+ ) ;
2438+
2439+ const req = app
2440+ . request ( )
2441+ . post ( urlString ( ) )
2442+ . send ( {
2443+ query :
2444+ '{ hello: test(who: "Rob"), ...frag @defer } fragment frag on QueryRoot { test(who: "World") }' ,
2445+ } )
2446+ . parse ( ( res , cb ) => {
2447+ res . on ( 'data' , ( data ) => {
2448+ res . text = `${ res . text || '' } ${ data . toString ( 'utf8' ) as string } ` ;
2449+ } ) ;
2450+ res . on ( 'end' , ( err ) => {
2451+ cb ( err , null ) ;
2452+ } ) ;
2453+ } ) ;
2454+
2455+ const response = await req ;
2456+ expect ( response . text ) . to . equal (
2457+ [
2458+ '' ,
2459+ '---' ,
2460+ 'Content-Type: application/json; charset=utf-8' ,
2461+ 'Content-Length: 124' ,
2462+ '' ,
2463+ '{"data":{"hello":"Hello Rob"},"hasNext":true,"extensions":{"preservedResult":{"data":{"hello":"Hello Rob"},"hasNext":true}}}' ,
2464+ '' ,
2465+ '---' ,
2466+ 'Content-Type: application/json; charset=utf-8' ,
2467+ 'Content-Length: 148' ,
2468+ '' ,
2469+ '{"data":{"test":"Hello World"},"path":[],"hasNext":false,"extensions":{"preservedResult":{"data":{"test":"Hello World"},"path":[],"hasNext":false}}}' ,
2470+ '' ,
2471+ '-----' ,
2472+ '' ,
2473+ ] . join ( '\r\n' ) ,
2474+ ) ;
2475+ } ) ;
2476+
22182477 it ( 'extension function may be async' , async ( ) => {
22192478 const app = server ( ) ;
22202479
0 commit comments