diff --git a/common/api-review/data-connect.api.md b/common/api-review/data-connect.api.md index 8f133312868..ae9db6ae19c 100644 --- a/common/api-review/data-connect.api.md +++ b/common/api-review/data-connect.api.md @@ -46,7 +46,7 @@ export interface ConnectorConfig { // @public (undocumented) export class DataConnect { - constructor(app: FirebaseApp, dataConnectOptions: DataConnectOptions, authProvider: Provider); + constructor(app: FirebaseApp, dataConnectOptions: DataConnectOptions, _authProvider: Provider); // (undocumented) readonly app: FirebaseApp; // (undocumented) @@ -59,7 +59,7 @@ export class DataConnect { isEmulator: boolean; // (undocumented) setInitialized(): void; - } +} // @public (undocumented) export interface DataConnectOptions extends ConnectorConfig { @@ -115,7 +115,7 @@ export const FIREBASE_DATA_CONNECT_EMULATOR_HOST_VAR = "FIREBASE_DATA_CONNECT_EM // @public (undocumented) export class FirebaseAuthProvider implements AuthTokenProvider { - constructor(appName: string, options: FirebaseOptions, authProvider_: Provider); + constructor(_appName: string, _options: FirebaseOptions, _authProvider: Provider); // (undocumented) addTokenChangeListener(listener: AuthTokenListener): void; // (undocumented) @@ -130,28 +130,31 @@ export function getDataConnect(options: ConnectorConfig): DataConnect; // @public (undocumented) export function getDataConnect(app: FirebaseApp, options: ConnectorConfig): DataConnect; +// @public (undocumented) +export const MUTATION_STR = "mutation"; + // @public (undocumented) export class MutationManager { - constructor(transport: DataConnectTransport); + constructor(_transport: DataConnectTransport); // (undocumented) - executeMutation(mutationRef: MutationRef): MutationPromise; - } + executeMutation(mutationRef: MutationRef): MutationPromise; +} // @public (undocumented) export interface MutationPromise extends PromiseLike> { } // @public (undocumented) -export interface MutationRef extends OperationRef { +export interface MutationRef extends OperationRef { // (undocumented) - refType: typeof MutationStr; + refType: typeof MUTATION_STR; } // @public (undocumented) -export function mutationRef(dcInstance: DataConnect, queryName: string): MutationRef; +export function mutationRef(dcInstance: DataConnect, queryName: string): MutationRef; // @public (undocumented) -export function mutationRef(dcInstance: DataConnect, queryName: string, variables: Variables): MutationRef; +export function mutationRef(dcInstance: DataConnect, mutationName: string, variables: Variables): MutationRef; // @public (undocumented) export interface MutationResponse extends CancellableOperation { @@ -163,9 +166,6 @@ export interface MutationResult extends DataConnectResult; } -// @public (undocumented) -export const MutationStr = "mutation"; - // @public (undocumented) export type OnCompleteSubscription = () => void; @@ -198,16 +198,7 @@ export interface OpResult { } // @public (undocumented) -export interface ProjectOptions { - // (undocumented) - connector: string; - // (undocumented) - location: string; - // (undocumented) - projectId: string; - // (undocumented) - service: string; -} +export const QUERY_STR = "query"; // @public (undocumented) export interface QueryPromise extends PromiseLike> { @@ -216,7 +207,7 @@ export interface QueryPromise extends PromiseLike extends OperationRef { // (undocumented) - refType: typeof QueryStr; + refType: typeof QUERY_STR; } // @public (undocumented) @@ -237,14 +228,11 @@ export interface QueryResult extends DataConnectResult SerializedRef; } -// @public (undocumented) -export const QueryStr = "query"; - // @public (undocumented) export type QueryUnsubscribe = () => void; // @public (undocumented) -export type ReferenceType = typeof QueryStr | typeof MutationStr; +export type ReferenceType = typeof QUERY_STR | typeof MUTATION_STR; // @public (undocumented) export interface RefInfo { @@ -296,7 +284,7 @@ export interface SubscriptionOptions { } // @public (undocumented) -export function terminate(dataConnect: DataConnect): void; +export function terminate(dataConnect: DataConnect): Promise; // @public (undocumented) export function toQueryRef(serializedRef: SerializedRef): QueryRef; diff --git a/packages/data-connect/package.json b/packages/data-connect/package.json index b15f343e6f8..aa06a74c23f 100644 --- a/packages/data-connect/package.json +++ b/packages/data-connect/package.json @@ -33,7 +33,7 @@ "prettier": "prettier --write '*.js' '*.ts' '@(src|test)/**/*.ts'", "build:deps": "lerna run --scope @firebase/'{app,data-connect}' --include-dependencies build", "dev": "rollup -c -w", - "test": "run-p --npm-path npm lint test:emulator", + "test": "run-p --npm-path npm test:emulator", "test:ci": "node ../../scripts/run_tests_in_ci.js -s test:emulator", "test:all": "npm run test:node", "test:browser": "karma start --single-run", diff --git a/packages/data-connect/src/api.browser.ts b/packages/data-connect/src/api.browser.ts index 1e0bc61399b..a1547eabd7d 100644 --- a/packages/data-connect/src/api.browser.ts +++ b/packages/data-connect/src/api.browser.ts @@ -63,7 +63,7 @@ export function subscribe( let ref: QueryRef; let initialCache: OpResult | undefined; if ('refInfo' in queryRefOrSerializedResult) { - let serializedRef: SerializedRef = + const serializedRef: SerializedRef = queryRefOrSerializedResult; const { data, source, fetchTime } = serializedRef; initialCache = { diff --git a/packages/data-connect/src/api/DataConnect.ts b/packages/data-connect/src/api/DataConnect.ts index ff3a6c3d2ee..60347758880 100644 --- a/packages/data-connect/src/api/DataConnect.ts +++ b/packages/data-connect/src/api/DataConnect.ts @@ -24,24 +24,18 @@ import { import { FirebaseAuthInternalName } from '@firebase/auth-interop-types'; import { Provider } from '@firebase/component'; +import { Code, DataConnectError } from '../core/error'; import { AuthTokenProvider, FirebaseAuthProvider } from '../core/FirebaseAuthProvider'; import { QueryManager } from '../core/QueryManager'; +import { logDebug, logError } from '../logger'; import { DataConnectTransport, TransportClass } from '../network'; import { RESTTransport } from '../network/transport/rest'; import { MutationManager } from './Mutation'; -import { Code, DataConnectError } from '../core/error'; -import { logDebug, logError } from '../logger'; -export interface ProjectOptions { - location: string; - connector: string; - service: string; - projectId: string; -} export interface ConnectorConfig { location: string; @@ -78,27 +72,28 @@ export interface DataConnectOptions extends ConnectorConfig { export class DataConnect { _queryManager!: QueryManager; _mutationManager!: MutationManager; - public isEmulator = false; + isEmulator = false; initialized = false; private _transport!: DataConnectTransport; - private transportClass: TransportClass | undefined; - private transportOptions?: TransportOptions; - private authTokenProvider?: AuthTokenProvider; + private _transportClass: TransportClass | undefined; + private _transportOptions?: TransportOptions; + private _authTokenProvider?: AuthTokenProvider; constructor( public readonly app: FirebaseApp, + // TODO(mtewani): Replace with _dataConnectOptions in the future private readonly dataConnectOptions: DataConnectOptions, - private readonly authProvider: Provider + private readonly _authProvider: Provider ) { if (typeof process !== 'undefined' && process.env) { const host = process.env[FIREBASE_DATA_CONNECT_EMULATOR_HOST_VAR]; if (host) { logDebug('Found custom host. Using emulator'); this.isEmulator = true; - this.transportOptions = parseOptions(host); + this._transportOptions = parseOptions(host); } } } - _delete() { + _delete(): Promise { _removeServiceInstance( this.app, 'data-connect', @@ -113,49 +108,49 @@ export class DataConnect { return copy; } - setInitialized() { + setInitialized(): void { if (this.initialized) { return; } - if (this.transportClass === undefined) { + if (this._transportClass === undefined) { logDebug('transportClass not provided. Defaulting to RESTTransport.'); - this.transportClass = RESTTransport; + this._transportClass = RESTTransport; } - if (this.authProvider) { - this.authTokenProvider = new FirebaseAuthProvider( + if (this._authProvider) { + this._authTokenProvider = new FirebaseAuthProvider( this.app.name, this.app.options, - this.authProvider + this._authProvider ); } this.initialized = true; - this._transport = new this.transportClass( + this._transport = new this._transportClass( this.dataConnectOptions, this.app.options.apiKey, - this.authTokenProvider + this._authTokenProvider ); - if (this.transportOptions) { + if (this._transportOptions) { this._transport.useEmulator( - this.transportOptions.host, - this.transportOptions.port, - this.transportOptions.sslEnabled + this._transportOptions.host, + this._transportOptions.port, + this._transportOptions.sslEnabled ); } this._queryManager = new QueryManager(this._transport); this._mutationManager = new MutationManager(this._transport); } - enableEmulator(transportOptions: TransportOptions) { + enableEmulator(transportOptions: TransportOptions): void { if (this.initialized) { - logError('enableEmulator called without initializing'); + logError('enableEmulator called after initialization'); throw new DataConnectError( Code.ALREADY_INITIALIZED, 'DataConnect instance already initialized!' ); } - this.transportOptions = transportOptions; + this._transportOptions = transportOptions; this.isEmulator = true; } } @@ -165,7 +160,7 @@ export function connectDataConnectEmulator( host: string, port?: number, sslEnabled = false -) { +): void { dc.enableEmulator({ host, port, sslEnabled }); } @@ -213,7 +208,7 @@ export function getDataConnect( }); } -export function terminate(dataConnect: DataConnect) { - dataConnect._delete(); +export function terminate(dataConnect: DataConnect): Promise { + return dataConnect._delete(); // TODO(mtewani): Stop pending tasks } diff --git a/packages/data-connect/src/api/Mutation.ts b/packages/data-connect/src/api/Mutation.ts index 4a9a6db4a94..21f4e49d49c 100644 --- a/packages/data-connect/src/api/Mutation.ts +++ b/packages/data-connect/src/api/Mutation.ts @@ -20,35 +20,35 @@ import { DataConnectTransport } from '../network/transport'; import { DataConnect } from './DataConnect'; import { DataConnectResult, - MutationStr, + MUTATION_STR, OperationRef, SOURCE_SERVER } from './Reference'; -export interface MutationRef - extends OperationRef { - refType: typeof MutationStr; +export interface MutationRef + extends OperationRef { + refType: typeof MUTATION_STR; } -export function mutationRef( +export function mutationRef( dcInstance: DataConnect, queryName: string -): MutationRef; -export function mutationRef( +): MutationRef; +export function mutationRef( dcInstance: DataConnect, - queryName: string, + mutationName: string, variables: Variables -): MutationRef; -export function mutationRef( +): MutationRef; +export function mutationRef( dcInstance: DataConnect, queryName: string, variables?: Variables -): MutationRef { +): MutationRef { dcInstance.setInitialized(); - const ref: MutationRef = { + const ref: MutationRef = { dataConnect: dcInstance, name: queryName, - refType: MutationStr, + refType: MUTATION_STR, variables: variables as Variables }; return ref; @@ -56,16 +56,16 @@ export function mutationRef( export class MutationManager { private _inflight: Array> = []; - constructor(private transport: DataConnectTransport) {} - executeMutation( - mutationRef: MutationRef - ): MutationPromise { - const result = this.transport.invokeMutation( + constructor(private _transport: DataConnectTransport) {} + executeMutation( + mutationRef: MutationRef + ): MutationPromise { + const result = this._transport.invokeMutation( mutationRef.name, mutationRef.variables ); const withRefPromise = result.then(res => { - const obj: MutationResult = { + const obj: MutationResult = { ...res, // Double check that the result is result.data, not just result source: SOURCE_SERVER, ref: mutationRef, diff --git a/packages/data-connect/src/api/Reference.ts b/packages/data-connect/src/api/Reference.ts index e0a0e510c6e..10550e82682 100644 --- a/packages/data-connect/src/api/Reference.ts +++ b/packages/data-connect/src/api/Reference.ts @@ -16,9 +16,9 @@ */ import { DataConnect, DataConnectOptions } from './DataConnect'; -export const QueryStr = 'query'; -export const MutationStr = 'mutation'; -export type ReferenceType = typeof QueryStr | typeof MutationStr; +export const QUERY_STR = 'query'; +export const MUTATION_STR = 'mutation'; +export type ReferenceType = typeof QUERY_STR | typeof MUTATION_STR; export const SOURCE_SERVER = 'SERVER'; export const SOURCE_CACHE = 'CACHE'; diff --git a/packages/data-connect/src/api/query.ts b/packages/data-connect/src/api/query.ts index f68d30426ac..c84aa283f13 100644 --- a/packages/data-connect/src/api/query.ts +++ b/packages/data-connect/src/api/query.ts @@ -16,10 +16,11 @@ */ import { DataConnectError } from '../core/error'; + import { DataConnect, getDataConnect } from './DataConnect'; import { OperationRef, - QueryStr, + QUERY_STR, DataConnectResult, SerializedRef } from './Reference'; @@ -36,7 +37,7 @@ export interface DataConnectSubscription { } export interface QueryRef extends OperationRef { - refType: typeof QueryStr; + refType: typeof QUERY_STR; } export interface QueryResult extends DataConnectResult { @@ -73,7 +74,7 @@ export function queryRef( dcInstance._queryManager.track(queryName, variables, initialCache); return { dataConnect: dcInstance, - refType: QueryStr, + refType: QUERY_STR, name: queryName, variables: variables as Variables }; diff --git a/packages/data-connect/src/core/FirebaseAuthProvider.ts b/packages/data-connect/src/core/FirebaseAuthProvider.ts index 92d14009329..e74e6581388 100644 --- a/packages/data-connect/src/core/FirebaseAuthProvider.ts +++ b/packages/data-connect/src/core/FirebaseAuthProvider.ts @@ -22,6 +22,7 @@ import { FirebaseAuthTokenData } from '@firebase/auth-interop-types'; import { Provider } from '@firebase/component'; + import { logDebug, logError } from '../logger'; export interface AuthTokenProvider { @@ -31,22 +32,22 @@ export interface AuthTokenProvider { export type AuthTokenListener = (token: string | null) => void; export class FirebaseAuthProvider implements AuthTokenProvider { - private auth_: FirebaseAuthInternal; + private _auth: FirebaseAuthInternal; constructor( - private appName: string, - private options: FirebaseOptions, - private authProvider_: Provider + private _appName: string, + private _options: FirebaseOptions, + private _authProvider: Provider ) { - this.auth_ = authProvider_.getImmediate({ optional: true })!; - if (!this.auth_) { - authProvider_.onInit(auth => (this.auth_ = auth)); + this._auth = _authProvider.getImmediate({ optional: true })!; + if (!this._auth) { + _authProvider.onInit(auth => (this._auth = auth)); } } getToken(forceRefresh: boolean): Promise { - if (!this.auth_) { + if (!this._auth) { return new Promise((resolve, reject) => { setTimeout(() => { - if (this.auth_) { + if (this._auth) { this.getToken(forceRefresh).then(resolve, reject); } else { resolve(null); @@ -54,7 +55,7 @@ export class FirebaseAuthProvider implements AuthTokenProvider { }, 0); }); } - return this.auth_.getToken(forceRefresh).catch(error => { + return this._auth.getToken(forceRefresh).catch(error => { if (error && error.code === 'auth/token-not-initialized') { logDebug( 'Got auth/token-not-initialized error. Treating as null token.' @@ -69,11 +70,11 @@ export class FirebaseAuthProvider implements AuthTokenProvider { } }); } - addTokenChangeListener(listener: AuthTokenListener) { - this.auth_?.addAuthTokenListener(listener); + addTokenChangeListener(listener: AuthTokenListener): void { + this._auth?.addAuthTokenListener(listener); } removeTokenChangeListener(listener: (token: string | null) => void): void { - this.authProvider_ + this._authProvider .get() .then(auth => auth.removeAuthTokenListener(listener)); } diff --git a/packages/data-connect/src/core/QueryManager.ts b/packages/data-connect/src/core/QueryManager.ts index 6cb5645924f..6df1a4f9a42 100644 --- a/packages/data-connect/src/core/QueryManager.ts +++ b/packages/data-connect/src/core/QueryManager.ts @@ -25,7 +25,7 @@ import { } from '../api/query'; import { OperationRef, - QueryStr, + QUERY_STR, OpResult, SerializedRef, SOURCE_SERVER, @@ -36,12 +36,13 @@ import { logDebug } from '../logger'; import { DataConnectTransport } from '../network'; import { encoderImpl } from '../util/encoder'; import { setIfNotExists } from '../util/map'; + import { DataConnectError } from './error'; -interface TrackedQuery { - ref: Omit, 'dataConnect'>; - subscriptions: Array>; - currentCache: OpResult | null; +interface TrackedQuery { + ref: Omit, 'dataConnect'>; + subscriptions: Array>; + currentCache: OpResult | null; lastError: DataConnectError | null; } @@ -72,18 +73,18 @@ export class QueryManager { constructor(private transport: DataConnectTransport) { this._queries = new Map(); } - track( + track( queryName: string, variables: Variables, - initialCache?: OpResult + initialCache?: OpResult ) { - const ref: TrackedQuery['ref'] = { + const ref: TrackedQuery['ref'] = { name: queryName, variables, - refType: QueryStr + refType: QUERY_STR }; const key = encoderImpl(ref); - const newTrackedQuery: TrackedQuery = { + const newTrackedQuery: TrackedQuery = { ref, subscriptions: [], currentCache: initialCache || null, @@ -93,19 +94,19 @@ export class QueryManager { setIfNotExists(this._queries, key, newTrackedQuery); return this._queries.get(key); } - addSubscription( - queryRef: OperationRef, - onResultCallback: OnResultSubscription, + addSubscription( + queryRef: OperationRef, + onResultCallback: OnResultSubscription, onErrorCallback?: OnErrorSubscription, - initialCache?: OpResult - ) { + initialCache?: OpResult + ): () => void { const key = encoderImpl({ name: queryRef.name, variables: queryRef.variables, - refType: QueryStr + refType: QUERY_STR }); const trackedQuery = this._queries.get(key) as TrackedQuery< - Response, + Data, Variables >; const subscription = { @@ -136,9 +137,9 @@ export class QueryManager { onResultCallback({ data: cachedData, source: SOURCE_CACHE, - ref: queryRef as QueryRef, + ref: queryRef as QueryRef, toJSON: getRefSerializer( - queryRef as QueryRef, + queryRef as QueryRef, trackedQuery.currentCache.data, SOURCE_CACHE ), @@ -163,30 +164,30 @@ export class QueryManager { )}. Calling executeQuery.` ); const promise = this.executeQuery( - queryRef as QueryRef + queryRef as QueryRef ); // We want to ignore the error and let subscriptions handle it promise.then(undefined, err => {}); } return unsubscribe; } - executeQuery( - queryRef: QueryRef - ): QueryPromise { + executeQuery( + queryRef: QueryRef + ): QueryPromise { const key = encoderImpl({ name: queryRef.name, variables: queryRef.variables, - refType: QueryStr + refType: QUERY_STR }); const trackedQuery = this._queries.get(key)!; - const result = this.transport.invokeQuery( + const result = this.transport.invokeQuery( queryRef.name, queryRef.variables ); const newR = result.then( res => { const fetchTime = new Date().toString(); - const result: QueryResult = { + const result: QueryResult = { ...res, source: SOURCE_SERVER, ref: queryRef, diff --git a/packages/data-connect/src/index.ts b/packages/data-connect/src/index.ts index 1b6a552d3fc..b59c6e72b0c 100644 --- a/packages/data-connect/src/index.ts +++ b/packages/data-connect/src/index.ts @@ -28,39 +28,10 @@ export * from './api'; export * from './api.browser'; registerDataConnect(); -// function sha512(str) { -// return window.crypto.subtle.encrypt() -// } -// async function encoder(object: unknown): Promise { -// const encoder = new TextEncoder(); -// const data = encoder.encode(JSON.stringify(object)); -// const hash = await crypto.subtle.digest('SHA-256', data); -// return hash; -// } -// setEncoder(encoder); + declare module '@firebase/component' { interface NameServiceMapping { 'data-connect': DataConnect; } -} -// import { getDataConnect, queryRef } from './api'; -// import { getApp } from '@firebase/app'; -// const app = getApp(); -// const dc = getDataConnect({ location: '', connector: '', serviceId: '', projectId: '' }); -// interface Response { -// name: string; -// } -// const converter: Converter = { -// fromDataConnect(input: string) { -// return { name: input }; -// }, -// fromType(input) { -// return input; -// } -// }; -// const myRef = queryRef(dc, '', converter); -// // Ref's shouldn't have access to their own cache, right? -// const a = execute(myRef); -// subscribe(myRef, (res) => { -// }) +} \ No newline at end of file diff --git a/packages/data-connect/src/logger.ts b/packages/data-connect/src/logger.ts index 5f02de2578d..523d96bf9ad 100644 --- a/packages/data-connect/src/logger.ts +++ b/packages/data-connect/src/logger.ts @@ -14,7 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { Logger, LogLevel, LogLevelString } from '@firebase/logger'; +import { Logger, LogLevelString } from '@firebase/logger'; + import { SDK_VERSION } from './core/version'; const logger = new Logger('@firebase/data-connect'); diff --git a/packages/data-connect/src/network/fetch.ts b/packages/data-connect/src/network/fetch.ts index 7a29e11bdc2..67b8169d3a0 100644 --- a/packages/data-connect/src/network/fetch.ts +++ b/packages/data-connect/src/network/fetch.ts @@ -44,6 +44,8 @@ export function dcFetch( method: 'POST', headers, signal + }).catch(err => { + throw new DataConnectError(Code.OTHER, "Failed to fetch: " + JSON.stringify(err)); }) .then(async response => { let jsonResponse = null; diff --git a/packages/data-connect/src/network/transport/rest.ts b/packages/data-connect/src/network/transport/rest.ts index 79ba5e86006..72e6eba31a7 100644 --- a/packages/data-connect/src/network/transport/rest.ts +++ b/packages/data-connect/src/network/transport/rest.ts @@ -15,7 +15,6 @@ * limitations under the License. */ -import { DataConnectTransport } from '.'; import { DataConnectOptions, TransportOptions } from '../../api/DataConnect'; import { DataConnectError, Code } from '../../core/error'; import { AuthTokenProvider } from '../../core/FirebaseAuthProvider'; @@ -23,16 +22,18 @@ import { logDebug } from '../../logger'; import { addToken, urlBuilder } from '../../util/url'; import { dcFetch } from '../fetch'; +import { DataConnectTransport } from '.'; + export class RESTTransport implements DataConnectTransport { - private host = ''; - private port: number | undefined; - private location = 'l'; - private connectorName = ''; - private secure = true; - private project = 'p'; - private serviceName: string; - private accessToken: string | null = null; - private authInitialized_ = false; + private _host = ''; + private _port: number | undefined; + private _location = 'l'; + private _connectorName = ''; + private _secure = true; + private _project = 'p'; + private _serviceName: string; + private _accessToken: string | null = null; + private _authInitialized = false; constructor( options: DataConnectOptions, private apiKey?: string | undefined, @@ -41,62 +42,62 @@ export class RESTTransport implements DataConnectTransport { ) { if (transportOptions) { if (typeof transportOptions.port === 'number') { - this.port = transportOptions.port; + this._port = transportOptions.port; } if (typeof transportOptions.sslEnabled !== 'undefined') { - this.secure = transportOptions.sslEnabled; + this._secure = transportOptions.sslEnabled; } - this.host = transportOptions.host; + this._host = transportOptions.host; } const { location, projectId: project, connector, service } = options; if (location) { - this.location = location; + this._location = location; } if (project) { - this.project = project; + this._project = project; } - this.serviceName = service; + this._serviceName = service; if (!connector) { throw new DataConnectError( Code.INVALID_ARGUMENT, 'Connector Name required!' ); } - this.connectorName = connector; + this._connectorName = connector; this.authProvider?.addTokenChangeListener(token => { logDebug(`New Token Available: ${token}`); - this.accessToken = token; + this._accessToken = token; }); } get endpointUrl(): string { return urlBuilder( { - connector: this.connectorName, - location: this.location, - projectId: this.project, - service: this.serviceName + connector: this._connectorName, + location: this._location, + projectId: this._project, + service: this._serviceName }, - { host: this.host, sslEnabled: this.secure, port: this.port } + { host: this._host, sslEnabled: this._secure, port: this._port } ); } useEmulator(host: string, port?: number, isSecure?: boolean): void { - this.host = host; + this._host = host; if (typeof port === 'number') { - this.port = port; + this._port = port; } if (typeof isSecure !== 'undefined') { - this.secure = isSecure; + this._secure = isSecure; } } onTokenChanged(newToken: string | null) { - this.accessToken = newToken; + this._accessToken = newToken; } getWithAuth() { let starterPromise: Promise = new Promise(resolve => - resolve(this.accessToken) + resolve(this._accessToken) ); - if (!this.authInitialized_) { + if (!this._authInitialized) { if (this.authProvider) { starterPromise = this.authProvider .getToken(/*forceToken=*/ false) @@ -104,8 +105,8 @@ export class RESTTransport implements DataConnectTransport { if (!data) { return null; } - this.accessToken = data.accessToken; - return this.accessToken; + this._accessToken = data.accessToken; + return this._accessToken; }); } else { starterPromise = new Promise(resolve => resolve('')); @@ -123,12 +124,12 @@ export class RESTTransport implements DataConnectTransport { return dcFetch( addToken(`${this.endpointUrl}:executeQuery`, this.apiKey), { - name: `projects/${this.project}/locations/${this.location}/services/${this.serviceName}/connectors/${this.connectorName}`, + name: `projects/${this._project}/locations/${this._location}/services/${this._serviceName}/connectors/${this._connectorName}`, operationName: queryName, variables: body } as unknown as U, // TODO(mtewani): This is a patch, fix this. abortController, - this.accessToken + this._accessToken ); }); @@ -142,12 +143,12 @@ export class RESTTransport implements DataConnectTransport { return dcFetch( addToken(`${this.endpointUrl}:executeMutation`, this.apiKey), { - name: `projects/${this.project}/locations/${this.location}/services/${this.serviceName}/connectors/${this.connectorName}`, + name: `projects/${this._project}/locations/${this._location}/services/${this._serviceName}/connectors/${this._connectorName}`, operationName: mutationName, variables: body } as unknown as U, abortController, - this.accessToken + this._accessToken ); }); diff --git a/packages/data-connect/src/util/map.ts b/packages/data-connect/src/util/map.ts index 5921365d674..a86d3aef0ef 100644 --- a/packages/data-connect/src/util/map.ts +++ b/packages/data-connect/src/util/map.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -export function setIfNotExists(map: Map, key: string, val: T) { +export function setIfNotExists(map: Map, key: string, val: T): void { if (!map.has(key)) { map.set(key, val); } diff --git a/packages/data-connect/src/util/url.ts b/packages/data-connect/src/util/url.ts index 67840475c0a..b3a8f7c2cff 100644 --- a/packages/data-connect/src/util/url.ts +++ b/packages/data-connect/src/util/url.ts @@ -15,12 +15,12 @@ * limitations under the License. */ -import { ProjectOptions, TransportOptions } from '../api/DataConnect'; +import { DataConnectOptions, TransportOptions } from '../api/DataConnect'; import { Code, DataConnectError } from '../core/error'; import { logError } from '../logger'; export function urlBuilder( - projectConfig: ProjectOptions, + projectConfig: DataConnectOptions, transportOptions: TransportOptions ) { const { connector, location, projectId: project, service } = projectConfig; diff --git a/packages/data-connect/test/emulatorSeeder.ts b/packages/data-connect/test/emulatorSeeder.ts index 6649ea166fe..edcb512b9ef 100644 --- a/packages/data-connect/test/emulatorSeeder.ts +++ b/packages/data-connect/test/emulatorSeeder.ts @@ -15,6 +15,7 @@ * limitations under the License. */ +import fs from 'fs'; import * as path from 'path'; // curl localhost:3628/setupSchema -X POST -d '{ // "service_id": "s", @@ -37,14 +38,12 @@ import * as path from 'path'; // } // } -import fs from 'fs'; -import fetch from 'node-fetch'; import { ReferenceType } from '../src'; // } -import { CONNECTOR_NAME, EMULATOR_PORT } from './util'; +import { EMULATOR_PORT } from './util'; export interface SeedInfo { type: ReferenceType; diff --git a/packages/data-connect/test/queries.test.ts b/packages/data-connect/test/queries.test.ts index e2183a426ef..fb912005356 100644 --- a/packages/data-connect/test/queries.test.ts +++ b/packages/data-connect/test/queries.test.ts @@ -15,7 +15,6 @@ * limitations under the License. */ -import { FirebaseApp } from '@firebase/app'; import { uuidv4 } from '@firebase/util'; import { expect, use } from 'chai'; import chaiAsPromised from 'chai-as-promised'; @@ -27,18 +26,16 @@ import { executeQuery, getDataConnect, mutationRef, - OnResultSubscription, QueryRef, queryRef, QueryResult, SerializedRef, subscribe, terminate -} from '../src'; +, SOURCE_CACHE, SOURCE_SERVER } from '../src'; import { setupQueries } from './emulatorSeeder'; -import { app, getConnectionConfig, initDatabase, PROJECT_ID } from './util'; -import { SOURCE_CACHE, SOURCE_SERVER } from '../src'; +import { getConnectionConfig, initDatabase, PROJECT_ID } from './util'; use(chaiAsPromised); @@ -60,7 +57,7 @@ const SEEDED_DATA = [ content: 'task 2' } ]; -function seedDatabase(instance: DataConnect) { +function seedDatabase(instance: DataConnect): Promise { // call mutation query that adds SEEDED_DATA to database return new Promise((resolve, reject) => { async function run() { @@ -95,7 +92,7 @@ describe('DataConnect Tests', async () => { }); afterEach(async () => { await deleteDatabase(dc); - terminate(dc); + await terminate(dc); }); it('Can get all posts', async () => { const taskListQuery = queryRef(dc, 'listPosts'); @@ -109,7 +106,7 @@ describe('DataConnect Tests', async () => { const promise = new Promise>( (resolve, reject) => { const unsubscribe = subscribe(taskListQuery, { - onResult: res => { + onNext: res => { unsubscribe(); resolve(res); }, @@ -164,12 +161,12 @@ describe('DataConnect Tests', async () => { }); connectDataConnectEmulator(fakeInstance, 'localhost', Number(0)); const taskListQuery = queryRef(dc, 'listPosts'); - expect(executeQuery(taskListQuery)).to.eventually.be.rejected; + expect(await executeQuery(taskListQuery)).to.eventually.be.rejectedWith('ECONNREFUSED'); }); }); async function waitForFirstEvent( query: QueryRef -) { +): Promise> { return await new Promise<{ result: QueryResult; unsubscribe: () => void; @@ -182,8 +179,8 @@ async function waitForFirstEvent( }); }); }; - let unsubscribe = subscribe(query, { - onResult, + const unsubscribe = subscribe(query, { + onNext: onResult, onErr: e => { reject({ e, unsubscribe }); } diff --git a/packages/data-connect/test/util.ts b/packages/data-connect/test/util.ts index a5c0293dcf6..cd9149ed41e 100644 --- a/packages/data-connect/test/util.ts +++ b/packages/data-connect/test/util.ts @@ -20,6 +20,7 @@ import { initializeApp } from '@firebase/app'; import { connectDataConnectEmulator, ConnectorConfig, + DataConnect, getDataConnect } from '../src'; @@ -43,7 +44,7 @@ export const app = initializeApp({ }); // Seed the database to have the proper fields to query, such as a list of tasks. -export function initDatabase() { +export function initDatabase(): DataConnect { const instance = getDataConnect(getConnectionConfig()); if (!instance.isEmulator) { connectDataConnectEmulator(instance, 'localhost', Number(EMULATOR_PORT)); diff --git a/packages/data-connect/tsconfig.json b/packages/data-connect/tsconfig.json index 198ba4b1bc5..2355409eed4 100644 --- a/packages/data-connect/tsconfig.json +++ b/packages/data-connect/tsconfig.json @@ -2,9 +2,10 @@ "extends": "../../config/tsconfig.base.json", "compilerOptions": { "outDir": "dist", - "strict": true + "strict": false }, "exclude": [ - "dist/**/*" + "dist/**/*", + "./test/**/*" ] } diff --git a/scripts/emulator-testing/emulators/dataconnect-emulator.ts b/scripts/emulator-testing/emulators/dataconnect-emulator.ts index d240f7227bf..487319e5ffd 100644 --- a/scripts/emulator-testing/emulators/dataconnect-emulator.ts +++ b/scripts/emulator-testing/emulators/dataconnect-emulator.ts @@ -17,7 +17,7 @@ import { Emulator } from './emulator'; -const DATABASE_EMULATOR_VERSION = '1.1.4'; +const DATABASE_EMULATOR_VERSION = '1.1.17'; export class DataConnectEmulator extends Emulator { // namespace: string; @@ -28,7 +28,7 @@ export class DataConnectEmulator extends Emulator { // Use locked version of emulator for test to be deterministic. // The latest version can be found from database emulator doc: // https://firebase.google.com/docs/database/security/test-rules-emulator - `https://firebasestorage.googleapis.com/v0/b/firemat-preview-drop/o/emulator%2Fdataconnect-emulator-macos-v1.1.4?alt=media&token=45a9ae02-568f-4f1e-bd2d-e841411ef221`, + `https://firebasestorage.googleapis.com/v0/b/firemat-preview-drop/o/emulator%2Fdataconnect-emulator-macos-v1.1.17?alt=media&token=c5e758bc-aaad-4be6-bd41-bcc08f3944a7`, port ); this.isJar = false;