@@ -30,14 +30,16 @@ import {
30
30
splitSelectionParameters ,
31
31
getTemporalArguments ,
32
32
temporalPredicateClauses ,
33
- isTemporalType
33
+ isTemporalType ,
34
+ isGraphqlScalarType
34
35
} from './utils' ;
35
36
import { getNamedType } from 'graphql' ;
36
37
import { buildCypherSelection } from './selections' ;
37
38
import _ from 'lodash' ;
38
39
39
40
export const customCypherField = ( {
40
41
customCypher,
42
+ cypherParams,
41
43
schemaTypeRelation,
42
44
initial,
43
45
fieldName,
@@ -62,6 +64,7 @@ export const customCypherField = ({
62
64
fieldIsList ? '' : 'head('
63
65
} [ ${ nestedVariable } IN apoc.cypher.runFirstColumn("${ customCypher } ", ${ cypherDirectiveArgs (
64
66
variableName ,
67
+ cypherParams ,
65
68
headSelection ,
66
69
schemaType ,
67
70
resolveInfo
@@ -368,7 +371,7 @@ export const temporalField = ({
368
371
// containing this temporal field was a node
369
372
let variableName = parentVariableName ;
370
373
let fieldIsArray = isArrayType ( parentFieldType ) ;
371
- if ( ! isNodeType ( parentSchemaType . astNode ) ) {
374
+ if ( parentSchemaType && ! isNodeType ( parentSchemaType . astNode ) ) {
372
375
// initial assumption wrong, build appropriate relationship variable
373
376
if (
374
377
isRootSelection ( {
@@ -474,6 +477,7 @@ export const temporalType = ({
474
477
// Query API root operation branch
475
478
export const translateQuery = ( {
476
479
resolveInfo,
480
+ context,
477
481
selections,
478
482
variableName,
479
483
typeName,
@@ -493,13 +497,15 @@ export const translateQuery = ({
493
497
const queryArgs = getQueryArguments ( resolveInfo ) ;
494
498
const temporalArgs = getTemporalArguments ( queryArgs ) ;
495
499
const queryTypeCypherDirective = getQueryCypherDirective ( resolveInfo ) ;
500
+ const cypherParams = getCypherParams ( context ) ;
496
501
const queryParams = paramsToString (
497
502
innerFilterParams (
498
503
filterParams ,
499
504
temporalArgs ,
500
505
null ,
501
506
queryTypeCypherDirective ? true : false
502
- )
507
+ ) ,
508
+ cypherParams
503
509
) ;
504
510
const safeVariableName = safeVar ( variableName ) ;
505
511
const temporalClauses = temporalPredicateClauses (
@@ -509,9 +515,11 @@ export const translateQuery = ({
509
515
) ;
510
516
const outerSkipLimit = getOuterSkipLimit ( first ) ;
511
517
const orderByValue = computeOrderBy ( resolveInfo , selections ) ;
518
+
512
519
if ( queryTypeCypherDirective ) {
513
520
return customQuery ( {
514
521
resolveInfo,
522
+ cypherParams,
515
523
schemaType,
516
524
argString : queryParams ,
517
525
selections,
@@ -525,6 +533,7 @@ export const translateQuery = ({
525
533
} else {
526
534
return nodeQuery ( {
527
535
resolveInfo,
536
+ cypherParams,
528
537
schemaType,
529
538
argString : queryParams ,
530
539
selections,
@@ -542,9 +551,19 @@ export const translateQuery = ({
542
551
}
543
552
} ;
544
553
554
+ const getCypherParams = context => {
555
+ return context &&
556
+ context . cypherParams &&
557
+ context . cypherParams instanceof Object &&
558
+ Object . keys ( context . cypherParams ) . length > 0
559
+ ? context . cypherParams
560
+ : undefined ;
561
+ } ;
562
+
545
563
// Custom read operation
546
564
const customQuery = ( {
547
565
resolveInfo,
566
+ cypherParams,
548
567
schemaType,
549
568
argString,
550
569
selections,
@@ -558,27 +577,40 @@ const customQuery = ({
558
577
const safeVariableName = safeVar ( variableName ) ;
559
578
const [ subQuery , subParams ] = buildCypherSelection ( {
560
579
initial : '' ,
580
+ cypherParams,
561
581
selections,
562
582
variableName,
563
583
schemaType,
564
584
resolveInfo,
565
585
paramIndex : 1
566
586
} ) ;
567
587
const params = { ...nonNullParams , ...subParams } ;
588
+ if ( cypherParams ) {
589
+ params [ 'cypherParams' ] = cypherParams ;
590
+ }
568
591
// QueryType with a @cypher directive
569
592
const cypherQueryArg = queryTypeCypherDirective . arguments . find ( x => {
570
593
return x . name . value === 'statement' ;
571
594
} ) ;
595
+ const isScalarType = isGraphqlScalarType ( schemaType ) ;
596
+ const temporalType = isTemporalType ( schemaType . name ) ;
572
597
const query = `WITH apoc.cypher.runFirstColumn("${
573
598
cypherQueryArg . value . value
574
- } ", ${ argString || 'null' } , True) AS x UNWIND x AS ${ safeVariableName }
575
- RETURN ${ safeVariableName } {${ subQuery } } AS ${ safeVariableName } ${ orderByValue } ${ outerSkipLimit } ` ;
599
+ } ", ${ argString ||
600
+ 'null' } , True) AS x UNWIND x AS ${ safeVariableName } RETURN ${ safeVariableName } ${
601
+ // Don't add subQuery for scalar type payloads
602
+ // FIXME: fix subselection translation for temporal type payload
603
+ ! temporalType && ! isScalarType
604
+ ? `{${ subQuery } } AS ${ safeVariableName } ${ orderByValue } `
605
+ : ''
606
+ } ${ outerSkipLimit } `;
576
607
return [ query , params ] ;
577
608
} ;
578
609
579
610
// Generated API
580
611
const nodeQuery = ( {
581
612
resolveInfo,
613
+ cypherParams,
582
614
schemaType,
583
615
selections,
584
616
variableName,
@@ -596,13 +628,17 @@ const nodeQuery = ({
596
628
const safeLabelName = safeLabel ( typeName ) ;
597
629
const [ subQuery , subParams ] = buildCypherSelection ( {
598
630
initial : '' ,
631
+ cypherParams,
599
632
selections,
600
633
variableName,
601
634
schemaType,
602
635
resolveInfo,
603
636
paramIndex : 1
604
637
} ) ;
605
638
const params = { ...nonNullParams , ...subParams } ;
639
+ if ( cypherParams ) {
640
+ params [ 'cypherParams' ] = cypherParams ;
641
+ }
606
642
const arrayParams = _ . pickBy ( filterParams , Array . isArray ) ;
607
643
const args = innerFilterParams ( filterParams , temporalArgs ) ;
608
644
@@ -642,6 +678,7 @@ const nodeQuery = ({
642
678
// Mutation API root operation branch
643
679
export const translateMutation = ( {
644
680
resolveInfo,
681
+ context,
645
682
schemaType,
646
683
selections,
647
684
variableName,
@@ -669,6 +706,7 @@ export const translateMutation = ({
669
706
if ( mutationTypeCypherDirective ) {
670
707
return customMutation ( {
671
708
...mutationInfo ,
709
+ context,
672
710
mutationTypeCypherDirective,
673
711
variableName,
674
712
orderByValue,
@@ -712,6 +750,7 @@ export const translateMutation = ({
712
750
// Custom write operation
713
751
const customMutation = ( {
714
752
params,
753
+ context,
715
754
mutationTypeCypherDirective,
716
755
selections,
717
756
variableName,
@@ -720,6 +759,7 @@ const customMutation = ({
720
759
orderByValue,
721
760
outerSkipLimit
722
761
} ) => {
762
+ const cypherParams = getCypherParams ( context ) ;
723
763
const safeVariableName = safeVar ( variableName ) ;
724
764
// FIXME: support IN for multiple values -> WHERE
725
765
const argString = paramsToString (
@@ -728,7 +768,8 @@ const customMutation = ({
728
768
null ,
729
769
null ,
730
770
true
731
- )
771
+ ) ,
772
+ cypherParams
732
773
) ;
733
774
const cypherQueryArg = mutationTypeCypherDirective . arguments . find ( x => {
734
775
return x . name . value === 'statement' ;
@@ -741,12 +782,21 @@ const customMutation = ({
741
782
resolveInfo,
742
783
paramIndex : 1
743
784
} ) ;
785
+ const isScalarType = isGraphqlScalarType ( schemaType ) ;
786
+ const temporalType = isTemporalType ( schemaType . name ) ;
744
787
params = { ...params , ...subParams } ;
788
+ if ( cypherParams ) {
789
+ params [ 'cypherParams' ] = cypherParams ;
790
+ }
745
791
const query = `CALL apoc.cypher.doIt("${
746
792
cypherQueryArg . value . value
747
793
} ", ${ argString } ) YIELD value
748
794
WITH apoc.map.values(value, [keys(value)[0]])[0] AS ${ safeVariableName }
749
- RETURN ${ safeVariableName } {${ subQuery } } AS ${ safeVariableName } ${ orderByValue } ${ outerSkipLimit } ` ;
795
+ RETURN ${ safeVariableName } ${
796
+ ! temporalType && ! isScalarType
797
+ ? `{${ subQuery } } AS ${ safeVariableName } ${ orderByValue } ${ outerSkipLimit } `
798
+ : ''
799
+ } `;
750
800
return [ query , params ] ;
751
801
} ;
752
802
0 commit comments