Skip to content

Commit 1e6bd3e

Browse files
Add Node.js support to Storage v9 (#4985)
1 parent 3ea1e1f commit 1e6bd3e

35 files changed

+564
-237
lines changed

config/webpack.test.js

+11-13
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,11 @@ const path = require('path');
1919
const webpack = require('webpack');
2020

2121
/**
22-
* A regular expression used to replace Firestore's platform specific modules,
23-
* which are located under 'packages/firestore/src/platform/'.
22+
* A regular expression used to replace Firestore's and Storage's platform-
23+
* specific modules, which are located under
24+
* 'packages/(component)/src/platform/'.
2425
*/
25-
const FIRESTORE_PLATFORM_RE = /^(.*)\/platform\/([^.\/]*)(\.ts)?$/;
26+
const PLATFORM_RE = /^(.*)\/platform\/([^.\/]*)(\.ts)?$/;
2627

2728
module.exports = {
2829
mode: 'development',
@@ -100,16 +101,13 @@ module.exports = {
100101
symlinks: false
101102
},
102103
plugins: [
103-
new webpack.NormalModuleReplacementPlugin(
104-
FIRESTORE_PLATFORM_RE,
105-
resource => {
106-
const targetPlatform = process.env.TEST_PLATFORM || 'browser';
107-
resource.request = resource.request.replace(
108-
FIRESTORE_PLATFORM_RE,
109-
`$1/platform/${targetPlatform}/$2.ts`
110-
);
111-
}
112-
),
104+
new webpack.NormalModuleReplacementPlugin(PLATFORM_RE, resource => {
105+
const targetPlatform = process.env.TEST_PLATFORM || 'browser';
106+
resource.request = resource.request.replace(
107+
PLATFORM_RE,
108+
`$1/platform/${targetPlatform}/$2.ts`
109+
);
110+
}),
113111
new webpack.EnvironmentPlugin([
114112
'RTDB_EMULATOR_PORT',
115113
'RTDB_EMULATOR_NAMESPACE'
+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<component name="ProjectRunConfigurationManager">
2+
<configuration default="false" name="All Tests" type="mocha-javascript-test-runner">
3+
<node-interpreter>project</node-interpreter>
4+
<node-options />
5+
<mocha-package>$PROJECT_DIR$/../../node_modules/mocha</mocha-package>
6+
<working-directory>$PROJECT_DIR$</working-directory>
7+
<pass-parent-env>true</pass-parent-env>
8+
<envs>
9+
<env name="TS_NODE_COMPILER_OPTIONS" value="{&quot;module&quot;:&quot;commonjs&quot;}" />
10+
<env name="TS_NODE_FILES" value="true" />
11+
<env name="TS_NODE_CACHE" value="NO" />
12+
</envs>
13+
<ui>bdd</ui>
14+
<extra-mocha-options>--require ts-node/register/type-check --require index.ts</extra-mocha-options>
15+
<test-kind>PATTERN</test-kind>
16+
<test-pattern>test/{,!(browser)/**/}*.test.ts</test-pattern>
17+
<method v="2" />
18+
</configuration>
19+
</component>

packages/storage/exp/index.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import {
2828
// eslint-disable-next-line import/no-extraneous-dependencies
2929
} from '@firebase/app-exp';
3030

31-
import { XhrIoPool } from '../src/implementation/xhriopool';
31+
import { ConnectionPool } from '../src/implementation/connectionPool';
3232
import {
3333
StorageService as StorageServiceInternal,
3434
useStorageEmulator as useEmulatorInternal
@@ -76,7 +76,7 @@ function factory(
7676
app,
7777
authProvider,
7878
appCheckProvider,
79-
new XhrIoPool(),
79+
new ConnectionPool(),
8080
url,
8181
SDK_VERSION
8282
);

packages/storage/exp/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@firebase/storage-exp",
33
"description": "A tree-shakeable version of the Storage SDK",
4-
"main": "./dist/index.browser.cjs.js",
4+
"main": "./dist/index.node.cjs.js",
55
"module": "./dist/index.browser.esm2017.js",
66
"browser": "./dist/index.browser.esm2017.js",
77
"esm5": "./dist/index.browser.esm5.js",

packages/storage/index.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import { _FirebaseNamespace } from '@firebase/app-types/private';
2020
import { StringFormat } from './src/implementation/string';
2121
import { TaskEvent, TaskState } from './src/implementation/taskenums';
2222

23-
import { XhrIoPool } from './src/implementation/xhriopool';
23+
import { ConnectionPool } from './src/implementation/connectionPool';
2424
import { ReferenceCompat } from './compat/reference';
2525
import { StorageServiceCompat } from './compat/service';
2626
import { StorageService } from './src/service';
@@ -59,7 +59,7 @@ function factory(
5959
app,
6060
authProvider,
6161
appCheckProvider,
62-
new XhrIoPool(),
62+
new ConnectionPool(),
6363
url,
6464
firebase.SDK_VERSION
6565
)

packages/storage/package.json

+6-3
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,16 @@
2121
"build:exp:release": "yarn build:exp && yarn build:compat",
2222
"build:deps": "lerna run --scope @firebase/storage --include-dependencies build",
2323
"dev": "rollup -c -w",
24-
"test": "run-p test:browser lint",
25-
"test:ci": "node ../../scripts/run_tests_in_ci.js -s test:browser",
24+
"test": "run-p test:browser test:node lint",
25+
"test:ci": "node ../../scripts/run_tests_in_ci.js -s test:browser test:node",
2626
"test:browser:compat:unit": "karma start --single-run --compat --unit",
2727
"test:browser:exp:unit": "karma start --single-run --exp --unit",
2828
"test:browser:compat:integration": "karma start --single-run --compat --integration",
2929
"test:browser:exp:integration": "karma start --single-run --exp --integration",
3030
"test:browser:compat": "karma start --single-run --compat",
3131
"test:browser:exp": "karma start --single-run --exp",
3232
"test:browser": "karma start --single-run",
33+
"test:node": "TS_NODE_FILES=true TS_NODE_CACHE=NO TS_NODE_COMPILER_OPTIONS='{\"module\":\"commonjs\"}' nyc --reporter lcovonly -- mocha 'test/{,!(browser)/**/}*.test.ts' --file index.ts --config ../../config/mocharc.node.js",
3334
"test:debug": "karma start --browser=Chrome",
3435
"prettier": "prettier --write 'src/**/*.ts' 'test/**/*.ts'",
3536
"api-report": "api-extractor run --local --verbose && ts-node-script ../../repo-scripts/prune-dts/prune-dts.ts --input exp/dist/storage-public.d.ts --output exp/dist/storage-public.d.ts",
@@ -40,6 +41,7 @@
4041
"@firebase/storage-types": "0.4.1",
4142
"@firebase/util": "1.1.0",
4243
"@firebase/component": "0.5.3",
44+
"node-fetch": "2.6.1",
4345
"tslib": "^2.1.0"
4446
},
4547
"peerDependencies": {
@@ -50,6 +52,7 @@
5052
"@firebase/app": "0.6.27",
5153
"@firebase/auth": "0.16.7",
5254
"rollup": "2.35.1",
55+
"@rollup/plugin-alias": "3.1.1",
5356
"@rollup/plugin-json": "4.1.0",
5457
"rollup-plugin-typescript2": "0.29.0",
5558
"typescript": "4.2.2"
@@ -63,4 +66,4 @@
6366
"url": "https://github.com/firebase/firebase-js-sdk/issues"
6467
},
6568
"typings": "dist/index.d.ts"
66-
}
69+
}

packages/storage/rollup.config.compat.js

+5-2
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,13 @@
1818
import json from '@rollup/plugin-json';
1919
import typescriptPlugin from 'rollup-plugin-typescript2';
2020
import typescript from 'typescript';
21+
import alias from '@rollup/plugin-alias';
2122
import pkg from './package.json';
2223

2324
import { getImportPathTransformer } from '../../scripts/exp/ts-transform-import-path';
2425

26+
const { generateAliasConfig } = require('./rollup.shared');
27+
2528
const deps = [
2629
...Object.keys(Object.assign({}, pkg.peerDependencies, pkg.dependencies)),
2730
'@firebase/storage'
@@ -59,7 +62,7 @@ const es5Builds = [
5962
sourcemap: true
6063
}
6164
],
62-
plugins: es5BuildPlugins,
65+
plugins: [alias(generateAliasConfig('browser')), ...es5BuildPlugins],
6366
external: id => deps.some(dep => id === dep || id.startsWith(`${dep}/`)),
6467
treeshake: {
6568
moduleSideEffects: false
@@ -98,7 +101,7 @@ const es2017Builds = [
98101
format: 'es',
99102
sourcemap: true
100103
},
101-
plugins: es2017BuildPlugins,
104+
plugins: [alias(generateAliasConfig('browser')), ...es2017BuildPlugins],
102105
external: id => deps.some(dep => id === dep || id.startsWith(`${dep}/`)),
103106
treeshake: {
104107
moduleSideEffects: false

packages/storage/rollup.config.exp.js

+27-14
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,13 @@ import json from '@rollup/plugin-json';
1919
import typescriptPlugin from 'rollup-plugin-typescript2';
2020
import typescript from 'typescript';
2121
import pkgExp from './exp/package.json';
22+
import alias from '@rollup/plugin-alias';
2223
import pkg from './package.json';
2324
import path from 'path';
2425
import { importPathTransformer } from '../../scripts/exp/ts-transform-import-path';
2526

27+
const { generateAliasConfig } = require('./rollup.shared');
28+
2629
const deps = [
2730
...Object.keys(Object.assign({}, pkg.peerDependencies, pkg.dependencies)),
2831
'@firebase/app'
@@ -38,14 +41,15 @@ const es5Plugins = [
3841
];
3942

4043
const es5Builds = [
44+
// Browser
4145
{
4246
input: './exp/index.ts',
4347
output: {
4448
file: path.resolve('./exp', pkgExp.esm5),
4549
format: 'es',
4650
sourcemap: true
4751
},
48-
plugins: es5Plugins,
52+
plugins: [alias(generateAliasConfig('browser')), ...es5Plugins],
4953
external: id => deps.some(dep => id === dep || id.startsWith(`${dep}/`)),
5054
treeshake: {
5155
moduleSideEffects: false
@@ -68,21 +72,30 @@ const es2017Plugins = [
6872
];
6973

7074
const es2017Builds = [
75+
// Node
7176
{
7277
input: './exp/index.ts',
73-
output: [
74-
{
75-
file: path.resolve('./exp', pkgExp.main),
76-
format: 'cjs',
77-
sourcemap: true
78-
},
79-
{
80-
file: path.resolve('./exp', pkgExp.browser),
81-
format: 'es',
82-
sourcemap: true
83-
}
84-
],
85-
plugins: es2017Plugins,
78+
output: {
79+
file: path.resolve('./exp', pkgExp.main),
80+
format: 'cjs',
81+
sourcemap: true
82+
},
83+
plugins: [alias(generateAliasConfig('node')), ...es2017Plugins],
84+
external: id => deps.some(dep => id === dep || id.startsWith(`${dep}/`)),
85+
treeshake: {
86+
moduleSideEffects: false
87+
}
88+
},
89+
90+
// Browser
91+
{
92+
input: './exp/index.ts',
93+
output: {
94+
file: path.resolve('./exp', pkgExp.browser),
95+
format: 'es',
96+
sourcemap: true
97+
},
98+
plugins: [alias(generateAliasConfig('browser')), ...es2017Plugins],
8699
external: id => deps.some(dep => id === dep || id.startsWith(`${dep}/`)),
87100
treeshake: {
88101
moduleSideEffects: false

packages/storage/rollup.config.js

+5-2
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,11 @@
1818
import json from '@rollup/plugin-json';
1919
import typescriptPlugin from 'rollup-plugin-typescript2';
2020
import typescript from 'typescript';
21+
import alias from '@rollup/plugin-alias';
2122
import pkg from './package.json';
2223

24+
const { generateAliasConfig } = require('./rollup.shared');
25+
2326
const deps = Object.keys(
2427
Object.assign({}, pkg.peerDependencies, pkg.dependencies)
2528
);
@@ -40,7 +43,7 @@ const es5Builds = [
4043
{ file: pkg.main, format: 'cjs', sourcemap: true },
4144
{ file: pkg.module, format: 'es', sourcemap: true }
4245
],
43-
plugins: es5BuildPlugins,
46+
plugins: [alias(generateAliasConfig('browser')), ...es5BuildPlugins],
4447
external: id => deps.some(dep => id === dep || id.startsWith(`${dep}/`)),
4548
treeshake: {
4649
moduleSideEffects: false
@@ -71,7 +74,7 @@ const es2017Builds = [
7174
format: 'es',
7275
sourcemap: true
7376
},
74-
plugins: es2017BuildPlugins,
77+
plugins: [alias(generateAliasConfig('browser')), ...es2017BuildPlugins],
7578
external: id => deps.some(dep => id === dep || id.startsWith(`${dep}/`)),
7679
treeshake: {
7780
moduleSideEffects: false

packages/storage/rollup.shared.js

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
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+
/**
19+
* Returns an replacement configuration for `@rollup/plugin-alias` that replaces
20+
* references to platform-specific files with implementations for the provided
21+
* target platform.
22+
*/
23+
function generateAliasConfig(platform) {
24+
return {
25+
entries: [
26+
{
27+
find: /^(.*)\/platform\/([^.\/]*)(\.ts)?$/,
28+
replacement: `$1\/platform/${platform}/$2.ts`
29+
}
30+
]
31+
};
32+
}
33+
34+
exports.generateAliasConfig = generateAliasConfig;

packages/storage/src/implementation/xhrio.ts renamed to packages/storage/src/implementation/connection.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,23 @@
1616
*/
1717

1818
/**
19-
* XHR headers
19+
* Network headers
2020
*/
2121
export interface Headers {
22-
[name: string]: string | number;
22+
[name: string]: string;
2323
}
2424

2525
/**
2626
* A lightweight wrapper around XMLHttpRequest with a
2727
* goog.net.XhrIo-like interface.
2828
*/
29-
export interface XhrIo {
29+
export interface Connection {
3030
send(
3131
url: string,
3232
method: string,
3333
body?: ArrayBufferView | Blob | string | null,
3434
headers?: Headers
35-
): Promise<XhrIo>;
35+
): Promise<void>;
3636

3737
getErrorCode(): ErrorCode;
3838

packages/storage/src/implementation/xhriopool.ts renamed to packages/storage/src/implementation/connectionPool.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,14 @@
1818
/**
1919
* @fileoverview Replacement for goog.net.XhrIoPool that works with fbs.XhrIo.
2020
*/
21-
import { XhrIo } from './xhrio';
22-
import { NetworkXhrIo } from './xhrio_network';
21+
import { Connection } from './connection';
22+
import { newConnection } from '../platform/connection';
2323

2424
/**
2525
* Factory-like class for creating XhrIo instances.
2626
*/
27-
export class XhrIoPool {
28-
createXhrIo(): XhrIo {
29-
return new NetworkXhrIo();
27+
export class ConnectionPool {
28+
createConnection(): Connection {
29+
return newConnection();
3030
}
3131
}

0 commit comments

Comments
 (0)