Skip to content

Commit

Permalink
Add DataConnect Service
Browse files Browse the repository at this point in the history
  • Loading branch information
lahirumaramba committed Sep 11, 2024
1 parent 5549680 commit 66e4030
Show file tree
Hide file tree
Showing 9 changed files with 84 additions and 241 deletions.
22 changes: 12 additions & 10 deletions etc/firebase-admin.data-connect.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,22 @@

import { Agent } from 'http';

// @public (undocumented)
export interface ConnectorConfig {
// (undocumented)
location: string;
// (undocumented)
serviceId: string;
}

// @public
export class DataConnect {
// Warning: (ae-forgotten-export) The symbol "App" needs to be exported by the entry point index.d.ts
//
// (undocumented)
readonly app: App;
// (undocumented)
readonly connectorConfig: ConnectorConfig;
executeGraphql<GraphqlResponse, Variables>(query: string, options?: GraphqlOptions<Variables>): Promise<ExecuteGraphqlResponse<GraphqlResponse>>;
}

Expand All @@ -24,18 +34,10 @@ export interface ExecuteGraphqlResponse<GraphqlResponse> {
}

// @public
export function getDataConnect(app?: App): DataConnect;

// Warning: (ae-forgotten-export) The symbol "BaseGraphqlOptions" needs to be exported by the entry point index.d.ts
//
// @public (undocumented)
export interface GraphqlOptions<Variables> extends BaseGraphqlOptions<Variables> {
// (undocumented)
variables?: Variables;
}
export function getDataConnect(connectorConfig: ConnectorConfig, app?: App): DataConnect;

// @public (undocumented)
export interface GraphqlReadOptions<Variables> extends BaseGraphqlOptions<Variables> {
export interface GraphqlOptions<Variables> {
// (undocumented)
variables?: Variables;
}
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
"lint": "run-p lint:src lint:test",
"test": "run-s lint test:unit",
"integration": "run-s build test:integration",
"test:unit": "mocha test/unit/*.spec.ts --require ts-node/register",
"test:integration": "mocha test/integration/setup.ts test/integration/data-connect.ts --slow 5000 --timeout 20000 --require ts-node/register",
"test:unit": "mocha test/unit/data-connect/*.spec.ts --require ts-node/register",
"test:integration": "mocha test/integration/setup.ts test/integration/data-connect.spec.ts --slow 5000 --timeout 20000 --require ts-node/register",
"test:coverage": "nyc npm run test:unit",
"lint:src": "eslint src/ --ext .ts",
"lint:test": "eslint test/ --ext .ts",
Expand Down
6 changes: 3 additions & 3 deletions src/data-connect/data-connect-api-client-internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import {
import { PrefixedFirebaseError } from '../utils/error';
import * as utils from '../utils/index';
import * as validator from '../utils/validator';
import { ExecuteGraphqlResponse, GraphqlOptions } from './data-connect-api';
import { ConnectorConfig, ExecuteGraphqlResponse, GraphqlOptions } from './data-connect-api';

// Data Connect backend constants
const DATA_CONNECT_HOST = 'https://firebasedataconnect.googleapis.com';
Expand All @@ -47,7 +47,7 @@ export class DataConnectApiClient {
private readonly httpClient: HttpClient;
private projectId?: string;

constructor(private readonly app: App) {
constructor(private readonly connectorConfig: ConnectorConfig, private readonly app: App) {
if (!validator.isNonNullObject(app) || !('options' in app)) {
throw new FirebaseDataConnectError(
'invalid-argument',
Expand Down Expand Up @@ -79,7 +79,7 @@ export class DataConnectApiClient {
}
}
const host = (process.env.DATA_CONNECT_EMULATOR_HOST || DATA_CONNECT_HOST);
return this.getUrl(host, 'us-west2', 'my-service', EXECUTE_GRAPH_QL_ENDPOINT)
return this.getUrl(host, this.connectorConfig.location, this.connectorConfig.serviceId, EXECUTE_GRAPH_QL_ENDPOINT)
.then(async (url) => {
const request: HttpRequestConfig = {
method: 'POST',
Expand Down
10 changes: 1 addition & 9 deletions src/data-connect/data-connect-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,6 @@ export interface ExecuteGraphqlResponse<GraphqlResponse> {
data: GraphqlResponse;
}

export interface BaseGraphqlOptions<Variables> {
variables?: Variables;
}

export interface GraphqlReadOptions<Variables> extends BaseGraphqlOptions<Variables> {
variables?: Variables;
}

export interface GraphqlOptions<Variables> extends BaseGraphqlOptions<Variables> {
export interface GraphqlOptions<Variables> {
variables?: Variables;
}
37 changes: 35 additions & 2 deletions src/data-connect/data-connect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,43 @@ import { DataConnectApiClient } from './data-connect-api-client-internal';
//import * as validator from '../utils/validator';

import {
ConnectorConfig,
ExecuteGraphqlResponse,
GraphqlOptions,
//GraphqlReadOptions,
} from './data-connect-api';

export class DataConnectService {

private readonly appInternal: App;
private dataConnectInstances: Map<string, DataConnect> = new Map();

constructor(app: App) {
this.appInternal = app;
}

getDataConnect(connectorConfig: ConnectorConfig): DataConnect {
const id = `${connectorConfig.location}-${connectorConfig.serviceId}`;
const dc = this.dataConnectInstances.get(id);
if (typeof dc !== 'undefined') {
return dc;
}

const newInstance = new DataConnect(connectorConfig, this.appInternal);
this.dataConnectInstances.set(id, newInstance);
return newInstance;
}

/**
* Returns the app associated with this `DataConnect` instance.
*
* @returns The app associated with this `DataConnect` instance.
*/
get app(): App {
return this.appInternal;
}
}

/**
* The Firebase `DataConnect` service interface.
*/
Expand All @@ -33,12 +65,13 @@ export class DataConnect {
private readonly client: DataConnectApiClient;

/**
* @param connectorConfig - Connector Config
* @param app - The app for this `DataConnect` service.
* @constructor
* @internal
*/
constructor(readonly app: App) {
this.client = new DataConnectApiClient(app);
constructor(readonly connectorConfig: ConnectorConfig, readonly app: App) {
this.client = new DataConnectApiClient(connectorConfig, app);
}

/**
Expand Down
12 changes: 8 additions & 4 deletions src/data-connect/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,13 @@

import { App, getApp } from '../app';
import { FirebaseApp } from '../app/firebase-app';
import { DataConnect } from './data-connect';
import { DataConnect, DataConnectService } from './data-connect';
import { ConnectorConfig } from './data-connect-api';

export {
GraphqlOptions,
ExecuteGraphqlResponse,
GraphqlReadOptions,
ConnectorConfig,
} from './data-connect-api'
export {
DataConnect,
Expand All @@ -53,18 +54,21 @@ export {
* // Get the `DataConnect` service for a given app
* const otherDataConnect = getDataConnect(otherApp);
* ```
*
* @param connectorConfig - Connector Config
*
* @param app - Optional app for which to return the `DataConnect` service.
* If not provided, the default `DataConnect` service is returned.
*
* @returns The default `DataConnect` service if no app is provided, or the `DataConnect`
* service associated with the provided app.
*/
export function getDataConnect(app?: App): DataConnect {
export function getDataConnect(connectorConfig: ConnectorConfig, app?: App): DataConnect {
if (typeof app === 'undefined') {
app = getApp();
}

const firebaseApp: FirebaseApp = app as FirebaseApp;
return firebaseApp.getOrInitService('dataConnect', (app) => new DataConnect(app));
const dataConnectService = firebaseApp.getOrInitService('dataConnect', (app) => new DataConnectService(app));
return dataConnectService.getDataConnect(connectorConfig);
}
20 changes: 14 additions & 6 deletions test/integration/data-connect.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@

import * as chai from 'chai';
import * as chaiAsPromised from 'chai-as-promised';
import { getDataConnect } from '../../lib/data-connect/index';
import { getDataConnect, ConnectorConfig } from '../../lib/data-connect/index';

chai.should();
chai.use(chaiAsPromised);

//const expect = chai.expect;
const expect = chai.expect;

interface UserResponse {
users: [
Expand All @@ -37,16 +37,24 @@ interface UserVariables {
id: string;
}

const connectorConfig: ConnectorConfig = {
location: 'us-west2',
serviceId: 'my-service',
};

describe('getDataConnect()', () => {

const query = 'query ListUsers @auth(level: PUBLIC) { users { uid, name, address } }';

//const mutation = 'mutation user { user_insert(data: {uid: "QVBJcy5ndXJ2", address: "Address", name: "Name"}) }'

describe('executeGraphql()', () => {
it('successfully executes a GraphQL', async () => {
const resp = await getDataConnect().executeGraphql<UserResponse, UserVariables>(query, {});
console.dir(resp.data.users);
//expect(resp.data.user.id).to.be.not.undefined;
//expect(resp.data.user.name).to.be.not.undefined;
const resp = await getDataConnect(connectorConfig).executeGraphql<UserResponse, UserVariables>(query, {});
//console.dir(resp.data.users);
expect(resp.data.users).to.be.not.empty;
expect(resp.data.users[0].name).to.be.not.undefined;
expect(resp.data.users[0].address).to.be.not.undefined;
});
});
});
50 changes: 0 additions & 50 deletions test/integration/data-connect.ts

This file was deleted.

Loading

0 comments on commit 66e4030

Please sign in to comment.