Skip to content

Commit 0a91a90

Browse files
sam-gcFeiyang1
andauthored
Make node and browser entry points identical (#5318)
* Overhaul node/browser entry points so that they are identical; use rollup-plugin-alias to overwrite browser-specific features * Formatting, license * Revert bad change * Update packages-exp/auth-exp/rollup.config.shared.js Co-authored-by: Feiyang <[email protected]> * Fix popup/redirect stuff * Fix popup/redirect stuff Co-authored-by: Feiyang <[email protected]>
1 parent 5bc6afb commit 0a91a90

15 files changed

+286
-201
lines changed

packages-exp/auth-compat-exp/src/popup_redirect.test.ts

+14-3
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,15 @@ import { FirebaseApp } from '@firebase/app-compat';
2626
use(sinonChai);
2727

2828
describe('popup_redirect/CompatPopupRedirectResolver', () => {
29+
// Do not run these tests in node; in node, this resolver
30+
// is never instantiated.
31+
if (typeof window === 'undefined') {
32+
console.log(
33+
'Skipping popup/redirect resolver tests in non-browser environment'
34+
);
35+
return;
36+
}
37+
2938
let compatResolver: CompatPopupRedirectResolver;
3039
let auth: exp.AuthImpl;
3140

@@ -75,9 +84,11 @@ describe('popup_redirect/CompatPopupRedirectResolver', () => {
7584

7685
beforeEach(() => {
7786
underlyingResolver = sinon.createStubInstance(FakeResolver);
78-
((compatResolver as unknown) as {
79-
underlyingResolver: exp.PopupRedirectResolverInternal;
80-
}).underlyingResolver = underlyingResolver;
87+
(
88+
compatResolver as unknown as {
89+
underlyingResolver: exp.PopupRedirectResolverInternal;
90+
}
91+
).underlyingResolver = underlyingResolver;
8192
provider = new exp.GoogleAuthProvider();
8293
});
8394

packages-exp/auth-compat-exp/src/popup_redirect.ts

+12-9
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,17 @@ import * as exp from '@firebase/auth-exp/internal';
1919
import { _isCordova, _isLikelyCordova } from './platform';
2020

2121
const _assert: typeof exp._assert = exp._assert;
22-
const BROWSER_RESOLVER: exp.PopupRedirectResolverInternal = exp._getInstance(
23-
exp.browserPopupRedirectResolver
24-
);
25-
const CORDOVA_RESOLVER: exp.PopupRedirectResolverInternal = exp._getInstance(
26-
exp.cordovaPopupRedirectResolver
27-
);
2822

2923
/** Platform-agnostic popup-redirect resolver */
3024
export class CompatPopupRedirectResolver
31-
implements exp.PopupRedirectResolverInternal {
25+
implements exp.PopupRedirectResolverInternal
26+
{
27+
// Create both resolvers for dynamic resolution later
28+
private readonly browserResolver: exp.PopupRedirectResolverInternal =
29+
exp._getInstance(exp.browserPopupRedirectResolver);
30+
private readonly cordovaResolver: exp.PopupRedirectResolverInternal =
31+
exp._getInstance(exp.cordovaPopupRedirectResolver);
32+
// The actual resolver in use: either browserResolver or cordovaResolver.
3233
private underlyingResolver: exp.PopupRedirectResolverInternal | null = null;
3334
_redirectPersistence = exp.browserSessionPersistence;
3435

@@ -85,7 +86,7 @@ export class CompatPopupRedirectResolver
8586
}
8687

8788
get _shouldInitProactively(): boolean {
88-
return _isLikelyCordova() || BROWSER_RESOLVER._shouldInitProactively;
89+
return _isLikelyCordova() || this.browserResolver._shouldInitProactively;
8990
}
9091

9192
private get assertedUnderlyingResolver(): exp.PopupRedirectResolverInternal {
@@ -101,6 +102,8 @@ export class CompatPopupRedirectResolver
101102
// We haven't yet determined whether or not we're in Cordova; go ahead
102103
// and determine that state now.
103104
const isCordova = await _isCordova();
104-
this.underlyingResolver = isCordova ? CORDOVA_RESOLVER : BROWSER_RESOLVER;
105+
this.underlyingResolver = isCordova
106+
? this.cordovaResolver
107+
: this.browserResolver;
105108
}
106109
}

packages-exp/auth-exp/index.cordova.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,7 @@ import { initializeAuth } from './src';
3030
import { registerAuth } from './src/core/auth/register';
3131
import { ClientPlatform } from './src/core/util/version';
3232

33-
// Core functionality shared by all clients
34-
export * from './src';
33+
export * from './index.shared';
3534

3635
// Cordova also supports indexedDB / browserSession / browserLocal
3736
export { indexedDBLocalPersistence } from './src/platform_browser/persistence/indexed_db';

packages-exp/auth-exp/index.node.ts

+3-46
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
22
* @license
3-
* Copyright 2017 Google LLC
3+
* Copyright 2021 Google LLC
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
66
* you may not use this file except in compliance with the License.
@@ -15,48 +15,5 @@
1515
* limitations under the License.
1616
*/
1717

18-
/**
19-
* This is the file that people using Node.js will actually import. You should
20-
* only include this file if you have something specific about your
21-
* implementation that mandates having a separate entrypoint. Otherwise you can
22-
* just use index.browser.ts
23-
*/
24-
25-
import * as fetchImpl from 'node-fetch';
26-
27-
import { FirebaseApp, getApp, _getProvider } from '@firebase/app-exp';
28-
import { Auth } from './src/model/public_types';
29-
30-
import { initializeAuth } from './src';
31-
import { registerAuth } from './src/core/auth/register';
32-
import { FetchProvider } from './src/core/util/fetch_provider';
33-
import { ClientPlatform } from './src/core/util/version';
34-
35-
// Initialize the fetch polyfill, the types are slightly off so just cast and hope for the best
36-
FetchProvider.initialize(
37-
fetchImpl.default as unknown as typeof fetch,
38-
fetchImpl.Headers as unknown as typeof Headers,
39-
fetchImpl.Response as unknown as typeof Response
40-
);
41-
42-
// Core functionality shared by all clients
43-
export * from './src';
44-
export {
45-
FactorId,
46-
ProviderId,
47-
SignInMethod,
48-
OperationType,
49-
ActionCodeOperation
50-
} from './src/model/enum_maps';
51-
52-
export function getAuth(app: FirebaseApp = getApp()): Auth {
53-
const provider = _getProvider(app, 'auth-exp');
54-
55-
if (provider.isInitialized()) {
56-
return provider.getImmediate();
57-
}
58-
59-
return initializeAuth(app);
60-
}
61-
62-
registerAuth(ClientPlatform.NODE);
18+
// Node entry point is identical to browser entry point
19+
export * from './index';

packages-exp/auth-exp/index.rn.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ import { ClientPlatform } from './src/core/util/version';
3333
import { getReactNativePersistence } from './src/platform_react_native/persistence/react_native';
3434

3535
// Core functionality shared by all clients
36-
export * from './src';
36+
export * from './index.shared';
3737

3838
/**
3939
* An implementation of {@link Persistence} of type 'LOCAL' for use in React

packages-exp/auth-exp/index.shared.ts

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/**
2+
* @license
3+
* Copyright 2021 Google LLC
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
// Public types
19+
export * from './src/model/public_types';
20+
21+
// Helper maps (not used internally)
22+
export {
23+
FactorId,
24+
ProviderId,
25+
SignInMethod,
26+
OperationType,
27+
ActionCodeOperation
28+
} from './src/model/enum_maps';
29+
30+
// Core functionality shared by all clients
31+
export * from './src';

packages-exp/auth-exp/index.ts

+37-47
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,6 @@
2121
* limitations under the License.
2222
*/
2323

24-
import { FirebaseApp, getApp, _getProvider } from '@firebase/app-exp';
25-
26-
import { initializeAuth } from './src';
27-
import { registerAuth } from './src/core/auth/register';
28-
import { ClientPlatform } from './src/core/util/version';
29-
import { browserLocalPersistence } from './src/platform_browser/persistence/local_storage';
30-
import { browserSessionPersistence } from './src/platform_browser/persistence/session_storage';
31-
import { indexedDBLocalPersistence } from './src/platform_browser/persistence/indexed_db';
32-
import { browserPopupRedirectResolver } from './src/platform_browser/popup_redirect';
33-
import { Auth } from './src/model/public_types';
34-
3524
// Public types
3625
export * from './src/model/public_types';
3726

@@ -47,64 +36,65 @@ export {
4736
// Core functionality shared by all clients
4837
export * from './src';
4938

50-
// Additional DOM dependend functionality
39+
// Additional DOM dependend functionality; we need to import and then
40+
// export separately so that the rollup alias will work (for aliasing these
41+
// imports in node environments to no-ops and errors... see
42+
// src/platform_node/index.ts).
5143

5244
// persistence
53-
export { browserLocalPersistence } from './src/platform_browser/persistence/local_storage';
54-
export { browserSessionPersistence } from './src/platform_browser/persistence/session_storage';
55-
export { indexedDBLocalPersistence } from './src/platform_browser/persistence/indexed_db';
45+
import { browserLocalPersistence } from './src/platform_browser/persistence/local_storage';
46+
import { browserSessionPersistence } from './src/platform_browser/persistence/session_storage';
47+
import { indexedDBLocalPersistence } from './src/platform_browser/persistence/indexed_db';
5648

5749
// providers
58-
export { PhoneAuthProvider } from './src/platform_browser/providers/phone';
50+
import { PhoneAuthProvider } from './src/platform_browser/providers/phone';
5951

6052
// strategies
61-
export {
53+
import {
6254
signInWithPhoneNumber,
6355
linkWithPhoneNumber,
6456
reauthenticateWithPhoneNumber,
6557
updatePhoneNumber
6658
} from './src/platform_browser/strategies/phone';
67-
export {
59+
import {
6860
signInWithPopup,
6961
linkWithPopup,
7062
reauthenticateWithPopup
7163
} from './src/platform_browser/strategies/popup';
72-
export {
64+
import {
7365
signInWithRedirect,
7466
linkWithRedirect,
7567
reauthenticateWithRedirect,
7668
getRedirectResult
7769
} from './src/platform_browser/strategies/redirect';
7870

79-
export { RecaptchaVerifier } from './src/platform_browser/recaptcha/recaptcha_verifier';
80-
export { browserPopupRedirectResolver } from './src/platform_browser/popup_redirect';
71+
import { RecaptchaVerifier } from './src/platform_browser/recaptcha/recaptcha_verifier';
72+
import { browserPopupRedirectResolver } from './src/platform_browser/popup_redirect';
8173

8274
// MFA
83-
export { PhoneMultiFactorGenerator } from './src/platform_browser/mfa/assertions/phone';
84-
85-
/**
86-
* Returns the Auth instance associated with the provided {@link @firebase/app#FirebaseApp}.
87-
* If no instance exists, initializes an Auth instance with platform-specific default dependencies.
88-
*
89-
* @param app - The Firebase App.
90-
*
91-
* @public
92-
*/
93-
export function getAuth(app: FirebaseApp = getApp()): Auth {
94-
const provider = _getProvider(app, 'auth-exp');
75+
import { PhoneMultiFactorGenerator } from './src/platform_browser/mfa/assertions/phone';
9576

96-
if (provider.isInitialized()) {
97-
return provider.getImmediate();
98-
}
77+
// Initialization and registration of Auth
78+
import { getAuth } from './src/platform_browser';
9979

100-
return initializeAuth(app, {
101-
popupRedirectResolver: browserPopupRedirectResolver,
102-
persistence: [
103-
indexedDBLocalPersistence,
104-
browserLocalPersistence,
105-
browserSessionPersistence
106-
]
107-
});
108-
}
109-
110-
registerAuth(ClientPlatform.BROWSER);
80+
export {
81+
browserLocalPersistence,
82+
browserSessionPersistence,
83+
indexedDBLocalPersistence,
84+
PhoneAuthProvider,
85+
signInWithPhoneNumber,
86+
linkWithPhoneNumber,
87+
reauthenticateWithPhoneNumber,
88+
updatePhoneNumber,
89+
signInWithPopup,
90+
linkWithPopup,
91+
reauthenticateWithPopup,
92+
signInWithRedirect,
93+
linkWithRedirect,
94+
reauthenticateWithRedirect,
95+
getRedirectResult,
96+
RecaptchaVerifier,
97+
browserPopupRedirectResolver,
98+
PhoneMultiFactorGenerator,
99+
getAuth
100+
};

packages-exp/auth-exp/index.webworker.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import { ClientPlatform } from './src/core/util/version';
2727
import { indexedDBLocalPersistence } from './src/platform_browser/persistence/indexed_db';
2828

2929
// Core functionality shared by all clients
30-
export * from './src';
30+
export * from './index.shared';
3131

3232
// persistence
3333
export { indexedDBLocalPersistence } from './src/platform_browser/persistence/indexed_db';

packages-exp/auth-exp/package.json

+5-5
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,10 @@
3838
"test:cordova": "karma start --single-run --cordova",
3939
"test:cordova:debug": "karma start --auto-watch --cordova",
4040
"test:node": "run-s test:node:unit test:node:integration:local",
41-
"test:node:unit": "node ./scripts/run-node-tests.js",
42-
"test:node:integration": "node ./scripts/run-node-tests.js --integration",
43-
"test:node:integration:local": "node ./scripts/run-node-tests.js --integration --local",
44-
"test:webdriver": "rollup -c test/integration/webdriver/static/rollup.config.js && node ./scripts/run-node-tests.js --webdriver",
41+
"test:node:unit": "ts-node -O '{\"module\": \"commonjs\", \"target\": \"es6\"}' scripts/run_node_tests.ts",
42+
"test:node:integration": "ts-node -O '{\"module\": \"commonjs\", \"target\": \"es6\"}' scripts/run_node_tests.ts --integration",
43+
"test:node:integration:local": "ts-node -O '{\"module\": \"commonjs\", \"target\": \"es6\"}' scripts/run_node_tests.ts --integration --local",
44+
"test:webdriver": "rollup -c test/integration/webdriver/static/rollup.config.js && ts-node -O '{\"module\": \"commonjs\", \"target\": \"es6\"}' scripts/run_node_tests.ts --webdriver",
4545
"api-report": "api-extractor run --local --verbose && ts-node-script ../../repo-scripts/prune-dts/prune-dts.ts --input dist/auth-exp-public.d.ts --output dist/auth-exp-public.d.ts",
4646
"predoc": "node ../../scripts/exp/remove-exp.js temp",
4747
"doc": "api-documenter markdown --input temp --output docs",
@@ -85,4 +85,4 @@
8585
"reportDir": "./coverage/node"
8686
},
8787
"esm5": "dist/esm5/index.js"
88-
}
88+
}

packages-exp/auth-exp/rollup.config.shared.js

+17-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import strip from '@rollup/plugin-strip';
1919
import typescriptPlugin from 'rollup-plugin-typescript2';
2020
import json from '@rollup/plugin-json';
21+
import alias from '@rollup/plugin-alias';
2122
import typescript from 'typescript';
2223
import pkg from './package.json';
2324
import { importPathTransformer } from '../../scripts/exp/ts-transform-import-path';
@@ -37,6 +38,21 @@ const commonPlugins = [
3738
})
3839
];
3940

41+
/**
42+
* Node has the same entry point as browser, but browser-specific exports
43+
* are turned into either no-ops or errors. See src/platform_node/index.ts for
44+
* more info. This regex tests explicitly ./src/platform_browser so that the
45+
* only impacted file is the main index.ts
46+
*/
47+
const nodeAliasPlugin = alias({
48+
entries: [
49+
{
50+
find: /^\.\/src\/platform_browser(\/.*)?$/,
51+
replacement: `./src/platform_node`
52+
}
53+
]
54+
});
55+
4056
export function getConfig({ isReleaseBuild }) {
4157
/**
4258
* ES5 Builds
@@ -90,7 +106,7 @@ export function getConfig({ isReleaseBuild }) {
90106
internal: 'internal/index.ts'
91107
},
92108
output: [{ dir: 'dist/node', format: 'cjs', sourcemap: true }],
93-
plugins: es5BuildPlugins,
109+
plugins: [nodeAliasPlugin, ...es5BuildPlugins],
94110
external: id => deps.some(dep => id === dep || id.startsWith(`${dep}/`))
95111
},
96112
/**

0 commit comments

Comments
 (0)