• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

thoughtspot / rise / #363

28 May 2025 06:00AM UTC coverage: 0.0% (-85.8%) from 85.769%
#363

push

sagar1993
Add gqlVariables to gqlResolver

0 of 113 branches covered (0.0%)

Branch coverage included in aggregate %.

0 of 5 new or added lines in 2 files covered. (0.0%)

144 existing lines in 4 files now uncovered.

0 of 162 relevant lines covered (0.0%)

0.0 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/gql-resolver.ts
UNCOV
1
import fetch from 'node-fetch';
×
2
import { GraphQLFieldConfig } from 'graphql';
UNCOV
3
import { print } from 'graphql/language/printer';
×
4
import _ from 'lodash';
UNCOV
5
import { RiseDirectiveOptions, getReqHeaders, processResHeaders } from './common';
×
NEW
6
import { generateBodyFromTemplate } from './rest-resolver';
×
7

8
export interface RiseDirectiveOptionsGql extends RiseDirectiveOptions {
9
    apiType: 'gql';
10
}
11

12
/**
13
 * Wraps arguments in a object of graphql query, when a wrapping object name and Class is defined.
14
 *
15
 * eg: Given wrapping object name 'session' and class 'ACSession'
16
 * query getSession($sessionId: String, $sessionName: String) {
17
 *   getGQLSessionDetails(sessionId: $sessionId, sessionName: $sessionName) {
18
 *     name
19
 *     email
20
 *     id
21
 *   }
22
 * }
23
 *
24
 *    ||  ||  ||  ||
25
 *    \/  \/  \/  \/
26
 *
27
 * query getSession($session: ACSession) {
28
 *   getGQLSessionDetails(session: $session) {
29
 *     name
30
 *     email
31
 *     id
32
 *   }
33
 * }
34
 *
35
 * Also takes care of adding structuring with the object name while making graphql call.
36
 *
37
 * fetch('/graphql', { query, variables: {session: { sessionId, sessionName }}})
38
 *  .then(res => res.session);
39
 *
40
 */
41
// eslint-disable-next-line default-param-last
42
function wrapArgumentsInGql(query = '', info, argwrapper) {
×
UNCOV
43
    if (argwrapper.name) {
×
UNCOV
44
        const { name: wrapperName, type: wrapperClass } = argwrapper;
×
UNCOV
45
        const operationType = info.operation.operation;
×
UNCOV
46
        const operationName = info.operation.name?.value;
×
UNCOV
47
        const fieldName = info.fieldName;
×
48

49
        // Regex to replace query getOpName($var1: VarType1, $var2: VarType2 ...)
50
        // to query getOpName($wrappedType: WrappedType)
UNCOV
51
        const createOpNameRegex = (opType, opName) => new RegExp(`\\b${opType}\\s+${opName}\\s*\\([^()]*\\)`, 'g');
×
52

53
        // Regex to replace GetOpName(var1: $var1, var2: $var2, ...)
54
        // to GetOpName(wrappedType: $wrappedType)
UNCOV
55
        const createFieldNameRegex = (field) => new RegExp(`\\b${field}\\s*\\([^()]*\\)`, 'g');
×
56

57
        // Replace operation and field names carefully
UNCOV
58
        return query
×
59
            // Replace the operation and operationName
60
            .replace(
61
                createOpNameRegex('query', operationName),
62
                `${operationType} ${operationName}($${wrapperName}: ${wrapperClass})`,
63
            )
64
            // Replace the fieldName in the query body
65
            .replace(
66
                createFieldNameRegex(fieldName),
67
                `${fieldName}(${wrapperName}: $${wrapperName})`,
68
            );
69
    }
70
    return query;
×
71
}
72

UNCOV
73
export function gqlResolver(
×
74
    riseDirective,
75
    options: RiseDirectiveOptionsGql,
76
    fieldConfig: GraphQLFieldConfig<any, any, any>,
77
) {
UNCOV
78
    const url = options.baseURL;
×
NEW
79
    let { argwrapper, gqlVariables } = riseDirective;
×
80

UNCOV
81
    fieldConfig.resolve = (source, args, context, info) => {
×
UNCOV
82
        let urlToFetch = url;
×
UNCOV
83
        let originalContext = context;
×
UNCOV
84
        let query = print(info.operation);
×
85

UNCOV
86
        const wrappingObject = argwrapper && argwrapper.name;
×
87

UNCOV
88
        if (argwrapper) {
×
UNCOV
89
            query = wrapArgumentsInGql(query, info, argwrapper);
×
90
        }
91

NEW
92
        const variables = gqlVariables ? generateBodyFromTemplate(gqlVariables, args) : info.variableValues;
×
UNCOV
93
        let body = JSON.stringify({
×
94
            query,
95
            variables: wrappingObject ? { [wrappingObject]: variables } : variables,
×
96
        });
NEW
97
        console.debug('[Rise] GQL request body:', body);
×
98

UNCOV
99
        const reqHeaders = getReqHeaders(riseDirective, options, originalContext);
×
100

UNCOV
101
        console.debug('[Rise] GQL - Downstream URL and operation', urlToFetch, info.fieldName);
×
UNCOV
102
        return fetch(urlToFetch, {
×
103
            method: 'POST',
104
            headers: reqHeaders,
105
            body,
106
        })
107
            .then((response) => {
UNCOV
108
                processResHeaders(response, originalContext);
×
UNCOV
109
                return response.json();
×
110
            })
111
            .then((response) => {
UNCOV
112
                if (response.errors) {
×
113
                    // TODO: Update the error class to passthough error context more correctly.
UNCOV
114
                    throw new options.ErrorClass(
×
115
                        response.statusText,
116
                        response.status,
117
                        response.errors,
118
                    );
119
                }
120

UNCOV
121
                return response.data[info.fieldName];
×
122
            });
123
    };
124
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc