Skip to content

FDC Parsing Improvements #8892

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
5 changes: 5 additions & 0 deletions .changeset/hip-chefs-attack.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@firebase/data-connect": patch
---

Fix issue where ipv6 addresses weren't getting parsed correctly when setting FIREBASE_DATA_CONNECT_EMULATOR_HOST
26 changes: 19 additions & 7 deletions packages/data-connect/src/api/DataConnect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ export interface ConnectorConfig {
*/
export interface TransportOptions {
host: string;
sslEnabled?: boolean;
port?: number;
sslEnabled?: boolean;
}

const FIREBASE_DATA_CONNECT_EMULATOR_HOST_VAR =
Expand All @@ -71,11 +71,22 @@ const FIREBASE_DATA_CONNECT_EMULATOR_HOST_VAR =
* @internal
*/
export function parseOptions(fullHost: string): TransportOptions {
const [protocol, hostName] = fullHost.split('://');
const isSecure = protocol === 'https';
const [host, portAsString] = hostName.split(':');
const port = Number(portAsString);
return { host, port, sslEnabled: isSecure };
const trimmedHost = fullHost.trim();
if (fullHost.includes('://')) {
const [protocol, host] = trimmedHost.split('://');
if (protocol !== 'http' && protocol !== 'https') {
throw new DataConnectError(
Code.INVALID_ARGUMENT,
`Protocol ${protocol} is not supported. Use 'http' or 'https' instead.`
);
}
const isSecure = protocol === 'https';
return { host, sslEnabled: isSecure };
}
return {
host: trimmedHost,
sslEnabled: false
};
}
/**
* DataConnectOptions including project id
Expand Down Expand Up @@ -237,7 +248,8 @@ export function connectDataConnectEmulator(
port?: number,
sslEnabled = false
): void {
dc.enableEmulator({ host, port, sslEnabled });
const hostWithPort = port ? `${host}:${port}` : host;
dc.enableEmulator({ host: hostWithPort, sslEnabled });
}

/**
Expand Down
3 changes: 0 additions & 3 deletions packages/data-connect/src/core/QueryManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,9 +221,6 @@ export class QueryManager {

return newR;
}
enableEmulator(host: string, port: number): void {
this.transport.useEmulator(host, port);
}
}
function compareDates(str1: string, str2: string): boolean {
const date1 = new Date(str1);
Expand Down
15 changes: 2 additions & 13 deletions packages/data-connect/src/util/url.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,27 +16,16 @@
*/

import { DataConnectOptions, TransportOptions } from '../api/DataConnect';
import { Code, DataConnectError } from '../core/error';
import { logError } from '../logger';

export function urlBuilder(
projectConfig: DataConnectOptions,
transportOptions: TransportOptions
): string {
const { connector, location, projectId: project, service } = projectConfig;
const { host, sslEnabled, port } = transportOptions;
const { host, sslEnabled } = transportOptions;
const protocol = sslEnabled ? 'https' : 'http';
const realHost = host || `firebasedataconnect.googleapis.com`;
let baseUrl = `${protocol}://${realHost}`;
if (typeof port === 'number') {
baseUrl += `:${port}`;
} else if (typeof port !== 'undefined') {
logError('Port type is of an invalid type');
throw new DataConnectError(
Code.INVALID_ARGUMENT,
'Incorrect type for port passed in!'
);
}
const baseUrl = `${protocol}://${realHost}`;
return `${baseUrl}/v1/projects/${project}/locations/${location}/services/${service}/connectors/${connector}`;
}
export function addToken(url: string, apiKey?: string): string {
Expand Down
47 changes: 0 additions & 47 deletions packages/data-connect/test/dataconnect/index.esm.js

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

6 changes: 0 additions & 6 deletions packages/data-connect/test/dataconnect/movies.tools.json

This file was deleted.

6 changes: 0 additions & 6 deletions packages/data-connect/test/dataconnect/test.tools.json

This file was deleted.

35 changes: 34 additions & 1 deletion packages/data-connect/test/unit/dataconnect.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import { deleteApp, initializeApp } from '@firebase/app';
import { expect } from 'chai';

import { getDataConnect } from '../../src';
import { getDataConnect, parseOptions } from '../../src';

describe('Data Connect Test', () => {
beforeEach(() => {});
Expand Down Expand Up @@ -60,4 +60,37 @@ describe('Data Connect Test', () => {
expect(dc.app.options.projectId).to.eq(projectId);
await deleteApp(customApp);
});
it('should parse env var correctly with http://', async () => {
const parsedHost = parseOptions('http://localhost');
expect(parsedHost.host).to.eq('localhost');
expect(parsedHost.sslEnabled).to.be.false;
});
it('should parse env var correctly with port', async () => {
const parsedHost = parseOptions('localhost:8080');
expect(parsedHost.host).to.eq('localhost:8080');
expect(parsedHost.sslEnabled).to.be.false;
});
it('should parse env var correctly with https://', async () => {
const parsedHost = parseOptions('https://localhost');
expect(parsedHost.host).to.eq('localhost');
expect(parsedHost.sslEnabled).to.be.true;
});
it('should parse ipv6 addresses correctly', async () => {
const host = '2001:0db8:85a3:0000:0000:8a2e:0370:7334';
const parsedHost = parseOptions(host);
expect(parsedHost.host).to.eq(host);
expect(parsedHost.sslEnabled).to.be.false;
});
it('should parse ipv6 localhost addresses correctly', async () => {
const host = '[::1]:8080';
const parsedHost = parseOptions(host);
expect(parsedHost.host).to.eq(host);
expect(parsedHost.sslEnabled).to.be.false;
});
it('should throw for non-http protocols', async () => {
const host = 'ftp://localhost';
expect(() => parseOptions(host)).to.throw(
"Protocol ftp is not supported. Use 'http' or 'https' instead."
);
});
});
Loading