mirror of
https://github.com/hanzoai/firebase-js-sdk.git
synced 2026-09-24 16:59:10 +00:00
* Add node engines fields specifying a minimum of 18 (#8457) * Make memory lru gc the default (#8110) * Make memory lru gc the default * undo yarn.lock * Make memory lru gc the default * Fix tests * V11 release removal of node-fetch and undici dependencies (#8492) Our v11 release will require node 18+. Since fetch has been introduced in these node versions, we can remove our dependency on third party fetch implementations. This change removes our usage of fetch variants undici and node-fetch for our node target builds and our CI tools. * V11 - Remove functions node bundle (#8507) With the removal of fetch we no long need to create a node bundle for functions. Instead the sourcebase may become isomorphic, so long as we remove the older node sources. And that's what the PR does! * Initial changes for Vertex GA packaging (#8498) * [Vertex GA] Rewrite Schema (#8479) * [Vertex GA] Add new endpoint and error message. (#8497) * [Vertex GA] Miscellaneous breaking changes for Vertex GA (#8514) * Remove ES5 Support (#8509) * Emit a module package file for functions ESM builds (#8517) * Update API_NOT_ENABLED error for Vertex (#8549) * Upgrade cjs bundles for storage and performance (#8557) These should have been part of the bigger PR, but I missed these. * Rollup JS files with rollup-typescript-plugin (#8503) The rollup-typescript-plugin does not transpile JS files using the TS compiler by default. This means that external dependencies that provide JS bundles will not be transpiled to the target ES version specified in the TypeScript config used by the plugin. This resulted in one of our dependencies (https://github.com/jakearchibald/idb) being included in the CDN bundles without being transpiled to ES5 (the target ES version). Since this dependencies bundle uses ES2018 syntax (object spread operator `{ ...x }`), this upgraded our CDN bundles' minimum ES version requirement to ES2018 which isn't compatible with older browser versions. To see the ES2018 syntax in one of the CDN bundles, see https://www.gstatic.com/firebasejs/10.13.1/firebase-app.js and search for `...oldTraps`. * Fix tsc errors in vertex tests (#8562) * Make SafetySettings.method optional (#8567) * Make SafetySettings.method optional * Update API reports --------- Co-authored-by: hsubox76 <[email protected]> * [Vertex GA] Regenerate docs after Vertex GA changes (#8505) * Close emulator file after download is complete (#8572) * close file * Add test:ci to end of test command in CI * revert workflow file changes * format * rename vertexai package reference in a changeset (#8573) * Missed one doc change from a PR (#8575) * Overwrite undefined candidate index (#8577) * Overwrite undefined candidate index * Fix index overwrite condition to only be true when index is not a property * Upgrade Vertex Mock Responses to V5 (#8579) * Upgrade to mock responses v4 * Upgrade from v4 to v5 mock responses --------- Co-authored-by: wu-hui <[email protected]> Co-authored-by: DellaBitta <[email protected]> Co-authored-by: Daniel La Rocque <[email protected]> Co-authored-by: hsubox76 <[email protected]>
338 lines
11 KiB
TypeScript
338 lines
11 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright 2021 Google LLC
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
import { expect } from 'chai';
|
|
import * as sinon from 'sinon';
|
|
import {
|
|
discoverEmulators,
|
|
EMULATOR_HOST_ENV_VARS,
|
|
getEmulatorHostAndPort
|
|
} from '../../src/impl/discovery';
|
|
import { HostAndPort } from '../../src/public_types';
|
|
import { restoreEnvVars, stashEnvVars } from '../test_utils';
|
|
|
|
describe('discoverEmulators()', () => {
|
|
it('finds all running emulators', async () => {
|
|
const emulators = await discoverEmulators(getEmulatorHostAndPort('hub')!);
|
|
|
|
expect(emulators).to.deep.equal({
|
|
database: {
|
|
host: '127.0.0.1',
|
|
port: 9002
|
|
},
|
|
firestore: {
|
|
host: '127.0.0.1',
|
|
port: 9003
|
|
},
|
|
storage: {
|
|
host: '127.0.0.1',
|
|
port: 9199
|
|
},
|
|
hub: {
|
|
host: '127.0.0.1',
|
|
port: 4400
|
|
}
|
|
});
|
|
});
|
|
|
|
it('connect to IPv6 addresses correctly', async () => {
|
|
const fetch = sinon.fake(async () => {
|
|
return {
|
|
ok: true,
|
|
async json() {
|
|
return {};
|
|
}
|
|
};
|
|
});
|
|
const emulators = await discoverEmulators(
|
|
{ host: '::1', port: 1111 },
|
|
fetch as any
|
|
);
|
|
|
|
expect(fetch).to.be.calledOnceWith(new URL('http://[::1]:1111/emulators')); // bracketed
|
|
expect(emulators).to.deep.equal({});
|
|
});
|
|
|
|
it('throws error if emulator hub is unreachable', async () => {
|
|
// Connect to port:0. Should always fail (although error codes may differ among OSes).
|
|
await expect(
|
|
discoverEmulators({ host: '127.0.0.1', port: 0 })
|
|
).to.be.rejectedWith(/EADDRNOTAVAIL|ECONNREFUSED|fetch failed/);
|
|
});
|
|
|
|
it('throws if response status is not 2xx', async () => {
|
|
const fetch = sinon.fake(async () => {
|
|
return {
|
|
ok: false,
|
|
status: 666,
|
|
async json() {
|
|
return {};
|
|
}
|
|
};
|
|
});
|
|
|
|
await expect(
|
|
discoverEmulators({ host: '127.0.0.1', port: 4444 }, fetch as any)
|
|
).to.be.rejectedWith(/HTTP Error 666/);
|
|
});
|
|
});
|
|
|
|
describe('getEmulatorHostAndPort()', () => {
|
|
context('without env vars', () => {
|
|
beforeEach(() => {
|
|
stashEnvVars();
|
|
});
|
|
afterEach(() => {
|
|
restoreEnvVars();
|
|
});
|
|
|
|
it('returns undefined if config option is not set', async () => {
|
|
const result = getEmulatorHostAndPort('hub');
|
|
|
|
expect(result).to.be.undefined;
|
|
});
|
|
|
|
it('returns undefined if config option does not contain host/port', async () => {
|
|
const result = getEmulatorHostAndPort('hub', {
|
|
rules: '/* security rules only, no host/port */'
|
|
});
|
|
|
|
expect(result).to.be.undefined;
|
|
});
|
|
|
|
it('removes brackets from IPv6 hosts', async () => {
|
|
const result = getEmulatorHostAndPort('hub', {
|
|
host: '[::1]',
|
|
port: 1111
|
|
});
|
|
|
|
expect(result?.host).to.equal('::1');
|
|
});
|
|
|
|
it('throws if only host is present', async () => {
|
|
expect(() =>
|
|
getEmulatorHostAndPort('hub', {
|
|
host: '[::1]'
|
|
} as HostAndPort)
|
|
).to.throw(/hub.port=undefined/);
|
|
});
|
|
|
|
it('throws if only port is present', async () => {
|
|
expect(() =>
|
|
getEmulatorHostAndPort('database', {
|
|
port: 1234
|
|
} as HostAndPort)
|
|
).to.throw(/Invalid configuration database.host=undefined/);
|
|
});
|
|
|
|
it('connect to 127.0.0.1 if host is wildcard 0.0.0.0', async () => {
|
|
const result = getEmulatorHostAndPort('hub', {
|
|
host: '0.0.0.0',
|
|
port: 1111
|
|
});
|
|
|
|
// Do not connect to 0.0.0.0 which is invalid and won't work on some OSes.
|
|
expect(result?.host).to.equal('127.0.0.1');
|
|
});
|
|
|
|
it('connect to [::1] if host is wildcard [::]', async () => {
|
|
const result = getEmulatorHostAndPort('hub', { host: '::1', port: 1111 });
|
|
|
|
// Do not connect to :: which is invalid and won't work on some OSes.
|
|
expect(result?.host).to.equal('::1');
|
|
});
|
|
|
|
it('uses discovered host/port if both config and env var are unset', async () => {
|
|
const result = getEmulatorHostAndPort('hub', undefined, {
|
|
hub: { host: '::1', port: 3333 }
|
|
});
|
|
|
|
expect(result?.host).to.equal('::1');
|
|
expect(result?.port).to.equal(3333);
|
|
});
|
|
|
|
it('returns undefined if none of config, env var, discovered contains emulator', async () => {
|
|
const result = getEmulatorHostAndPort('database', undefined, {
|
|
hub: { host: '::1', port: 3333 } /* only hub, no database */
|
|
});
|
|
|
|
expect(result).to.be.undefined;
|
|
});
|
|
|
|
it('uses hub host as fallback if discovered host is wildcard 0.0.0.0/[::]', async () => {
|
|
const result = getEmulatorHostAndPort('database', undefined, {
|
|
database: { host: '0.0.0.0', port: 1111 },
|
|
hub: { host: '10.0.0.1', port: 3333 }
|
|
});
|
|
|
|
// If we can reach hub via 10.0.0.1 but database has host 0.0.0.0, it is very likely that
|
|
// database is also running on 10.0.0.1 and listening on all IPv4 addresses.
|
|
expect(result?.host).to.equal('10.0.0.1');
|
|
expect(result?.port).to.equal(1111);
|
|
|
|
const result2 = getEmulatorHostAndPort('database', undefined, {
|
|
database: { host: '::', port: 2222 },
|
|
hub: { host: '10.0.0.1', port: 3333 }
|
|
});
|
|
|
|
// The situation is less ideal when database listens on all IPv6 addresses, but we'll still
|
|
// try the same host as hub, hoping that the OS running database forwards v6 to v4.
|
|
expect(result2?.host).to.equal('10.0.0.1');
|
|
expect(result2?.port).to.equal(2222);
|
|
});
|
|
|
|
it('uses hub host as fallback if config host is wildcard 0.0.0.0/[::]', async () => {
|
|
// We apply the same logic to manually specified {host: '0.0.0.0'}, although it is a bit
|
|
// unclear what the developer actually means in that case. If we get this wrong though, the
|
|
// developer can always manually specify a non-wildcard address instead.
|
|
const discovered = {
|
|
hub: { host: '10.0.0.1', port: 3333 }
|
|
};
|
|
const result = getEmulatorHostAndPort(
|
|
'database',
|
|
{
|
|
host: '0.0.0.0',
|
|
port: 1111
|
|
},
|
|
discovered
|
|
);
|
|
|
|
expect(result?.host).to.equal('10.0.0.1');
|
|
expect(result?.port).to.equal(1111);
|
|
|
|
const result2 = getEmulatorHostAndPort(
|
|
'database',
|
|
{
|
|
host: '[::]',
|
|
port: 2222
|
|
},
|
|
discovered
|
|
);
|
|
|
|
expect(result2?.host).to.equal('10.0.0.1');
|
|
expect(result2?.port).to.equal(2222);
|
|
});
|
|
});
|
|
|
|
context('with env vars', () => {
|
|
beforeEach(() => {
|
|
stashEnvVars();
|
|
});
|
|
afterEach(() => {
|
|
restoreEnvVars();
|
|
});
|
|
|
|
it('parses IPv4 host + port correctly from env var', async () => {
|
|
process.env[EMULATOR_HOST_ENV_VARS.hub] = '127.0.0.1:3445';
|
|
const result = getEmulatorHostAndPort('hub');
|
|
|
|
expect(result?.host).to.equal('127.0.0.1');
|
|
expect(result?.port).to.equal(3445);
|
|
});
|
|
|
|
it('throws if port is not a number', async () => {
|
|
process.env[EMULATOR_HOST_ENV_VARS.hub] = '127.0.0.1:hhh';
|
|
expect(() => getEmulatorHostAndPort('hub')).to.throw(
|
|
/Invalid format in environment variable FIREBASE_EMULATOR_HUB/
|
|
);
|
|
});
|
|
|
|
it('parses IPv6 host + port correctly from env var and removes brackets', async () => {
|
|
process.env[EMULATOR_HOST_ENV_VARS.hub] = '[::1]:3445';
|
|
const result = getEmulatorHostAndPort('hub');
|
|
|
|
expect(result?.host).to.equal('::1');
|
|
expect(result?.port).to.equal(3445);
|
|
});
|
|
|
|
it('parses env var with IPv6 host but no port correctly', async () => {
|
|
process.env[EMULATOR_HOST_ENV_VARS.hub] = '[::1]';
|
|
const result = getEmulatorHostAndPort('hub');
|
|
|
|
expect(result?.host).to.equal('::1');
|
|
expect(result?.port).to.equal(80); // default port
|
|
});
|
|
|
|
it('parses env var with host but no port correctly', async () => {
|
|
process.env[EMULATOR_HOST_ENV_VARS.hub] = 'myhub.example.com';
|
|
const result = getEmulatorHostAndPort('hub');
|
|
|
|
expect(result?.host).to.equal('myhub.example.com');
|
|
expect(result?.port).to.equal(80); // default port
|
|
});
|
|
|
|
it('connect to 127.0.0.1 if host is wildcard 0.0.0.0', async () => {
|
|
process.env[EMULATOR_HOST_ENV_VARS.hub] = '0.0.0.0:3445';
|
|
const result = getEmulatorHostAndPort('hub');
|
|
|
|
// Do not connect to 0.0.0.0 which is invalid and won't work on some OSes.
|
|
expect(result?.host).to.equal('127.0.0.1');
|
|
});
|
|
|
|
it('connect to [::1] if host is wildcard [::]', async () => {
|
|
process.env[EMULATOR_HOST_ENV_VARS.hub] = '[::]:3445';
|
|
const result = getEmulatorHostAndPort('hub');
|
|
|
|
// Do not connect to :: which is invalid and won't work on some OSes.
|
|
expect(result?.host).to.equal('::1');
|
|
});
|
|
|
|
it('prefers config value over env var', async () => {
|
|
process.env[EMULATOR_HOST_ENV_VARS.hub] = '127.0.0.1:3445'; // ignored
|
|
const result = getEmulatorHostAndPort('hub', {
|
|
host: 'localhost',
|
|
port: 1234
|
|
});
|
|
|
|
expect(result?.host).to.equal('localhost');
|
|
expect(result?.port).to.equal(1234);
|
|
});
|
|
|
|
it('takes host and port from env var if config has no host/port', async () => {
|
|
process.env[EMULATOR_HOST_ENV_VARS.hub] = '127.0.0.1:3445';
|
|
const result = getEmulatorHostAndPort('hub', {
|
|
rules: '/* security rules only, no host/port */'
|
|
});
|
|
|
|
expect(result?.host).to.equal('127.0.0.1');
|
|
expect(result?.port).to.equal(3445);
|
|
});
|
|
|
|
it('uses hub host as fallback if host from env var is wildcard 0.0.0.0/[::]', async () => {
|
|
process.env[EMULATOR_HOST_ENV_VARS.database] = '0.0.0.0:1111';
|
|
const result = getEmulatorHostAndPort('database', undefined, {
|
|
hub: { host: '10.0.0.1', port: 3333 }
|
|
});
|
|
|
|
// If we can reach hub via 10.0.0.1 but database has host 0.0.0.0, it is very likely that
|
|
// database is also running on 10.0.0.1 and listening on all IPv4 addresses.
|
|
expect(result?.host).to.equal('10.0.0.1');
|
|
expect(result?.port).to.equal(1111);
|
|
|
|
process.env[EMULATOR_HOST_ENV_VARS.database] = '[::]:2222';
|
|
const result2 = getEmulatorHostAndPort('database', undefined, {
|
|
hub: { host: '10.0.0.1', port: 3333 }
|
|
});
|
|
|
|
// The situation is less ideal when database listens on all IPv6 addresses, but we'll still
|
|
// try the same host as hub, hoping that the OS running database forwards v6 to v4.
|
|
expect(result2?.host).to.equal('10.0.0.1');
|
|
expect(result2?.port).to.equal(2222);
|
|
});
|
|
});
|
|
});
|