@@ -31,12 +31,22 @@ const API_VERSION = 'v1alpha';
3131const FIREBASE_DATA_CONNECT_BASE_URL_FORMAT =
3232 'https://firebasedataconnect.googleapis.com/{version}/projects/{projectId}/locations/{locationId}/services/{serviceId}:{endpointId}' ;
3333
34- /** Firebase Data Connect base URl format when using the Data Connect emultor. */
34+ /** The Firebase Data Connect backend base URL format including a connector. */
35+ const FIREBASE_DATA_CONNECT_BASE_URL_FORMAT_WITH_CONNECTOR =
36+ 'https://firebasedataconnect.googleapis.com/{version}/projects/{projectId}/locations/{locationId}/services/{serviceId}/connectors/${connector}:{endpointId}' ;
37+
38+ /** Firebase Data Connect base URl format when using the Data Connect emulator. */
3539const FIREBASE_DATA_CONNECT_EMULATOR_BASE_URL_FORMAT =
3640 'http://{host}/{version}/projects/{projectId}/locations/{locationId}/services/{serviceId}:{endpointId}' ;
3741
42+ /** Firebase Data Connect base URl format when using the Data Connect emulator including a connector. */
43+ const FIREBASE_DATA_CONNECT_EMULATOR_BASE_URL_FORMAT_WITH_CONNECTOR =
44+ 'http://{host}/{version}/projects/{projectId}/locations/{locationId}/services/{serviceId}/connectors/${connector}:{endpointId}' ;
45+
3846const EXECUTE_GRAPH_QL_ENDPOINT = 'executeGraphql' ;
3947const EXECUTE_GRAPH_QL_READ_ENDPOINT = 'executeGraphqlRead' ;
48+ const EXECUTE_QUERY_ENDPOINT = 'executeQuery' ;
49+ // const EXECUTE_MUTATION_ENDPOINT = 'executeMutation';
4050
4151const DATA_CONNECT_CONFIG_HEADERS = {
4252 'X-Firebase-Client' : `fire-admin-node/${ utils . getSdkVersion ( ) } `
@@ -75,7 +85,7 @@ export class DataConnectApiClient {
7585 }
7686
7787 /**
78- * Execute arbitrary read-only GraphQL queries
88+ * Execute arbi<QueryResult<Data, Variables>>trary read-only GraphQL queries
7989 *
8090 * @param query - The GraphQL (read-only) string to be executed.
8191 * @param options - GraphQL Options
@@ -89,6 +99,68 @@ export class DataConnectApiClient {
8999 return this . executeGraphqlHelper ( query , EXECUTE_GRAPH_QL_READ_ENDPOINT , options ) ;
90100 }
91101
102+ /**
103+ * Uses the name and the variables parameters to execute a query.
104+ */
105+ public async executeQuery < Data , Variables > (
106+ options : GraphqlOptions < Variables > ,
107+ ) : Promise < ExecuteGraphqlResponse < Data > > {
108+ // const {data} = await this.executeHelper(options.operationName!, EXECUTE_QUERY_ENDPOINT, options);
109+ return this . executeHelper ( EXECUTE_QUERY_ENDPOINT , options ) ;
110+ }
111+
112+ private async executeHelper < GraphqlResponse , Variables > (
113+ endpoint : string ,
114+ options ?: GraphqlOptions < Variables > ,
115+ gql ?: string
116+ ) : Promise < ExecuteGraphqlResponse < GraphqlResponse > > {
117+ if ( ! validator . isNonEmptyString ( gql ) ) {
118+ throw new FirebaseDataConnectError (
119+ DATA_CONNECT_ERROR_CODE_MAPPING . INVALID_ARGUMENT ,
120+ '`query` must be a non-empty string.' ) ;
121+ }
122+ if ( typeof options !== 'undefined' ) {
123+ if ( ! validator . isNonNullObject ( options ) ) {
124+ throw new FirebaseDataConnectError (
125+ DATA_CONNECT_ERROR_CODE_MAPPING . INVALID_ARGUMENT ,
126+ 'GraphqlOptions must be a non-null object' ) ;
127+ }
128+ }
129+ const data = {
130+ query : gql ,
131+ ...( ! gql && { name : options ?. operationName } ) ,
132+ ...( options ?. variables && { variables : options ?. variables } ) ,
133+ //change to if query != operationName for executeQuery and executeMutation
134+ //Also how was this needed in conjuncton with executeGraphql before? Just the name of an operation normally doesn't that mean this is how it was used before?
135+ ...( options ?. operationName && { operationName : options ?. operationName } ) ,
136+ ...( options ?. impersonate && { extensions : { impersonate : options ?. impersonate } } ) ,
137+ } ;
138+ return this . getUrl ( API_VERSION , this . connectorConfig . location , this . connectorConfig . serviceId , endpoint , this . connectorConfig . connector )
139+ . then ( async ( url ) => {
140+ const request : HttpRequestConfig = {
141+ method : 'POST' ,
142+ url,
143+ headers : DATA_CONNECT_CONFIG_HEADERS ,
144+ data,
145+ } ;
146+ const resp = await this . httpClient . send ( request ) ;
147+ if ( resp . data . errors && validator . isNonEmptyArray ( resp . data . errors ) ) {
148+ const allMessages = resp . data . errors . map ( ( error : { message : any ; } ) => error . message ) . join ( ' ' ) ;
149+ throw new FirebaseDataConnectError (
150+ DATA_CONNECT_ERROR_CODE_MAPPING . QUERY_ERROR , allMessages ) ;
151+ }
152+ return Promise . resolve ( {
153+ data : resp . data . data as GraphqlResponse ,
154+ } ) ;
155+ } )
156+ . then ( ( resp ) => {
157+ return resp ;
158+ } )
159+ . catch ( ( err ) => {
160+ throw this . toFirebaseError ( err ) ;
161+ } ) ;
162+ }
163+
92164 private async executeGraphqlHelper < GraphqlResponse , Variables > (
93165 query : string ,
94166 endpoint : string ,
@@ -138,23 +210,34 @@ export class DataConnectApiClient {
138210 } ) ;
139211 }
140212
141- private async getUrl ( version : string , locationId : string , serviceId : string , endpointId : string ) : Promise < string > {
213+ private async getUrl ( version : string , locationId : string , serviceId : string , endpointId : string , connector ?: string ) : Promise < string > {
142214 return this . getProjectId ( )
143215 . then ( ( projectId ) => {
144216 const urlParams = {
145217 version,
146218 projectId,
147219 locationId,
148220 serviceId,
149- endpointId
221+ endpointId,
222+ ...( connector && { connector } )
150223 } ;
151224 let urlFormat : string ;
152225 if ( useEmulator ( ) ) {
153- urlFormat = utils . formatString ( FIREBASE_DATA_CONNECT_EMULATOR_BASE_URL_FORMAT , {
226+ if ( 'connector' in urlParams ) {
227+ urlFormat = utils . formatString ( FIREBASE_DATA_CONNECT_EMULATOR_BASE_URL_FORMAT_WITH_CONNECTOR , {
154228 host : emulatorHost ( )
155229 } ) ;
230+ }
231+ else {
232+ urlFormat = utils . formatString ( FIREBASE_DATA_CONNECT_EMULATOR_BASE_URL_FORMAT , {
233+ host : emulatorHost ( )
234+ } ) ;
235+ }
156236 } else {
157- urlFormat = FIREBASE_DATA_CONNECT_BASE_URL_FORMAT ;
237+ if ( 'connector' in urlParams ) {
238+ urlFormat = FIREBASE_DATA_CONNECT_BASE_URL_FORMAT_WITH_CONNECTOR }
239+ else {
240+ urlFormat = FIREBASE_DATA_CONNECT_BASE_URL_FORMAT ; }
158241 }
159242 return utils . formatString ( urlFormat , urlParams ) ;
160243 } ) ;
0 commit comments