From 4713a3853d1befee02f957da6a1e6e3688072c1c Mon Sep 17 00:00:00 2001 From: Feiyang1 Date: Thu, 5 Aug 2021 16:25:38 -0700 Subject: [PATCH 01/22] separate storage-compat from storage --- common/api-review/storage.api.md | 12 +- packages/{storage => storage-compat}/index.ts | 10 +- packages/storage-compat/package.json | 24 ++++ .../register-module.ts | 0 .../rollup.config.compat.js | 0 .../compat => storage-compat/src}/index.ts | 6 +- .../compat => storage-compat/src}/list.ts | 0 .../src}/reference.ts | 0 .../compat => storage-compat/src}/service.ts | 0 .../compat => storage-compat/src}/task.ts | 0 .../src}/tasksnapshot.ts | 0 packages/storage/api-extractor.json | 6 +- packages/storage/compat/package.json | 13 --- packages/storage/exp/package.json | 10 -- packages/storage/package.json | 17 ++- packages/storage/rollup.config.exp.js | 110 ------------------ packages/storage/rollup.config.js | 57 +++++---- packages/storage/rollup.shared.js | 34 ------ packages/storage/{exp => src}/api.ts | 18 +-- packages/storage/{exp => src}/constants.ts | 2 +- .../storage/src/implementation/observer.ts | 4 +- .../storage/src/implementation/taskenums.ts | 5 +- packages/storage/{exp => src}/index.ts | 0 packages/storage/src/metadata.ts | 2 +- packages/storage/{exp => src}/public-types.ts | 2 +- packages/storage/src/reference.ts | 3 +- packages/storage/src/service.ts | 3 +- packages/storage/src/task.ts | 22 ++-- packages/storage/src/tasksnapshot.ts | 73 ------------ .../integration/integration.compat.test.ts | 2 +- .../storage/test/unit/index.compat.test.ts | 2 +- 31 files changed, 113 insertions(+), 324 deletions(-) rename packages/{storage => storage-compat}/index.ts (87%) create mode 100644 packages/storage-compat/package.json rename packages/{storage => storage-compat}/register-module.ts (100%) rename packages/{storage => storage-compat}/rollup.config.compat.js (100%) rename packages/{storage/compat => storage-compat/src}/index.ts (92%) rename packages/{storage/compat => storage-compat/src}/list.ts (100%) rename packages/{storage/compat => storage-compat/src}/reference.ts (100%) rename packages/{storage/compat => storage-compat/src}/service.ts (100%) rename packages/{storage/compat => storage-compat/src}/task.ts (100%) rename packages/{storage/compat => storage-compat/src}/tasksnapshot.ts (100%) delete mode 100644 packages/storage/compat/package.json delete mode 100644 packages/storage/exp/package.json delete mode 100644 packages/storage/rollup.config.exp.js delete mode 100644 packages/storage/rollup.shared.js rename packages/storage/{exp => src}/api.ts (94%) rename packages/storage/{exp => src}/constants.ts (93%) rename packages/storage/{exp => src}/index.ts (100%) rename packages/storage/{exp => src}/public-types.ts (99%) delete mode 100644 packages/storage/src/tasksnapshot.ts diff --git a/common/api-review/storage.api.md b/common/api-review/storage.api.md index 5cae77227bc..642fa4c48e7 100644 --- a/common/api-review/storage.api.md +++ b/common/api-review/storage.api.md @@ -230,20 +230,16 @@ export class _UploadTask { // Warning: (ae-forgotten-export) The symbol "Metadata" needs to be exported by the entry point index.d.ts _metadata: Metadata | null; // Warning: (ae-forgotten-export) The symbol "TaskEvent" needs to be exported by the entry point index.d.ts - // Warning: (ae-forgotten-export) The symbol "StorageObserver" needs to be exported by the entry point index.d.ts - // Warning: (ae-forgotten-export) The symbol "ErrorFn" needs to be exported by the entry point index.d.ts - // Warning: (ae-forgotten-export) The symbol "CompleteFn" needs to be exported by the entry point index.d.ts + // Warning: (ae-forgotten-export) The symbol "FirebaseStorageError" needs to be exported by the entry point index.d.ts // Warning: (ae-forgotten-export) The symbol "Unsubscribe" needs to be exported by the entry point index.d.ts // Warning: (ae-forgotten-export) The symbol "Subscribe" needs to be exported by the entry point index.d.ts - on(type: TaskEvent_2, nextOrObserver?: StorageObserver_2 | ((a: UploadTaskSnapshot_2) => unknown), error?: ErrorFn, completed?: CompleteFn_2): Unsubscribe_2 | Subscribe_2; + on(type: TaskEvent_2, nextOrObserver?: StorageObserver | null | ((snapshot: UploadTaskSnapshot) => unknown), error?: ((a: FirebaseStorageError_2) => unknown) | null, completed?: Unsubscribe_2 | null): Unsubscribe_2 | Subscribe_2; pause(): boolean; resume(): boolean; - // Warning: (ae-forgotten-export) The symbol "UploadTaskSnapshot" needs to be exported by the entry point index.d.ts - get snapshot(): UploadTaskSnapshot_2; + get snapshot(): UploadTaskSnapshot; // Warning: (ae-forgotten-export) The symbol "InternalTaskState" needs to be exported by the entry point index.d.ts _state: InternalTaskState; - // Warning: (ae-forgotten-export) The symbol "FirebaseStorageError" needs to be exported by the entry point index.d.ts - then(onFulfilled?: ((value: UploadTaskSnapshot_2) => U | Promise) | null, onRejected?: ((error: FirebaseStorageError_2) => U | Promise) | null): Promise; + then(onFulfilled?: ((value: UploadTaskSnapshot) => U | Promise) | null, onRejected?: ((error: FirebaseStorageError_2) => U | Promise) | null): Promise; _transferred: number; } diff --git a/packages/storage/index.ts b/packages/storage-compat/index.ts similarity index 87% rename from packages/storage/index.ts rename to packages/storage-compat/index.ts index 8128907d79b..774cdef15f0 100644 --- a/packages/storage/index.ts +++ b/packages/storage-compat/index.ts @@ -17,13 +17,13 @@ import firebase from '@firebase/app'; import { _FirebaseNamespace } from '@firebase/app-types/private'; -import { StringFormat } from './src/implementation/string'; -import { TaskEvent, TaskState } from './src/implementation/taskenums'; +import { StringFormat } from '../storage/src/implementation/string'; +import { TaskEvent, TaskState } from '../storage/src/implementation/taskenums'; -import { ConnectionPool } from './src/implementation/connectionPool'; +import { ConnectionPool } from '../storage/src/implementation/connectionPool'; import { ReferenceCompat } from './compat/reference'; import { StorageServiceCompat } from './compat/service'; -import { FirebaseStorageImpl } from './src/service'; +import { FirebaseStorageImpl } from '../storage/src/service'; import * as types from '@firebase/storage-types'; import { Component, @@ -32,7 +32,7 @@ import { InstanceFactoryOptions } from '@firebase/component'; -import { name, version } from './package.json'; +import { name, version } from '../storage/package.json'; import './register-module'; diff --git a/packages/storage-compat/package.json b/packages/storage-compat/package.json new file mode 100644 index 00000000000..0b292328b6f --- /dev/null +++ b/packages/storage-compat/package.json @@ -0,0 +1,24 @@ +{ + "name": "@firebase/storage-compat", + "version": "0.1.0", + "description": "The Cloud Storage component of the Firebase JS SDK.", + "author": "Firebase (https://firebase.google.com/)", + "main": "./dist/cjs/index.js", + "browser": "./dist/esm2017/index.js", + "module": "./dist/esm2017/index.js", + "esm5": "./dist/esm5/index.js", + "license": "Apache-2.0", + "typings": "./dist/esm2017/compat/index.d.ts", + "private": false, + "dependencies": { + "@firebase/storage-types": "0.4.1", + "@firebase/util": "1.2.0", + "@firebase/component": "0.5.5", + "node-fetch": "2.6.1", + "tslib": "^2.1.0", + "@firebase/storage": "0.0.900-exp.8b4d7550f" + }, + "files": [ + "dist" + ] +} diff --git a/packages/storage/register-module.ts b/packages/storage-compat/register-module.ts similarity index 100% rename from packages/storage/register-module.ts rename to packages/storage-compat/register-module.ts diff --git a/packages/storage/rollup.config.compat.js b/packages/storage-compat/rollup.config.compat.js similarity index 100% rename from packages/storage/rollup.config.compat.js rename to packages/storage-compat/rollup.config.compat.js diff --git a/packages/storage/compat/index.ts b/packages/storage-compat/src/index.ts similarity index 92% rename from packages/storage/compat/index.ts rename to packages/storage-compat/src/index.ts index 88ac166e1f9..c6dd48f7970 100644 --- a/packages/storage/compat/index.ts +++ b/packages/storage-compat/src/index.ts @@ -18,8 +18,8 @@ // eslint-disable-next-line import/no-extraneous-dependencies import firebase from '@firebase/app-compat'; import { _FirebaseNamespace } from '@firebase/app-types/private'; -import { StringFormat } from '../src/implementation/string'; -import { TaskEvent, TaskState } from '../src/implementation/taskenums'; +import { StringFormat } from '../../storage/src/implementation/string'; +import { TaskEvent, TaskState } from '../../storage/src/implementation/taskenums'; import { ReferenceCompat } from './reference'; import { StorageServiceCompat } from './service'; @@ -31,7 +31,7 @@ import { InstanceFactoryOptions } from '@firebase/component'; -import { name, version } from './package.json'; +import { name, version } from '../../storage/compat/package.json'; /** * Type constant for Firebase Storage. diff --git a/packages/storage/compat/list.ts b/packages/storage-compat/src/list.ts similarity index 100% rename from packages/storage/compat/list.ts rename to packages/storage-compat/src/list.ts diff --git a/packages/storage/compat/reference.ts b/packages/storage-compat/src/reference.ts similarity index 100% rename from packages/storage/compat/reference.ts rename to packages/storage-compat/src/reference.ts diff --git a/packages/storage/compat/service.ts b/packages/storage-compat/src/service.ts similarity index 100% rename from packages/storage/compat/service.ts rename to packages/storage-compat/src/service.ts diff --git a/packages/storage/compat/task.ts b/packages/storage-compat/src/task.ts similarity index 100% rename from packages/storage/compat/task.ts rename to packages/storage-compat/src/task.ts diff --git a/packages/storage/compat/tasksnapshot.ts b/packages/storage-compat/src/tasksnapshot.ts similarity index 100% rename from packages/storage/compat/tasksnapshot.ts rename to packages/storage-compat/src/tasksnapshot.ts diff --git a/packages/storage/api-extractor.json b/packages/storage/api-extractor.json index c85607441f0..e652744d245 100644 --- a/packages/storage/api-extractor.json +++ b/packages/storage/api-extractor.json @@ -1,10 +1,10 @@ { "extends": "../../config/api-extractor.json", // Point it to your entry point d.ts file. - "mainEntryPointFilePath": "/exp/dist/exp/index.d.ts", + "mainEntryPointFilePath": "/dist/storage/src/index.d.ts", "dtsRollup": { "enabled": true, - "untrimmedFilePath": "/exp/dist/.d.ts", - "publicTrimmedFilePath": "/exp/dist/-public.d.ts" + "untrimmedFilePath": "/dist/.d.ts", + "publicTrimmedFilePath": "/dist/-public.d.ts" } } \ No newline at end of file diff --git a/packages/storage/compat/package.json b/packages/storage/compat/package.json deleted file mode 100644 index 2c149a59ccb..00000000000 --- a/packages/storage/compat/package.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "name": "@firebase/storage-compat", - "version": "0.0.900", - "description": "The Cloud Storage component of the Firebase JS SDK.", - "author": "Firebase (https://firebase.google.com/)", - "main": "../dist/compat/cjs/index.js", - "browser": "../dist/compat/esm2017/index.js", - "module": "../dist/compat/esm2017/index.js", - "esm5": "../dist/compat/esm5/index.js", - "license": "Apache-2.0", - "typings": "../dist/compat/esm2017/compat/index.d.ts" - } - \ No newline at end of file diff --git a/packages/storage/exp/package.json b/packages/storage/exp/package.json deleted file mode 100644 index 896db7ac0c1..00000000000 --- a/packages/storage/exp/package.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "name": "@firebase/storage-exp", - "description": "A tree-shakeable version of the Storage SDK", - "main": "./dist/index.node.cjs.js", - "module": "./dist/index.browser.esm2017.js", - "browser": "./dist/index.browser.esm2017.js", - "esm5": "./dist/index.browser.esm5.js", - "typings": "./dist/storage-public.d.ts", - "private": true -} diff --git a/packages/storage/package.json b/packages/storage/package.json index a0f369c87f3..46e4c388f2d 100644 --- a/packages/storage/package.json +++ b/packages/storage/package.json @@ -3,10 +3,10 @@ "version": "0.6.1", "description": "", "author": "Firebase (https://firebase.google.com/)", - "main": "dist/index.node.cjs.js", - "module": "dist/index.browser.esm.js", - "browser": "dist/index.browser.esm.js", - "esm2017": "dist/index.browser.esm2017.js", + "main": "dist/index.cjs.js", + "module": "dist/index.esm2017.js", + "browser": "dist/index.esm2017.js", + "esm5": "dist/index.esm5.js", "files": [ "dist", "exp/dist" @@ -15,10 +15,8 @@ "bundle": "rollup -c", "lint": "eslint -c .eslintrc.js '**/*.ts' --ignore-path '../../.gitignore'", "lint:fix": "eslint --fix -c .eslintrc.js '**/*.ts' --ignore-path '../../.gitignore'", - "build": "run-p 'bundle rollup.config.js' build:exp && yarn build:compat", - "build:exp": "rollup -c rollup.config.exp.js ; yarn api-report", + "build": "rollup -c rollup.config.js && yarn api-report", "build:compat": "rollup -c rollup.config.compat.js && yarn add-compat-overloads", - "build:exp:release": "yarn build:exp && yarn build:compat", "build:deps": "lerna run --scope @firebase/storage --include-dependencies build", "dev": "rollup -c -w", "test": "run-p test:browser test:node lint", @@ -33,7 +31,7 @@ "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", "test:debug": "karma start --browser=Chrome", "prettier": "prettier --write 'src/**/*.ts' 'test/**/*.ts'", - "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", + "api-report": "api-extractor run --local --verbose && ts-node-script ../../repo-scripts/prune-dts/prune-dts.ts --input dist/storage-public.d.ts --output dist/storage-public.d.ts", "add-compat-overloads": "ts-node-script ../../scripts/exp/create-overloads.ts -i exp/dist/storage-public.d.ts -o dist/compat/esm2017/compat/index.d.ts -a -r StorageService:types.FirebaseStorage -r StorageReference:types.Reference -r FirebaseApp:FirebaseAppCompat --moduleToEnhance @firebase/storage" }, "license": "Apache-2.0", @@ -45,8 +43,7 @@ "tslib": "^2.1.0" }, "peerDependencies": { - "@firebase/app": "0.x", - "@firebase/app-types": "0.x" + "@firebase/app": "0.x" }, "devDependencies": { "@firebase/app": "0.6.29", diff --git a/packages/storage/rollup.config.exp.js b/packages/storage/rollup.config.exp.js deleted file mode 100644 index 0a6c310656a..00000000000 --- a/packages/storage/rollup.config.exp.js +++ /dev/null @@ -1,110 +0,0 @@ -/** - * @license - * Copyright 2020 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 json from '@rollup/plugin-json'; -import typescriptPlugin from 'rollup-plugin-typescript2'; -import typescript from 'typescript'; -import pkgExp from './exp/package.json'; -import alias from '@rollup/plugin-alias'; -import pkg from './package.json'; -import path from 'path'; -import { importPathTransformer } from '../../scripts/exp/ts-transform-import-path'; - -const { generateAliasConfig } = require('./rollup.shared'); - -const deps = [ - ...Object.keys(Object.assign({}, pkg.peerDependencies, pkg.dependencies)), - '@firebase/app' -]; - -const nodeDeps = [...deps, 'util']; - -const es5Plugins = [ - typescriptPlugin({ - typescript, - abortOnError: false, - transformers: [importPathTransformer] - }), - json() -]; - -const es5Builds = [ - // Browser - { - input: './exp/index.ts', - output: { - file: path.resolve('./exp', pkgExp.esm5), - format: 'es', - sourcemap: true - }, - plugins: [alias(generateAliasConfig('browser')), ...es5Plugins], - external: id => deps.some(dep => id === dep || id.startsWith(`${dep}/`)), - treeshake: { - moduleSideEffects: false - } - } -]; - -const es2017Plugins = [ - typescriptPlugin({ - typescript, - tsconfigOverride: { - compilerOptions: { - target: 'es2017' - } - }, - abortOnError: false, - transformers: [importPathTransformer] - }), - json({ preferConst: true }) -]; - -const es2017Builds = [ - // Node - { - input: './exp/index.ts', - output: { - file: path.resolve('./exp', pkgExp.main), - format: 'cjs', - sourcemap: true - }, - plugins: [alias(generateAliasConfig('node')), ...es2017Plugins], - external: id => - nodeDeps.some(dep => id === dep || id.startsWith(`${dep}/`)), - treeshake: { - moduleSideEffects: false - } - }, - - // Browser - { - input: './exp/index.ts', - output: { - file: path.resolve('./exp', pkgExp.browser), - format: 'es', - sourcemap: true - }, - plugins: [alias(generateAliasConfig('browser')), ...es2017Plugins], - external: id => deps.some(dep => id === dep || id.startsWith(`${dep}/`)), - treeshake: { - moduleSideEffects: false - } - } -]; - -// eslint-disable-next-line import/no-default-export -export default [...es5Builds, ...es2017Builds]; diff --git a/packages/storage/rollup.config.js b/packages/storage/rollup.config.js index d0688d3e9c6..29eb54ed69e 100644 --- a/packages/storage/rollup.config.js +++ b/packages/storage/rollup.config.js @@ -21,29 +21,42 @@ import typescript from 'typescript'; import alias from '@rollup/plugin-alias'; import pkg from './package.json'; -const { generateAliasConfig } = require('./rollup.shared'); +import { importPathTransformer } from '../../scripts/exp/ts-transform-import-path'; -const deps = Object.keys( - Object.assign({}, pkg.peerDependencies, pkg.dependencies) -); +function generateAliasConfig(platform) { + return { + entries: [ + { + find: /^(.*)\/platform\/([^.\/]*)(\.ts)?$/, + replacement: `$1\/platform/${platform}/$2.ts` + } + ] + }; +} + +const deps = Object.keys(Object.assign({}, pkg.peerDependencies, pkg.dependencies)); const nodeDeps = [...deps, 'util']; -/** - * ES5 Builds - */ -const es5BuildPlugins = [ +const es5Plugins = [ typescriptPlugin({ - typescript + typescript, + abortOnError: false, + transformers: [importPathTransformer] }), json() ]; const es5Builds = [ + // Browser { - input: './index.ts', - output: { file: pkg.module, format: 'es', sourcemap: true }, - plugins: [alias(generateAliasConfig('browser')), ...es5BuildPlugins], + input: './src/index.ts', + output: { + file: pkg.esm5, + format: 'es', + sourcemap: true + }, + plugins: [alias(generateAliasConfig('browser')), ...es5Plugins], external: id => deps.some(dep => id === dep || id.startsWith(`${dep}/`)), treeshake: { moduleSideEffects: false @@ -51,17 +64,16 @@ const es5Builds = [ } ]; -/** - * ES2017 Builds - */ -const es2017BuildPlugins = [ +const es2017Plugins = [ typescriptPlugin({ typescript, tsconfigOverride: { compilerOptions: { target: 'es2017' } - } + }, + abortOnError: false, + transformers: [importPathTransformer] }), json({ preferConst: true }) ]; @@ -69,28 +81,29 @@ const es2017BuildPlugins = [ const es2017Builds = [ // Node { - input: './index.ts', + input: './src/index.ts', output: { file: pkg.main, format: 'cjs', sourcemap: true }, - plugins: [alias(generateAliasConfig('node')), ...es2017BuildPlugins], + plugins: [alias(generateAliasConfig('node')), ...es2017Plugins], external: id => nodeDeps.some(dep => id === dep || id.startsWith(`${dep}/`)), treeshake: { moduleSideEffects: false } }, + // Browser { - input: './index.ts', + input: './src/index.ts', output: { - file: pkg.esm2017, + file: pkg.browser, format: 'es', sourcemap: true }, - plugins: [alias(generateAliasConfig('browser')), ...es2017BuildPlugins], + plugins: [alias(generateAliasConfig('browser')), ...es2017Plugins], external: id => deps.some(dep => id === dep || id.startsWith(`${dep}/`)), treeshake: { moduleSideEffects: false diff --git a/packages/storage/rollup.shared.js b/packages/storage/rollup.shared.js deleted file mode 100644 index 59562480d49..00000000000 --- a/packages/storage/rollup.shared.js +++ /dev/null @@ -1,34 +0,0 @@ -/** - * @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. - */ - -/** - * Returns an replacement configuration for `@rollup/plugin-alias` that replaces - * references to platform-specific files with implementations for the provided - * target platform. - */ -function generateAliasConfig(platform) { - return { - entries: [ - { - find: /^(.*)\/platform\/([^.\/]*)(\.ts)?$/, - replacement: `$1\/platform/${platform}/$2.ts` - } - ] - }; -} - -exports.generateAliasConfig = generateAliasConfig; diff --git a/packages/storage/exp/api.ts b/packages/storage/src/api.ts similarity index 94% rename from packages/storage/exp/api.ts rename to packages/storage/src/api.ts index 762c260c72b..17eabd64355 100644 --- a/packages/storage/exp/api.ts +++ b/packages/storage/src/api.ts @@ -21,7 +21,7 @@ import { ref as refInternal, FirebaseStorageImpl, connectStorageEmulator as connectEmulatorInternal -} from '../src/service'; +} from './service'; import { Provider } from '@firebase/component'; import { @@ -35,7 +35,7 @@ import { UploadMetadata, FullMetadata } from './public-types'; -import { Metadata as MetadataInternal } from '../src/metadata'; +import { Metadata as MetadataInternal } from './metadata'; import { uploadBytes as uploadBytesInternal, uploadBytesResumable as uploadBytesResumableInternal, @@ -48,7 +48,7 @@ import { deleteObject as deleteObjectInternal, Reference, _getChild as _getChildInternal -} from '../src/reference'; +} from './reference'; import { STORAGE_TYPE } from './constants'; import { getModularInstance } from '@firebase/util'; @@ -57,10 +57,10 @@ import { getModularInstance } from '@firebase/util'; */ export * from './public-types'; -export { Location as _Location } from '../src/implementation/location'; -export { UploadTask as _UploadTask } from '../src/task'; -export type { Reference as _Reference } from '../src/reference'; -export { FbsBlob as _FbsBlob } from '../src/implementation/blob'; +export { Location as _Location } from './implementation/location'; +export { UploadTask as _UploadTask } from './task'; +export type { Reference as _Reference } from './reference'; +export { FbsBlob as _FbsBlob } from './implementation/blob'; /** * Uploads data to this object's location. @@ -276,7 +276,7 @@ export function _getChild(ref: StorageReference, childPath: string): Reference { return _getChildInternal(ref as Reference, childPath); } -export { StringFormat } from '../src/implementation/string'; +export { StringFormat } from './implementation/string'; /** * Gets a Firebase StorageService instance for the given Firebase app. @@ -291,7 +291,7 @@ export function getStorage( bucketUrl?: string ): FirebaseStorage { app = getModularInstance(app); - const storageProvider: Provider<'storage-exp'> = _getProvider( + const storageProvider: Provider<'storage'> = _getProvider( app, STORAGE_TYPE ); diff --git a/packages/storage/exp/constants.ts b/packages/storage/src/constants.ts similarity index 93% rename from packages/storage/exp/constants.ts rename to packages/storage/src/constants.ts index a14f489490e..21ea91291b3 100644 --- a/packages/storage/exp/constants.ts +++ b/packages/storage/src/constants.ts @@ -18,4 +18,4 @@ /** * Type constant for Firebase Storage. */ -export const STORAGE_TYPE = 'storage-exp'; +export const STORAGE_TYPE = 'storage'; diff --git a/packages/storage/src/implementation/observer.ts b/packages/storage/src/implementation/observer.ts index 5c480758ca3..910cf8fe008 100644 --- a/packages/storage/src/implementation/observer.ts +++ b/packages/storage/src/implementation/observer.ts @@ -81,8 +81,8 @@ export class Observer implements StorageObserver { isFunction(nextOrObserver) || error != null || complete != null; if (asFunctions) { this.next = nextOrObserver as NextFn; - this.error = error; - this.complete = complete; + this.error = error || undefined; + this.complete = complete || undefined; } else { const observer = nextOrObserver as { next?: NextFn; diff --git a/packages/storage/src/implementation/taskenums.ts b/packages/storage/src/implementation/taskenums.ts index 735474ff974..c57c58a9f45 100644 --- a/packages/storage/src/implementation/taskenums.ts +++ b/packages/storage/src/implementation/taskenums.ts @@ -59,8 +59,9 @@ export const enum InternalTaskState { /** * Represents the current state of a running upload. */ -export type TaskState = string; +export type TaskState = typeof TaskState[keyof typeof TaskState]; +// type keys = keyof TaskState /** * Represents the current state of a running upload. */ @@ -79,7 +80,7 @@ export const TaskState = { /** The task failed with an error. */ ERROR: 'error' -}; +} as const; export function taskStateFromInternalTaskState( state: InternalTaskState diff --git a/packages/storage/exp/index.ts b/packages/storage/src/index.ts similarity index 100% rename from packages/storage/exp/index.ts rename to packages/storage/src/index.ts diff --git a/packages/storage/src/metadata.ts b/packages/storage/src/metadata.ts index 61af339068f..f91fd73a519 100644 --- a/packages/storage/src/metadata.ts +++ b/packages/storage/src/metadata.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { FullMetadata } from '../exp/public-types'; +import { FullMetadata } from './public-types'; /** * @fileoverview Documentation for the metadata format. diff --git a/packages/storage/exp/public-types.ts b/packages/storage/src/public-types.ts similarity index 99% rename from packages/storage/exp/public-types.ts rename to packages/storage/src/public-types.ts index d982f61805f..1815954d16b 100644 --- a/packages/storage/exp/public-types.ts +++ b/packages/storage/src/public-types.ts @@ -487,6 +487,6 @@ export interface UploadResult { declare module '@firebase/component' { interface NameServiceMapping { - 'storage-exp': FirebaseStorage; + 'storage': FirebaseStorage; } } diff --git a/packages/storage/src/reference.ts b/packages/storage/src/reference.ts index 944af2c0577..88df3ab4633 100644 --- a/packages/storage/src/reference.ts +++ b/packages/storage/src/reference.ts @@ -31,7 +31,7 @@ import { deleteObject as requestsDeleteObject, multipartUpload } from './implementation/requests'; -import { ListOptions } from '../exp/public-types'; +import { ListOptions, UploadResult } from './public-types'; import { StringFormat, dataFromString } from './implementation/string'; import { Metadata } from './metadata'; import { FirebaseStorageImpl } from './service'; @@ -39,7 +39,6 @@ import { ListResult } from './list'; import { UploadTask } from './task'; import { invalidRootOperation, noDownloadURL } from './implementation/error'; import { validateNumber } from './implementation/type'; -import { UploadResult } from './tasksnapshot'; /** * Provides methods to interact with a bucket in the Firebase Storage service. diff --git a/packages/storage/src/service.ts b/packages/storage/src/service.ts index 0a0078c41a4..9738d1f30e2 100644 --- a/packages/storage/src/service.ts +++ b/packages/storage/src/service.ts @@ -38,7 +38,7 @@ import { noDefaultBucket } from './implementation/error'; import { validateNumber } from './implementation/type'; -import { FirebaseStorage } from '../exp/public-types'; +import { FirebaseStorage } from './public-types'; export function isUrl(path?: string): boolean { return /^[A-Za-z]+:\/\//.test(path as string); @@ -140,7 +140,6 @@ export function connectStorageEmulator( /** * A service that provides Firebase Storage Reference instances. - * @public * @param opt_url - gs:// url to a custom Storage Bucket */ export class FirebaseStorageImpl implements FirebaseStorage { diff --git a/packages/storage/src/task.ts b/packages/storage/src/task.ts index e7edbc4e076..96986f5e7b1 100644 --- a/packages/storage/src/task.ts +++ b/packages/storage/src/task.ts @@ -32,15 +32,14 @@ import { } from './implementation/taskenums'; import { Metadata } from './metadata'; import { - CompleteFn, - ErrorFn, Observer, - StorageObserver, Subscribe, - Unsubscribe + Unsubscribe, + StorageObserver as StorageObserverInternal, + NextFn } from './implementation/observer'; import { Request } from './implementation/request'; -import { UploadTaskSnapshot } from './tasksnapshot'; +import { UploadTaskSnapshot, StorageObserver } from './public-types'; import { async as fbsAsync } from './implementation/async'; import { Mappings, getMappings } from './implementation/metadata'; import { @@ -76,7 +75,7 @@ export class UploadTask { _transferred: number = 0; private _needToFetchStatus: boolean = false; private _needToFetchMetadata: boolean = false; - private _observers: Array> = []; + private _observers: Array> = []; private _resumable: boolean; /** * Upload state. @@ -132,7 +131,7 @@ export class UploadTask { // Prevent uncaught rejections on the internal promise from bubbling out // to the top level with a dummy handler. - this._promise.then(null, () => {}); + this._promise.then(null, () => { }); } private _makeProgressCallback(): (p1: number, p2: number) => void { @@ -483,11 +482,12 @@ export class UploadTask { type: TaskEvent, nextOrObserver?: | StorageObserver - | ((a: UploadTaskSnapshot) => unknown), - error?: ErrorFn, - completed?: CompleteFn + | null + | ((snapshot: UploadTaskSnapshot) => unknown), + error?: ((a: FirebaseStorageError) => unknown) | null, + completed?: Unsubscribe | null ): Unsubscribe | Subscribe { - const observer = new Observer(nextOrObserver, error, completed); + const observer = new Observer((nextOrObserver as StorageObserverInternal | NextFn) || undefined, error || undefined, completed || undefined); this._addObserver(observer); return () => { this._removeObserver(observer); diff --git a/packages/storage/src/tasksnapshot.ts b/packages/storage/src/tasksnapshot.ts deleted file mode 100644 index 01341bf5df6..00000000000 --- a/packages/storage/src/tasksnapshot.ts +++ /dev/null @@ -1,73 +0,0 @@ -/** - * @license - * Copyright 2017 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 { TaskState } from './implementation/taskenums'; -import { Metadata } from './metadata'; -import { Reference } from './reference'; -import { UploadTask } from './task'; - -/** - * Result returned from a non-resumable upload. - * @public - */ -export interface UploadResult { - /** - * Contains the metadata sent back from the server. - */ - readonly metadata: Metadata; - - /** - * The reference that spawned this upload. - */ - readonly ref: Reference; -} - -/** - * Holds data about the current state of the upload task. - * @public - */ -export interface UploadTaskSnapshot { - /** - * The number of bytes that have been successfully uploaded so far. - */ - readonly bytesTransferred: number; - - /** - * The total number of bytes to be uploaded. - */ - readonly totalBytes: number; - - /** - * The current state of the task. - */ - readonly state: TaskState; - - /** - * Before the upload completes, contains the metadata sent to the server. - * After the upload completes, contains the metadata sent back from the server. - */ - readonly metadata: Metadata; - - /** - * The task of which this is a snapshot. - */ - readonly task: UploadTask; - - /** - * The reference that spawned this snapshot's upload task. - */ - readonly ref: Reference; -} diff --git a/packages/storage/test/integration/integration.compat.test.ts b/packages/storage/test/integration/integration.compat.test.ts index e2b5c6f8508..bac05921cc1 100644 --- a/packages/storage/test/integration/integration.compat.test.ts +++ b/packages/storage/test/integration/integration.compat.test.ts @@ -23,7 +23,7 @@ import '@firebase/auth'; import * as storage from '@firebase/storage-types'; import { expect } from 'chai'; -import '../../index'; +import '../../../storage-compat/index'; // eslint-disable-next-line @typescript-eslint/no-require-imports const PROJECT_CONFIG = require('../../../../config/project.json'); diff --git a/packages/storage/test/unit/index.compat.test.ts b/packages/storage/test/unit/index.compat.test.ts index 451821ab2b5..a9fee38c304 100644 --- a/packages/storage/test/unit/index.compat.test.ts +++ b/packages/storage/test/unit/index.compat.test.ts @@ -15,7 +15,7 @@ * limitations under the License. */ import { expect } from 'chai'; -import '../../index'; +import '../../../storage-compat/index'; import firebase from '@firebase/app'; // eslint-disable-next-line import/no-extraneous-dependencies import { StorageServiceCompat } from '../../compat/service'; From 46a8d8c353b48016343c4d72ac78d0d1d1260663 Mon Sep 17 00:00:00 2001 From: Feiyang1 Date: Thu, 5 Aug 2021 16:26:25 -0700 Subject: [PATCH 02/22] commit --- packages/storage-compat/src/index.ts | 7 +++++-- packages/storage-compat/src/reference.ts | 3 ++- packages/storage-compat/src/tasksnapshot.ts | 3 ++- packages/storage/rollup.config.js | 4 +++- packages/storage/src/api.ts | 5 +---- packages/storage/src/task.ts | 10 ++++++++-- 6 files changed, 21 insertions(+), 11 deletions(-) diff --git a/packages/storage-compat/src/index.ts b/packages/storage-compat/src/index.ts index c6dd48f7970..12fc1067a18 100644 --- a/packages/storage-compat/src/index.ts +++ b/packages/storage-compat/src/index.ts @@ -19,7 +19,10 @@ import firebase from '@firebase/app-compat'; import { _FirebaseNamespace } from '@firebase/app-types/private'; import { StringFormat } from '../../storage/src/implementation/string'; -import { TaskEvent, TaskState } from '../../storage/src/implementation/taskenums'; +import { + TaskEvent, + TaskState +} from '../../storage/src/implementation/taskenums'; import { ReferenceCompat } from './reference'; import { StorageServiceCompat } from './service'; @@ -73,7 +76,7 @@ export function registerStorage(instance: _FirebaseNamespace): void { instance.registerVersion(name, version); } -registerStorage((firebase as unknown) as _FirebaseNamespace); +registerStorage(firebase as unknown as _FirebaseNamespace); /** * Define extension behavior for `registerStorage` diff --git a/packages/storage-compat/src/reference.ts b/packages/storage-compat/src/reference.ts index 29deef4efcf..527189ed659 100644 --- a/packages/storage-compat/src/reference.ts +++ b/packages/storage-compat/src/reference.ts @@ -43,7 +43,8 @@ import { invalidRootOperation } from '../src/implementation/error'; import { Compat } from '@firebase/util'; export class ReferenceCompat - implements types.Reference, Compat { + implements types.Reference, Compat +{ constructor( readonly _delegate: StorageReference, public storage: StorageServiceCompat diff --git a/packages/storage-compat/src/tasksnapshot.ts b/packages/storage-compat/src/tasksnapshot.ts index 4d092994199..841dded18e7 100644 --- a/packages/storage-compat/src/tasksnapshot.ts +++ b/packages/storage-compat/src/tasksnapshot.ts @@ -22,7 +22,8 @@ import * as types from '@firebase/storage-types'; import { Compat } from '@firebase/util'; export class UploadTaskSnapshotCompat - implements types.UploadTaskSnapshot, Compat { + implements types.UploadTaskSnapshot, Compat +{ constructor( readonly _delegate: UploadTaskSnapshot, readonly task: UploadTaskCompat, diff --git a/packages/storage/rollup.config.js b/packages/storage/rollup.config.js index 29eb54ed69e..0093bcd9ec3 100644 --- a/packages/storage/rollup.config.js +++ b/packages/storage/rollup.config.js @@ -34,7 +34,9 @@ function generateAliasConfig(platform) { }; } -const deps = Object.keys(Object.assign({}, pkg.peerDependencies, pkg.dependencies)); +const deps = Object.keys( + Object.assign({}, pkg.peerDependencies, pkg.dependencies) +); const nodeDeps = [...deps, 'util']; diff --git a/packages/storage/src/api.ts b/packages/storage/src/api.ts index 17eabd64355..fbfbbc3abdb 100644 --- a/packages/storage/src/api.ts +++ b/packages/storage/src/api.ts @@ -291,10 +291,7 @@ export function getStorage( bucketUrl?: string ): FirebaseStorage { app = getModularInstance(app); - const storageProvider: Provider<'storage'> = _getProvider( - app, - STORAGE_TYPE - ); + const storageProvider: Provider<'storage'> = _getProvider(app, STORAGE_TYPE); const storageInstance = storageProvider.getImmediate({ identifier: bucketUrl }); diff --git a/packages/storage/src/task.ts b/packages/storage/src/task.ts index 96986f5e7b1..04c58d4ca1f 100644 --- a/packages/storage/src/task.ts +++ b/packages/storage/src/task.ts @@ -131,7 +131,7 @@ export class UploadTask { // Prevent uncaught rejections on the internal promise from bubbling out // to the top level with a dummy handler. - this._promise.then(null, () => { }); + this._promise.then(null, () => {}); } private _makeProgressCallback(): (p1: number, p2: number) => void { @@ -487,7 +487,13 @@ export class UploadTask { error?: ((a: FirebaseStorageError) => unknown) | null, completed?: Unsubscribe | null ): Unsubscribe | Subscribe { - const observer = new Observer((nextOrObserver as StorageObserverInternal | NextFn) || undefined, error || undefined, completed || undefined); + const observer = new Observer( + (nextOrObserver as + | StorageObserverInternal + | NextFn) || undefined, + error || undefined, + completed || undefined + ); this._addObserver(observer); return () => { this._removeObserver(observer); From c2fcd73eb8cac37044362211b3610dd8903d87b1 Mon Sep 17 00:00:00 2001 From: Feiyang1 Date: Thu, 5 Aug 2021 16:50:12 -0700 Subject: [PATCH 03/22] fix tests --- packages-exp/app-exp/src/constants.ts | 2 +- .../integration/integration.compat.test.ts | 2 +- .../test/unit/index.compat.test.ts | 4 ++-- .../test/unit/reference.compat.test.ts | 0 .../test/unit/service.compat.test.ts | 0 packages/storage/karma.conf.js | 24 ++++++++----------- ...ration.exp.test.ts => integration.test.ts} | 6 ++--- .../unit/{index.exp.test.ts => index.test.ts} | 2 +- ...eference.exp.test.ts => reference.test.ts} | 0 .../{service.exp.test.ts => service.test.ts} | 0 10 files changed, 18 insertions(+), 22 deletions(-) rename packages/{storage => storage-compat}/test/integration/integration.compat.test.ts (99%) rename packages/{storage => storage-compat}/test/unit/index.compat.test.ts (95%) rename packages/{storage => storage-compat}/test/unit/reference.compat.test.ts (100%) rename packages/{storage => storage-compat}/test/unit/service.compat.test.ts (100%) rename packages/storage/test/integration/{integration.exp.test.ts => integration.test.ts} (97%) rename packages/storage/test/unit/{index.exp.test.ts => index.test.ts} (97%) rename packages/storage/test/unit/{reference.exp.test.ts => reference.test.ts} (100%) rename packages/storage/test/unit/{service.exp.test.ts => service.test.ts} (100%) diff --git a/packages-exp/app-exp/src/constants.ts b/packages-exp/app-exp/src/constants.ts index f00a93f0da9..34feb88f791 100644 --- a/packages-exp/app-exp/src/constants.ts +++ b/packages-exp/app-exp/src/constants.ts @@ -36,7 +36,7 @@ import { name as performanceCompatName } from '../../../packages-exp/performance import { name as remoteConfigName } from '../../../packages-exp/remote-config-exp/package.json'; import { name as remoteConfigCompatName } from '../../../packages-exp/remote-config-compat/package.json'; import { name as storageName } from '../../../packages/storage/package.json'; -import { name as storageCompatName } from '../../../packages/storage/compat/package.json'; +import { name as storageCompatName } from '../../../packages/storage-compat/package.json'; import { name as firestoreName } from '../../../packages/firestore/package.json'; import { name as firestoreCompatName } from '../../../packages/firestore/compat/package.json'; import { name as packageName } from '../../../packages-exp/firebase-exp/package.json'; diff --git a/packages/storage/test/integration/integration.compat.test.ts b/packages/storage-compat/test/integration/integration.compat.test.ts similarity index 99% rename from packages/storage/test/integration/integration.compat.test.ts rename to packages/storage-compat/test/integration/integration.compat.test.ts index bac05921cc1..e2b5c6f8508 100644 --- a/packages/storage/test/integration/integration.compat.test.ts +++ b/packages/storage-compat/test/integration/integration.compat.test.ts @@ -23,7 +23,7 @@ import '@firebase/auth'; import * as storage from '@firebase/storage-types'; import { expect } from 'chai'; -import '../../../storage-compat/index'; +import '../../index'; // eslint-disable-next-line @typescript-eslint/no-require-imports const PROJECT_CONFIG = require('../../../../config/project.json'); diff --git a/packages/storage/test/unit/index.compat.test.ts b/packages/storage-compat/test/unit/index.compat.test.ts similarity index 95% rename from packages/storage/test/unit/index.compat.test.ts rename to packages/storage-compat/test/unit/index.compat.test.ts index a9fee38c304..a4346a92349 100644 --- a/packages/storage/test/unit/index.compat.test.ts +++ b/packages/storage-compat/test/unit/index.compat.test.ts @@ -15,11 +15,11 @@ * limitations under the License. */ import { expect } from 'chai'; -import '../../../storage-compat/index'; +import '../../index'; import firebase from '@firebase/app'; // eslint-disable-next-line import/no-extraneous-dependencies import { StorageServiceCompat } from '../../compat/service'; -import { FirebaseStorageImpl } from '../../src/service'; +import { FirebaseStorageImpl } from '../../../storage/src/service'; // eslint-disable-next-line @typescript-eslint/no-require-imports const PROJECT_CONFIG = require('../../../../config/project.json'); diff --git a/packages/storage/test/unit/reference.compat.test.ts b/packages/storage-compat/test/unit/reference.compat.test.ts similarity index 100% rename from packages/storage/test/unit/reference.compat.test.ts rename to packages/storage-compat/test/unit/reference.compat.test.ts diff --git a/packages/storage/test/unit/service.compat.test.ts b/packages/storage-compat/test/unit/service.compat.test.ts similarity index 100% rename from packages/storage/test/unit/service.compat.test.ts rename to packages/storage-compat/test/unit/service.compat.test.ts diff --git a/packages/storage/karma.conf.js b/packages/storage/karma.conf.js index ab37877fc20..e836c350a88 100644 --- a/packages/storage/karma.conf.js +++ b/packages/storage/karma.conf.js @@ -32,20 +32,16 @@ module.exports = function (config) { function getTestFiles(argv) { let unitTestFiles = ['test/unit/*']; - let integrationTestFiles = []; - if (argv.exp) { - unitTestFiles = unitTestFiles.filter( - filename => !filename.includes('.compat.') - ); - integrationTestFiles = ['test/integration/*exp*']; - } else if (argv.compat) { - unitTestFiles = unitTestFiles.filter( - filename => !filename.includes('.exp.') - ); - integrationTestFiles = ['test/integration/*compat*']; - } else { - integrationTestFiles = ['test/integration/*']; - } + let integrationTestFiles = ['test/integration/*']; + + // if (argv.compat) { + // unitTestFiles = unitTestFiles.filter( + // filename => !filename.includes('.exp.') + // ); + // integrationTestFiles = ['test/integration/*compat*']; + // } else { + // integrationTestFiles = ['test/integration/*']; + // } if (argv.unit) { return unitTestFiles; } else if (argv.integration) { diff --git a/packages/storage/test/integration/integration.exp.test.ts b/packages/storage/test/integration/integration.test.ts similarity index 97% rename from packages/storage/test/integration/integration.exp.test.ts rename to packages/storage/test/integration/integration.test.ts index 282ee9d6860..63b1c2c3cc9 100644 --- a/packages/storage/test/integration/integration.exp.test.ts +++ b/packages/storage/test/integration/integration.test.ts @@ -30,11 +30,11 @@ import { getMetadata, updateMetadata, listAll -} from '../../exp/index'; +} from '../../src/index'; import { use, expect } from 'chai'; import * as chaiAsPromised from 'chai-as-promised'; -import * as types from '../../exp/public-types'; +import * as types from '../../src/public-types'; use(chaiAsPromised); @@ -46,7 +46,7 @@ export const STORAGE_BUCKET = PROJECT_CONFIG.storageBucket; export const API_KEY = PROJECT_CONFIG.apiKey; export const AUTH_DOMAIN = PROJECT_CONFIG.authDomain; -describe('FirebaseStorage Exp', () => { +describe('FirebaseStorage Integration tests', () => { let app: FirebaseApp; let storage: types.FirebaseStorage; diff --git a/packages/storage/test/unit/index.exp.test.ts b/packages/storage/test/unit/index.test.ts similarity index 97% rename from packages/storage/test/unit/index.exp.test.ts rename to packages/storage/test/unit/index.test.ts index 9c57c2583eb..8f2a6b37785 100644 --- a/packages/storage/test/unit/index.exp.test.ts +++ b/packages/storage/test/unit/index.test.ts @@ -15,7 +15,7 @@ * limitations under the License. */ import { expect } from 'chai'; -import { getStorage } from '../../exp/index'; +import { getStorage } from '../../src/index'; import { FirebaseStorageImpl } from '../../src/service'; // eslint-disable-next-line import/no-extraneous-dependencies import { initializeApp, deleteApp } from '@firebase/app-exp'; diff --git a/packages/storage/test/unit/reference.exp.test.ts b/packages/storage/test/unit/reference.test.ts similarity index 100% rename from packages/storage/test/unit/reference.exp.test.ts rename to packages/storage/test/unit/reference.test.ts diff --git a/packages/storage/test/unit/service.exp.test.ts b/packages/storage/test/unit/service.test.ts similarity index 100% rename from packages/storage/test/unit/service.exp.test.ts rename to packages/storage/test/unit/service.test.ts From af627d2d680f8f9ef9316484418a82284df8cd37 Mon Sep 17 00:00:00 2001 From: Feiyang1 Date: Thu, 5 Aug 2021 16:50:25 -0700 Subject: [PATCH 04/22] wat? --- packages/storage/karma.conf.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/storage/karma.conf.js b/packages/storage/karma.conf.js index e836c350a88..daa472b2fe2 100644 --- a/packages/storage/karma.conf.js +++ b/packages/storage/karma.conf.js @@ -33,7 +33,7 @@ module.exports = function (config) { function getTestFiles(argv) { let unitTestFiles = ['test/unit/*']; let integrationTestFiles = ['test/integration/*']; - + // if (argv.compat) { // unitTestFiles = unitTestFiles.filter( // filename => !filename.includes('.exp.') From d2941badafca072a37566eda5515a1128b6a9611 Mon Sep 17 00:00:00 2001 From: Feiyang1 Date: Fri, 6 Aug 2021 16:42:58 -0700 Subject: [PATCH 05/22] build storage-compat --- common/api-review/storage.api.md | 93 +++++++++++++++++-- packages/storage-compat/.eslintrc.js | 48 ++++++++++ packages/storage-compat/.npmignore | 9 ++ packages/storage-compat/README.md | 5 + packages/storage-compat/index.ts | 88 ------------------ packages/storage-compat/karma.conf.js | 54 +++++++++++ packages/storage-compat/package.json | 37 ++++++-- packages/storage-compat/register-module.ts | 50 ---------- ...llup.config.compat.js => rollup.config.js} | 50 +++------- packages/storage-compat/src/index.ts | 12 +-- packages/storage-compat/src/list.ts | 2 +- packages/storage-compat/src/reference.ts | 26 +++--- packages/storage-compat/src/service.ts | 22 +++-- packages/storage-compat/src/task.ts | 2 +- packages/storage-compat/src/tasksnapshot.ts | 2 +- packages/storage-compat/tsconfig.json | 9 ++ packages/storage-types/index.d.ts | 2 +- packages/storage/api-extractor.json | 2 +- packages/storage/package.json | 6 +- packages/storage/src/api.ts | 4 + packages/storage/src/implementation/error.ts | 5 + packages/storage/src/implementation/string.ts | 3 + 22 files changed, 299 insertions(+), 232 deletions(-) create mode 100644 packages/storage-compat/.eslintrc.js create mode 100644 packages/storage-compat/.npmignore create mode 100644 packages/storage-compat/README.md delete mode 100644 packages/storage-compat/index.ts create mode 100644 packages/storage-compat/karma.conf.js delete mode 100644 packages/storage-compat/register-module.ts rename packages/storage-compat/{rollup.config.compat.js => rollup.config.js} (59%) create mode 100644 packages/storage-compat/tsconfig.json diff --git a/common/api-review/storage.api.md b/common/api-review/storage.api.md index 642fa4c48e7..23294f713b6 100644 --- a/common/api-review/storage.api.md +++ b/common/api-review/storage.api.md @@ -18,6 +18,11 @@ import { Unsubscribe } from '@firebase/util'; // @public export function connectStorageEmulator(storage: FirebaseStorage, host: string, port: number): void; +// Warning: (ae-forgotten-export) The symbol "StringData" needs to be exported by the entry point index.d.ts +// +// @internal (undocumented) +export function _dataFromString(format: StringFormat, stringData: string): StringData; + // @public export function deleteObject(ref: StorageReference): Promise; @@ -48,6 +53,55 @@ export interface FirebaseStorageError extends FirebaseError { serverResponse: string | null; } +// @public +export class _FirebaseStorageImpl implements FirebaseStorage { + constructor( + app: FirebaseApp, _authProvider: Provider, + _appCheckProvider: Provider, + _pool: ConnectionPool, _url?: string | undefined, _firebaseVersion?: string | undefined); + readonly app: FirebaseApp; + // @internal (undocumented) + readonly _appCheckProvider: Provider; + // (undocumented) + protected readonly _appId: string | null; + // (undocumented) + readonly _authProvider: Provider; + // Warning: (ae-incompatible-release-tags) The symbol "_bucket" is marked as @public, but its signature references "Location" which is marked as @internal + // + // (undocumented) + _bucket: _Location | null; + _delete(): Promise; + // (undocumented) + readonly _firebaseVersion?: string | undefined; + // (undocumented) + _getAppCheckToken(): Promise; + // (undocumented) + _getAuthToken(): Promise; + // (undocumented) + get host(): string; + set host(host: string); + // Warning: (ae-forgotten-export) The symbol "RequestInfo" needs to be exported by the entry point index.d.ts + // Warning: (ae-forgotten-export) The symbol "Request" needs to be exported by the entry point index.d.ts + // + // (undocumented) + _makeRequest(requestInfo: RequestInfo_2, authToken: string | null, appCheckToken: string | null): Request_2; + // (undocumented) + makeRequestWithTokens(requestInfo: RequestInfo_2): Promise>; + // Warning: (ae-incompatible-release-tags) The symbol "_makeStorageReference" is marked as @public, but its signature references "Location" which is marked as @internal + // Warning: (ae-incompatible-release-tags) The symbol "_makeStorageReference" is marked as @public, but its signature references "Reference" which is marked as @internal + _makeStorageReference(loc: _Location): _Reference; + get maxOperationRetryTime(): number; + set maxOperationRetryTime(time: number); + get maxUploadRetryTime(): number; + set maxUploadRetryTime(time: number); + // Warning: (ae-forgotten-export) The symbol "ConnectionPool" needs to be exported by the entry point index.d.ts + // + // @internal (undocumented) + readonly _pool: ConnectionPool; + // (undocumented) + readonly _url?: string | undefined; +} + // @public export interface FullMetadata extends UploadMetadata { bucket: string; @@ -74,6 +128,14 @@ export function getMetadata(ref: StorageReference): Promise; // @public export function getStorage(app?: FirebaseApp, bucketUrl?: string): FirebaseStorage; +// Warning: (ae-forgotten-export) The symbol "FirebaseStorageError" needs to be exported by the entry point index.d.ts +// +// @internal (undocumented) +export function _invalidArgument(message: string): FirebaseStorageError_2; + +// @internal (undocumented) +export function _invalidRootOperation(name: string): FirebaseStorageError_2; + // @public export function list(ref: StorageReference, options?: ListOptions): Promise; @@ -120,18 +182,17 @@ export function ref(storageOrRef: FirebaseStorage | StorageReference, path?: str // @internal export class _Reference { - // Warning: (ae-forgotten-export) The symbol "FirebaseStorageImpl" needs to be exported by the entry point index.d.ts - constructor(_service: FirebaseStorageImpl, location: string | _Location); + constructor(_service: _FirebaseStorageImpl, location: string | _Location); get bucket(): string; get fullPath(): string; // (undocumented) _location: _Location; get name(): string; // (undocumented) - protected _newRef(service: FirebaseStorageImpl, location: _Location): _Reference; + protected _newRef(service: _FirebaseStorageImpl, location: _Location): _Reference; get parent(): _Reference | null; get root(): _Reference; - get storage(): FirebaseStorageImpl; + get storage(): _FirebaseStorageImpl; _throwIfRoot(name: string): void; // @override toString(): string; @@ -184,9 +245,29 @@ export const StringFormat: { // @public export type TaskEvent = 'state_changed'; +// @public +export type _TaskEvent = string; + +// @public +export const _TaskEvent: { + STATE_CHANGED: string; +}; + // @public export type TaskState = 'running' | 'paused' | 'success' | 'canceled' | 'error'; +// @public +export type _TaskState = typeof _TaskState[keyof typeof _TaskState]; + +// @public +export const _TaskState: { + readonly RUNNING: "running"; + readonly PAUSED: "paused"; + readonly SUCCESS: "success"; + readonly CANCELED: "canceled"; + readonly ERROR: "error"; +}; + // @public export function updateMetadata(ref: StorageReference, metadata: SettableMetadata): Promise; @@ -229,11 +310,9 @@ export class _UploadTask { catch(onRejected: (p1: FirebaseStorageError_2) => T | Promise): Promise; // Warning: (ae-forgotten-export) The symbol "Metadata" needs to be exported by the entry point index.d.ts _metadata: Metadata | null; - // Warning: (ae-forgotten-export) The symbol "TaskEvent" needs to be exported by the entry point index.d.ts - // Warning: (ae-forgotten-export) The symbol "FirebaseStorageError" needs to be exported by the entry point index.d.ts // Warning: (ae-forgotten-export) The symbol "Unsubscribe" needs to be exported by the entry point index.d.ts // Warning: (ae-forgotten-export) The symbol "Subscribe" needs to be exported by the entry point index.d.ts - on(type: TaskEvent_2, nextOrObserver?: StorageObserver | null | ((snapshot: UploadTaskSnapshot) => unknown), error?: ((a: FirebaseStorageError_2) => unknown) | null, completed?: Unsubscribe_2 | null): Unsubscribe_2 | Subscribe_2; + on(type: _TaskEvent, nextOrObserver?: StorageObserver | null | ((snapshot: UploadTaskSnapshot) => unknown), error?: ((a: FirebaseStorageError_2) => unknown) | null, completed?: Unsubscribe_2 | null): Unsubscribe_2 | Subscribe_2; pause(): boolean; resume(): boolean; get snapshot(): UploadTaskSnapshot; diff --git a/packages/storage-compat/.eslintrc.js b/packages/storage-compat/.eslintrc.js new file mode 100644 index 00000000000..00bf88df31c --- /dev/null +++ b/packages/storage-compat/.eslintrc.js @@ -0,0 +1,48 @@ +/** + * @license + * Copyright 2020 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. + */ + +const path = require('path'); + +module.exports = { + extends: '../../config/.eslintrc.js', + parserOptions: { + project: 'tsconfig.json', + // to make vscode-eslint work with monorepo + // https://github.com/typescript-eslint/typescript-eslint/issues/251#issuecomment-463943250 + tsconfigRootDir: __dirname + }, + rules: { + 'no-throw-literal': 'off', + '@typescript-eslint/no-unused-vars': [ + 'error', + { + varsIgnorePattern: '^_', + args: 'none' + } + ], + 'import/no-extraneous-dependencies': [ + 'error', + { + 'packageDir': [ + path.resolve(__dirname, '../../'), + __dirname, + path.resolve(__dirname, 'exp') + ] + } + ] + } +}; diff --git a/packages/storage-compat/.npmignore b/packages/storage-compat/.npmignore new file mode 100644 index 00000000000..682c8f74a52 --- /dev/null +++ b/packages/storage-compat/.npmignore @@ -0,0 +1,9 @@ +# Directories not needed by end users +/src +test + +# Files not needed by end users +gulpfile.js +index.ts +karma.conf.js +tsconfig.json \ No newline at end of file diff --git a/packages/storage-compat/README.md b/packages/storage-compat/README.md new file mode 100644 index 00000000000..7c1c82bd424 --- /dev/null +++ b/packages/storage-compat/README.md @@ -0,0 +1,5 @@ +# @firebase/storage + +This is the Cloud Storage component of the Firebase JS SDK. + +**This package is not intended for direct usage, and should only be used via the officially supported [firebase](https://www.npmjs.com/package/firebase) package.** diff --git a/packages/storage-compat/index.ts b/packages/storage-compat/index.ts deleted file mode 100644 index 774cdef15f0..00000000000 --- a/packages/storage-compat/index.ts +++ /dev/null @@ -1,88 +0,0 @@ -/** - * @license - * Copyright 2020 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 firebase from '@firebase/app'; -import { _FirebaseNamespace } from '@firebase/app-types/private'; -import { StringFormat } from '../storage/src/implementation/string'; -import { TaskEvent, TaskState } from '../storage/src/implementation/taskenums'; - -import { ConnectionPool } from '../storage/src/implementation/connectionPool'; -import { ReferenceCompat } from './compat/reference'; -import { StorageServiceCompat } from './compat/service'; -import { FirebaseStorageImpl } from '../storage/src/service'; -import * as types from '@firebase/storage-types'; -import { - Component, - ComponentType, - ComponentContainer, - InstanceFactoryOptions -} from '@firebase/component'; - -import { name, version } from '../storage/package.json'; - -import './register-module'; - -/** - * Type constant for Firebase Storage. - */ -const STORAGE_TYPE = 'storage'; - -function factory( - container: ComponentContainer, - { instanceIdentifier: url }: InstanceFactoryOptions -): types.FirebaseStorage { - // Dependencies - // TODO: This should eventually be 'app-compat' - const app = container.getProvider('app').getImmediate(); - const authProvider = container.getProvider('auth-internal'); - const appCheckProvider = container.getProvider('app-check-internal'); - - // TODO: get StorageService instance from component framework instead - // of creating a new one. - const storageServiceCompat: StorageServiceCompat = new StorageServiceCompat( - app, - new FirebaseStorageImpl( - app, - authProvider, - appCheckProvider, - new ConnectionPool(), - url, - firebase.SDK_VERSION - ) - ); - return storageServiceCompat; -} - -export function registerStorage(instance: _FirebaseNamespace): void { - const namespaceExports = { - // no-inline - TaskState, - TaskEvent, - StringFormat, - Storage: FirebaseStorageImpl, - Reference: ReferenceCompat - }; - instance.INTERNAL.registerComponent( - new Component(STORAGE_TYPE, factory, ComponentType.PUBLIC) - .setServiceProps(namespaceExports) - .setMultipleInstances(true) - ); - - instance.registerVersion(name, version); -} - -registerStorage(firebase as _FirebaseNamespace); diff --git a/packages/storage-compat/karma.conf.js b/packages/storage-compat/karma.conf.js new file mode 100644 index 00000000000..daa472b2fe2 --- /dev/null +++ b/packages/storage-compat/karma.conf.js @@ -0,0 +1,54 @@ +/** + * @license + * Copyright 2017 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. + */ + +const karmaBase = require('../../config/karma.base'); +const { argv } = require('yargs'); + +module.exports = function (config) { + const karmaConfig = Object.assign({}, karmaBase, { + // files to load into karma + files: getTestFiles(argv), + // frameworks to use + // available frameworks: https://npmjs.org/browse/keyword/karma-adapter + frameworks: ['mocha'] + }); + + config.set(karmaConfig); +}; + +function getTestFiles(argv) { + let unitTestFiles = ['test/unit/*']; + let integrationTestFiles = ['test/integration/*']; + + // if (argv.compat) { + // unitTestFiles = unitTestFiles.filter( + // filename => !filename.includes('.exp.') + // ); + // integrationTestFiles = ['test/integration/*compat*']; + // } else { + // integrationTestFiles = ['test/integration/*']; + // } + if (argv.unit) { + return unitTestFiles; + } else if (argv.integration) { + return integrationTestFiles; + } else { + return [...unitTestFiles, ...integrationTestFiles]; + } +} + +module.exports.files = getTestFiles(argv); diff --git a/packages/storage-compat/package.json b/packages/storage-compat/package.json index 0b292328b6f..67c3af92a36 100644 --- a/packages/storage-compat/package.json +++ b/packages/storage-compat/package.json @@ -1,22 +1,39 @@ { "name": "@firebase/storage-compat", "version": "0.1.0", - "description": "The Cloud Storage component of the Firebase JS SDK.", + "description": "The Firebase Firestore compatibility package", "author": "Firebase (https://firebase.google.com/)", - "main": "./dist/cjs/index.js", - "browser": "./dist/esm2017/index.js", - "module": "./dist/esm2017/index.js", - "esm5": "./dist/esm5/index.js", + "main": "./dist/index.cjs.js", + "browser": "./dist/index.esm2017.js", + "module": "./dist/index.esm2017.js", + "esm5": "./dist/index.esm5.js", "license": "Apache-2.0", - "typings": "./dist/esm2017/compat/index.d.ts", - "private": false, + "typings": "./dist/storage-compat/src/index.d.ts", + "scripts": { + "lint": "eslint -c .eslintrc.js '**/*.ts' --ignore-path '../../.gitignore'", + "lint:fix": "eslint --fix -c .eslintrc.js '**/*.ts' --ignore-path '../../.gitignore'", + "build": "rollup -c rollup.config.js", + "build:deps": "lerna run --scope @firebase/storage-compat --include-dependencies build", + "dev": "rollup -c -w", + "test": "run-p test:browser test:node lint", + "test:ci": "node ../../scripts/run_tests_in_ci.js -s test:browser test:node", + "test:browser:unit": "karma start --single-run --compat --unit", + "test:browser:integration": "karma start --single-run --compat --integration", + "test:browser": "karma start --single-run", + "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", + "test:debug": "karma start --browser=Chrome", + "prettier": "prettier --write 'src/**/*.ts' 'test/**/*.ts'", + "add-compat-overloads": "ts-node-script ../../scripts/exp/create-overloads.ts -i ../storage/dist/storage-public.d.ts -o dist/storage-compat/src/index.d.ts -a -r FirebaseStorage:types.FirebaseStorage -r StorageReference:types.Reference -r FirebaseApp:FirebaseAppCompat --moduleToEnhance @firebase/storage" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + }, "dependencies": { + "@firebase/storage": "0.6.1", "@firebase/storage-types": "0.4.1", "@firebase/util": "1.2.0", "@firebase/component": "0.5.5", - "node-fetch": "2.6.1", - "tslib": "^2.1.0", - "@firebase/storage": "0.0.900-exp.8b4d7550f" + "tslib": "^2.1.0" }, "files": [ "dist" diff --git a/packages/storage-compat/register-module.ts b/packages/storage-compat/register-module.ts deleted file mode 100644 index 23d09759347..00000000000 --- a/packages/storage-compat/register-module.ts +++ /dev/null @@ -1,50 +0,0 @@ -/** - * @license - * Copyright 2020 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 * as types from '@firebase/storage-types'; - -/** - * Define extension behavior for `registerStorage` - */ -declare module '@firebase/app-types' { - interface FirebaseNamespace { - storage?: { - (app?: FirebaseApp, url?: string): types.FirebaseStorage; - Storage: typeof types.FirebaseStorage; - - StringFormat: { - BASE64: types.StringFormat; - BASE64URL: types.StringFormat; - DATA_URL: types.StringFormat; - RAW: types.StringFormat; - }; - TaskEvent: { - STATE_CHANGED: types.TaskEvent; - }; - TaskState: { - CANCELED: types.TaskState; - ERROR: types.TaskState; - PAUSED: types.TaskState; - RUNNING: types.TaskState; - SUCCESS: types.TaskState; - }; - }; - } - interface FirebaseApp { - storage?(storageBucket?: string): types.FirebaseStorage; - } -} diff --git a/packages/storage-compat/rollup.config.compat.js b/packages/storage-compat/rollup.config.js similarity index 59% rename from packages/storage-compat/rollup.config.compat.js rename to packages/storage-compat/rollup.config.js index a1b6321157d..c696af6963e 100644 --- a/packages/storage-compat/rollup.config.compat.js +++ b/packages/storage-compat/rollup.config.js @@ -18,55 +18,37 @@ import json from '@rollup/plugin-json'; import typescriptPlugin from 'rollup-plugin-typescript2'; import typescript from 'typescript'; -import alias from '@rollup/plugin-alias'; import pkg from './package.json'; -import { getImportPathTransformer } from '../../scripts/exp/ts-transform-import-path'; - -const { generateAliasConfig } = require('./rollup.shared'); - -const deps = [ - ...Object.keys(Object.assign({}, pkg.peerDependencies, pkg.dependencies)), - '@firebase/storage' -]; +const deps = Object.keys(Object.assign({}, pkg.peerDependencies, pkg.dependencies)); /** * ES5 Builds */ const es5BuildPlugins = [ typescriptPlugin({ typescript, - abortOnError: false, - transformers: [ - getImportPathTransformer({ - // ../exp/index - pattern: /^.*exp\/api$/, - template: ['@firebase/storage'] - }) - ] + abortOnError: false }), json() ]; const es5Builds = [ { - input: './compat/index.ts', + input: './src/index.ts', output: [ { - dir: 'dist/compat/cjs', + file: pkg.main, format: 'cjs', sourcemap: true }, { - dir: 'dist/compat/esm5', + file: pkg.esm5, format: 'es', sourcemap: true } ], - plugins: [alias(generateAliasConfig('browser')), ...es5BuildPlugins], - external: id => deps.some(dep => id === dep || id.startsWith(`${dep}/`)), - treeshake: { - moduleSideEffects: false - } + plugins: [...es5BuildPlugins], + external: id => deps.some(dep => id === dep || id.startsWith(`${dep}/`)) } ]; @@ -77,13 +59,6 @@ const es2017BuildPlugins = [ typescriptPlugin({ typescript, abortOnError: false, - transformers: [ - getImportPathTransformer({ - // ../exp/index - pattern: /^.*exp\/api$/, - template: ['@firebase/storage'] - }) - ], tsconfigOverride: { compilerOptions: { target: 'es2017' @@ -95,17 +70,14 @@ const es2017BuildPlugins = [ const es2017Builds = [ { - input: './compat/index.ts', + input: './src/index.ts', output: { - dir: 'dist/compat/esm2017', + file: pkg.browser, format: 'es', sourcemap: true }, - plugins: [alias(generateAliasConfig('browser')), ...es2017BuildPlugins], - external: id => deps.some(dep => id === dep || id.startsWith(`${dep}/`)), - treeshake: { - moduleSideEffects: false - } + plugins: [...es2017BuildPlugins], + external: id => deps.some(dep => id === dep || id.startsWith(`${dep}/`)) } ]; diff --git a/packages/storage-compat/src/index.ts b/packages/storage-compat/src/index.ts index 12fc1067a18..00e3d24c90e 100644 --- a/packages/storage-compat/src/index.ts +++ b/packages/storage-compat/src/index.ts @@ -18,11 +18,7 @@ // eslint-disable-next-line import/no-extraneous-dependencies import firebase from '@firebase/app-compat'; import { _FirebaseNamespace } from '@firebase/app-types/private'; -import { StringFormat } from '../../storage/src/implementation/string'; -import { - TaskEvent, - TaskState -} from '../../storage/src/implementation/taskenums'; +import { StringFormat, _TaskEvent as TaskEvent, _TaskState as TaskState} from '@firebase/storage'; import { ReferenceCompat } from './reference'; import { StorageServiceCompat } from './service'; @@ -34,12 +30,12 @@ import { InstanceFactoryOptions } from '@firebase/component'; -import { name, version } from '../../storage/compat/package.json'; +import { name, version } from '../package.json'; /** * Type constant for Firebase Storage. */ -const STORAGE_TYPE = 'storage'; +const STORAGE_TYPE = 'storage-compat'; function factory( container: ComponentContainer, @@ -48,7 +44,7 @@ function factory( // Dependencies const app = container.getProvider('app-compat').getImmediate(); const storageExp = container - .getProvider('storage-exp') + .getProvider('storage') .getImmediate({ identifier: url }); const storageServiceCompat: StorageServiceCompat = new StorageServiceCompat( diff --git a/packages/storage-compat/src/list.ts b/packages/storage-compat/src/list.ts index da394d20849..60c6a3b34e1 100644 --- a/packages/storage-compat/src/list.ts +++ b/packages/storage-compat/src/list.ts @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { ListResult } from '../exp/api'; +import { ListResult } from '@firebase/storage'; import * as types from '@firebase/storage-types'; import { ReferenceCompat } from './reference'; import { StorageServiceCompat } from './service'; diff --git a/packages/storage-compat/src/reference.ts b/packages/storage-compat/src/reference.ts index 527189ed659..8fb9eef41f5 100644 --- a/packages/storage-compat/src/reference.ts +++ b/packages/storage-compat/src/reference.ts @@ -26,20 +26,22 @@ import { deleteObject, UploadTask, StringFormat, + UploadMetadata, + FullMetadata, + SettableMetadata, _UploadTask, _getChild, _Reference, - _FbsBlob -} from '../exp/api'; // import from the exp public API + _FbsBlob, + _dataFromString, + _invalidRootOperation +} from '@firebase/storage'; // import from the exp public API import { UploadTaskCompat } from './task'; import { ListResultCompat } from './list'; import { StorageServiceCompat } from './service'; import * as types from '@firebase/storage-types'; -import { Metadata } from '../src/metadata'; -import { dataFromString } from '../src/implementation/string'; -import { invalidRootOperation } from '../src/implementation/error'; import { Compat } from '@firebase/util'; export class ReferenceCompat @@ -104,7 +106,7 @@ export class ReferenceCompat ): types.UploadTask { this._throwIfRoot('put'); return new UploadTaskCompat( - uploadBytesResumable(this._delegate, data, metadata as Metadata), + uploadBytesResumable(this._delegate, data, metadata as UploadMetadata), this ); } @@ -119,11 +121,11 @@ export class ReferenceCompat putString( value: string, format: StringFormat = StringFormat.RAW, - metadata?: Metadata + metadata?: types.UploadMetadata ): types.UploadTask { this._throwIfRoot('putString'); - const data = dataFromString(format, value); - const metadataClone = { ...metadata } as Metadata; + const data = _dataFromString(format, value); + const metadataClone = { ...metadata }; if (metadataClone['contentType'] == null && data.contentType != null) { metadataClone['contentType'] = data.contentType; } @@ -131,7 +133,7 @@ export class ReferenceCompat new _UploadTask( this._delegate as _Reference, new _FbsBlob(data.data, true), - metadataClone + metadataClone as FullMetadata & { [k: string]: string} ) as UploadTask, this ); @@ -208,7 +210,7 @@ export class ReferenceCompat ): Promise { return updateMetadata( this._delegate, - metadata as Metadata + metadata as SettableMetadata ) as Promise; } @@ -231,7 +233,7 @@ export class ReferenceCompat private _throwIfRoot(name: string): void { if ((this._delegate as _Reference)._location.path === '') { - throw invalidRootOperation(name); + throw _invalidRootOperation(name); } } } diff --git a/packages/storage-compat/src/service.ts b/packages/storage-compat/src/service.ts index 8eeade12257..be51181e76b 100644 --- a/packages/storage-compat/src/service.ts +++ b/packages/storage-compat/src/service.ts @@ -20,13 +20,13 @@ import { FirebaseApp } from '@firebase/app-types'; import { ref, - _Location, connectStorageEmulator, - FirebaseStorage -} from '../exp/api'; // import from the exp public API + FirebaseStorage, + _Location, + _invalidArgument, + _FirebaseStorageImpl +} from '@firebase/storage'; // import from the exp public API import { ReferenceCompat } from './reference'; -import { isUrl, FirebaseStorageImpl } from '../src/service'; -import { invalidArgument } from '../src/implementation/error'; import { Compat } from '@firebase/util'; /** @@ -52,7 +52,7 @@ export class StorageServiceCompat */ ref(path?: string): types.Reference { if (isUrl(path)) { - throw invalidArgument( + throw _invalidArgument( 'ref() expected a child path but got a URL, use refFromURL instead.' ); } @@ -65,14 +65,14 @@ export class StorageServiceCompat */ refFromURL(url: string): types.Reference { if (!isUrl(url)) { - throw invalidArgument( + throw _invalidArgument( 'refFromURL() expected a full URL but got a child path, use ref() instead.' ); } try { - _Location.makeFromUrl(url, (this._delegate as FirebaseStorageImpl).host); + _Location.makeFromUrl(url, (this._delegate as _FirebaseStorageImpl).host); } catch (e) { - throw invalidArgument( + throw _invalidArgument( 'refFromUrl() expected a valid full URL but got an invalid one.' ); } @@ -91,3 +91,7 @@ export class StorageServiceCompat connectStorageEmulator(this._delegate, host, port); } } + +function isUrl(path?: string): boolean { + return /^[A-Za-z]+:\/\//.test(path as string); +} \ No newline at end of file diff --git a/packages/storage-compat/src/task.ts b/packages/storage-compat/src/task.ts index a358c47c40a..13fcc6e8d03 100644 --- a/packages/storage-compat/src/task.ts +++ b/packages/storage-compat/src/task.ts @@ -21,7 +21,7 @@ import { UploadTaskSnapshot, TaskEvent, StorageObserver -} from '../exp/api'; +} from '@firebase/storage'; import { UploadTaskSnapshotCompat } from './tasksnapshot'; import { ReferenceCompat } from './reference'; import * as types from '@firebase/storage-types'; diff --git a/packages/storage-compat/src/tasksnapshot.ts b/packages/storage-compat/src/tasksnapshot.ts index 841dded18e7..9faaa3485e9 100644 --- a/packages/storage-compat/src/tasksnapshot.ts +++ b/packages/storage-compat/src/tasksnapshot.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { UploadTaskSnapshot } from '../exp/api'; +import { UploadTaskSnapshot } from '@firebase/storage'; import { ReferenceCompat } from './reference'; import { UploadTaskCompat } from './task'; import * as types from '@firebase/storage-types'; diff --git a/packages/storage-compat/tsconfig.json b/packages/storage-compat/tsconfig.json new file mode 100644 index 00000000000..a06ed9a374c --- /dev/null +++ b/packages/storage-compat/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../config/tsconfig.base.json", + "compilerOptions": { + "outDir": "dist" + }, + "exclude": [ + "dist/**/*" + ] +} \ No newline at end of file diff --git a/packages/storage-types/index.d.ts b/packages/storage-types/index.d.ts index 735d8c32278..ee78fab6f26 100644 --- a/packages/storage-types/index.d.ts +++ b/packages/storage-types/index.d.ts @@ -140,6 +140,6 @@ export class FirebaseStorage { declare module '@firebase/component' { interface NameServiceMapping { - 'storage': FirebaseStorage; + 'storage-compat': FirebaseStorage; } } diff --git a/packages/storage/api-extractor.json b/packages/storage/api-extractor.json index e652744d245..8a3c6cb251e 100644 --- a/packages/storage/api-extractor.json +++ b/packages/storage/api-extractor.json @@ -1,7 +1,7 @@ { "extends": "../../config/api-extractor.json", // Point it to your entry point d.ts file. - "mainEntryPointFilePath": "/dist/storage/src/index.d.ts", + "mainEntryPointFilePath": "/dist/src/index.d.ts", "dtsRollup": { "enabled": true, "untrimmedFilePath": "/dist/.d.ts", diff --git a/packages/storage/package.json b/packages/storage/package.json index 46e4c388f2d..07dbfafcbc1 100644 --- a/packages/storage/package.json +++ b/packages/storage/package.json @@ -16,7 +16,6 @@ "lint": "eslint -c .eslintrc.js '**/*.ts' --ignore-path '../../.gitignore'", "lint:fix": "eslint --fix -c .eslintrc.js '**/*.ts' --ignore-path '../../.gitignore'", "build": "rollup -c rollup.config.js && yarn api-report", - "build:compat": "rollup -c rollup.config.compat.js && yarn add-compat-overloads", "build:deps": "lerna run --scope @firebase/storage --include-dependencies build", "dev": "rollup -c -w", "test": "run-p test:browser test:node lint", @@ -31,8 +30,7 @@ "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", "test:debug": "karma start --browser=Chrome", "prettier": "prettier --write 'src/**/*.ts' 'test/**/*.ts'", - "api-report": "api-extractor run --local --verbose && ts-node-script ../../repo-scripts/prune-dts/prune-dts.ts --input dist/storage-public.d.ts --output dist/storage-public.d.ts", - "add-compat-overloads": "ts-node-script ../../scripts/exp/create-overloads.ts -i exp/dist/storage-public.d.ts -o dist/compat/esm2017/compat/index.d.ts -a -r StorageService:types.FirebaseStorage -r StorageReference:types.Reference -r FirebaseApp:FirebaseAppCompat --moduleToEnhance @firebase/storage" + "api-report": "api-extractor run --local --verbose && ts-node-script ../../repo-scripts/prune-dts/prune-dts.ts --input dist/storage-public.d.ts --output dist/storage-public.d.ts" }, "license": "Apache-2.0", "dependencies": { @@ -62,5 +60,5 @@ "bugs": { "url": "https://github.com/firebase/firebase-js-sdk/issues" }, - "typings": "dist/index.d.ts" + "typings": "dist/storage.d.ts" } diff --git a/packages/storage/src/api.ts b/packages/storage/src/api.ts index fbfbbc3abdb..fa081b85263 100644 --- a/packages/storage/src/api.ts +++ b/packages/storage/src/api.ts @@ -60,7 +60,11 @@ export * from './public-types'; export { Location as _Location } from './implementation/location'; export { UploadTask as _UploadTask } from './task'; export type { Reference as _Reference } from './reference'; +export type { FirebaseStorageImpl as _FirebaseStorageImpl } from './service'; export { FbsBlob as _FbsBlob } from './implementation/blob'; +export { dataFromString as _dataFromString } from './implementation/string'; +export { invalidRootOperation as _invalidRootOperation, invalidArgument as _invalidArgument } from './implementation/error'; +export { TaskEvent as _TaskEvent, TaskState as _TaskState } from './implementation/taskenums'; /** * Uploads data to this object's location. diff --git a/packages/storage/src/implementation/error.ts b/packages/storage/src/implementation/error.ts index 41a29fd5dff..c589c106504 100644 --- a/packages/storage/src/implementation/error.ts +++ b/packages/storage/src/implementation/error.ts @@ -250,6 +250,9 @@ export function noDownloadURL(): FirebaseStorageError { ); } +/** + * @internal + */ export function invalidArgument(message: string): FirebaseStorageError { return new FirebaseStorageError(StorageErrorCode.INVALID_ARGUMENT, message); } @@ -292,6 +295,8 @@ export function appDeleted(): FirebaseStorageError { /** * @param name - The name of the operation that was invalid. + * + * @internal */ export function invalidRootOperation(name: string): FirebaseStorageError { return new FirebaseStorageError( diff --git a/packages/storage/src/implementation/string.ts b/packages/storage/src/implementation/string.ts index ea9ba2dc275..8497190389f 100644 --- a/packages/storage/src/implementation/string.ts +++ b/packages/storage/src/implementation/string.ts @@ -70,6 +70,9 @@ export class StringData { } } +/** + * @internal + */ export function dataFromString( format: StringFormat, stringData: string From 40dbf779b19290e0015430e9f717b1a8e9b4833f Mon Sep 17 00:00:00 2001 From: Feiyang1 Date: Fri, 6 Aug 2021 16:43:12 -0700 Subject: [PATCH 06/22] save --- packages/storage-compat/rollup.config.js | 4 +++- packages/storage-compat/src/index.ts | 6 +++++- packages/storage-compat/src/reference.ts | 2 +- packages/storage-compat/src/service.ts | 2 +- packages/storage/src/api.ts | 10 ++++++++-- packages/storage/src/implementation/error.ts | 2 +- 6 files changed, 19 insertions(+), 7 deletions(-) diff --git a/packages/storage-compat/rollup.config.js b/packages/storage-compat/rollup.config.js index c696af6963e..c220eb88893 100644 --- a/packages/storage-compat/rollup.config.js +++ b/packages/storage-compat/rollup.config.js @@ -20,7 +20,9 @@ import typescriptPlugin from 'rollup-plugin-typescript2'; import typescript from 'typescript'; import pkg from './package.json'; -const deps = Object.keys(Object.assign({}, pkg.peerDependencies, pkg.dependencies)); +const deps = Object.keys( + Object.assign({}, pkg.peerDependencies, pkg.dependencies) +); /** * ES5 Builds */ diff --git a/packages/storage-compat/src/index.ts b/packages/storage-compat/src/index.ts index 00e3d24c90e..a4d7e913f3d 100644 --- a/packages/storage-compat/src/index.ts +++ b/packages/storage-compat/src/index.ts @@ -18,7 +18,11 @@ // eslint-disable-next-line import/no-extraneous-dependencies import firebase from '@firebase/app-compat'; import { _FirebaseNamespace } from '@firebase/app-types/private'; -import { StringFormat, _TaskEvent as TaskEvent, _TaskState as TaskState} from '@firebase/storage'; +import { + StringFormat, + _TaskEvent as TaskEvent, + _TaskState as TaskState +} from '@firebase/storage'; import { ReferenceCompat } from './reference'; import { StorageServiceCompat } from './service'; diff --git a/packages/storage-compat/src/reference.ts b/packages/storage-compat/src/reference.ts index 8fb9eef41f5..9d6bb19ee95 100644 --- a/packages/storage-compat/src/reference.ts +++ b/packages/storage-compat/src/reference.ts @@ -133,7 +133,7 @@ export class ReferenceCompat new _UploadTask( this._delegate as _Reference, new _FbsBlob(data.data, true), - metadataClone as FullMetadata & { [k: string]: string} + metadataClone as FullMetadata & { [k: string]: string } ) as UploadTask, this ); diff --git a/packages/storage-compat/src/service.ts b/packages/storage-compat/src/service.ts index be51181e76b..1fe5aeb6160 100644 --- a/packages/storage-compat/src/service.ts +++ b/packages/storage-compat/src/service.ts @@ -94,4 +94,4 @@ export class StorageServiceCompat function isUrl(path?: string): boolean { return /^[A-Za-z]+:\/\//.test(path as string); -} \ No newline at end of file +} diff --git a/packages/storage/src/api.ts b/packages/storage/src/api.ts index fa081b85263..5ffb2ffcd30 100644 --- a/packages/storage/src/api.ts +++ b/packages/storage/src/api.ts @@ -63,8 +63,14 @@ export type { Reference as _Reference } from './reference'; export type { FirebaseStorageImpl as _FirebaseStorageImpl } from './service'; export { FbsBlob as _FbsBlob } from './implementation/blob'; export { dataFromString as _dataFromString } from './implementation/string'; -export { invalidRootOperation as _invalidRootOperation, invalidArgument as _invalidArgument } from './implementation/error'; -export { TaskEvent as _TaskEvent, TaskState as _TaskState } from './implementation/taskenums'; +export { + invalidRootOperation as _invalidRootOperation, + invalidArgument as _invalidArgument +} from './implementation/error'; +export { + TaskEvent as _TaskEvent, + TaskState as _TaskState +} from './implementation/taskenums'; /** * Uploads data to this object's location. diff --git a/packages/storage/src/implementation/error.ts b/packages/storage/src/implementation/error.ts index c589c106504..a603237b455 100644 --- a/packages/storage/src/implementation/error.ts +++ b/packages/storage/src/implementation/error.ts @@ -295,7 +295,7 @@ export function appDeleted(): FirebaseStorageError { /** * @param name - The name of the operation that was invalid. - * + * * @internal */ export function invalidRootOperation(name: string): FirebaseStorageError { From 6d99fb44e23692f48cbf2a9053911bf4b1e08009 Mon Sep 17 00:00:00 2001 From: Feiyang1 Date: Tue, 10 Aug 2021 00:09:15 -0700 Subject: [PATCH 07/22] fixing some compat tests --- common/api-review/storage.api.md | 4 +- packages/storage-compat/karma.conf.js | 8 - packages/storage-compat/package.json | 9 +- ...ion.compat.test.ts => integration.test.ts} | 6 +- packages/storage-compat/test/setup.ts | 28 ++ .../{index.compat.test.ts => index.test.ts} | 12 +- .../test/unit/reference.compat.test.ts | 315 --------------- .../test/unit/reference.test.ts | 318 +++++++++++++++ .../test/unit/service.compat.test.ts | 370 ------------------ .../storage-compat/test/unit/service.test.ts | 195 +++++++++ packages/storage-compat/test/utils.ts | 14 + packages/storage/package.json | 4 +- packages/storage/rollup.config.js | 8 +- packages/storage/test/unit/service.test.ts | 25 ++ 14 files changed, 603 insertions(+), 713 deletions(-) rename packages/storage-compat/test/integration/{integration.compat.test.ts => integration.test.ts} (97%) create mode 100644 packages/storage-compat/test/setup.ts rename packages/storage-compat/test/unit/{index.compat.test.ts => index.test.ts} (84%) delete mode 100644 packages/storage-compat/test/unit/reference.compat.test.ts create mode 100644 packages/storage-compat/test/unit/reference.test.ts delete mode 100644 packages/storage-compat/test/unit/service.compat.test.ts create mode 100644 packages/storage-compat/test/unit/service.test.ts create mode 100644 packages/storage-compat/test/utils.ts diff --git a/common/api-review/storage.api.md b/common/api-review/storage.api.md index 23294f713b6..45c13854e59 100644 --- a/common/api-review/storage.api.md +++ b/common/api-review/storage.api.md @@ -6,10 +6,10 @@ import { AppCheckInternalComponentName } from '@firebase/app-check-interop-types'; import { CompleteFn } from '@firebase/util'; -import { FirebaseApp } from '@firebase/app'; +import { FirebaseApp } from '@firebase/app-exp'; import { FirebaseAuthInternalName } from '@firebase/auth-interop-types'; import { FirebaseError } from '@firebase/util'; -import { _FirebaseService } from '@firebase/app'; +import { _FirebaseService } from '@firebase/app-exp'; import { NextFn } from '@firebase/util'; import { Provider } from '@firebase/component'; import { Subscribe } from '@firebase/util'; diff --git a/packages/storage-compat/karma.conf.js b/packages/storage-compat/karma.conf.js index daa472b2fe2..3b5d7e3f39b 100644 --- a/packages/storage-compat/karma.conf.js +++ b/packages/storage-compat/karma.conf.js @@ -34,14 +34,6 @@ function getTestFiles(argv) { let unitTestFiles = ['test/unit/*']; let integrationTestFiles = ['test/integration/*']; - // if (argv.compat) { - // unitTestFiles = unitTestFiles.filter( - // filename => !filename.includes('.exp.') - // ); - // integrationTestFiles = ['test/integration/*compat*']; - // } else { - // integrationTestFiles = ['test/integration/*']; - // } if (argv.unit) { return unitTestFiles; } else if (argv.integration) { diff --git a/packages/storage-compat/package.json b/packages/storage-compat/package.json index 67c3af92a36..955157b9eae 100644 --- a/packages/storage-compat/package.json +++ b/packages/storage-compat/package.json @@ -20,7 +20,7 @@ "test:browser:unit": "karma start --single-run --compat --unit", "test:browser:integration": "karma start --single-run --compat --integration", "test:browser": "karma start --single-run", - "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", + "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 src/index.ts --config ../../config/mocharc.node.js", "test:debug": "karma start --browser=Chrome", "prettier": "prettier --write 'src/**/*.ts' 'test/**/*.ts'", "add-compat-overloads": "ts-node-script ../../scripts/exp/create-overloads.ts -i ../storage/dist/storage-public.d.ts -o dist/storage-compat/src/index.d.ts -a -r FirebaseStorage:types.FirebaseStorage -r StorageReference:types.Reference -r FirebaseApp:FirebaseAppCompat --moduleToEnhance @firebase/storage" @@ -35,6 +35,13 @@ "@firebase/component": "0.5.5", "tslib": "^2.1.0" }, + "devDependencies": { + "rollup": "2.52.2", + "@rollup/plugin-alias": "3.1.2", + "@rollup/plugin-json": "4.1.0", + "rollup-plugin-typescript2": "0.30.0", + "typescript": "4.2.2" + }, "files": [ "dist" ] diff --git a/packages/storage-compat/test/integration/integration.compat.test.ts b/packages/storage-compat/test/integration/integration.test.ts similarity index 97% rename from packages/storage-compat/test/integration/integration.compat.test.ts rename to packages/storage-compat/test/integration/integration.test.ts index e2b5c6f8508..e217781f5a6 100644 --- a/packages/storage-compat/test/integration/integration.compat.test.ts +++ b/packages/storage-compat/test/integration/integration.test.ts @@ -15,15 +15,15 @@ * limitations under the License. */ -import firebase from '@firebase/app'; -import '@firebase/auth'; +import firebase from '@firebase/app-compat'; +import '@firebase/auth-compat'; // See https://github.com/typescript-eslint/typescript-eslint/issues/363 // eslint-disable-next-line @typescript-eslint/no-unused-vars import * as storage from '@firebase/storage-types'; import { expect } from 'chai'; -import '../../index'; +import '../../src/index'; // eslint-disable-next-line @typescript-eslint/no-require-imports const PROJECT_CONFIG = require('../../../../config/project.json'); diff --git a/packages/storage-compat/test/setup.ts b/packages/storage-compat/test/setup.ts new file mode 100644 index 00000000000..22ed9b0d112 --- /dev/null +++ b/packages/storage-compat/test/setup.ts @@ -0,0 +1,28 @@ +/** + * @license + * Copyright 2019 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 { use } from 'chai'; +import { restore } from 'sinon'; +import * as sinonChai from 'sinon-chai'; +import * as chaiAsPromised from 'chai-as-promised'; + +use(chaiAsPromised); +use(sinonChai); + +afterEach(async () => { + restore(); +}); diff --git a/packages/storage-compat/test/unit/index.compat.test.ts b/packages/storage-compat/test/unit/index.test.ts similarity index 84% rename from packages/storage-compat/test/unit/index.compat.test.ts rename to packages/storage-compat/test/unit/index.test.ts index a4346a92349..23ee39ca483 100644 --- a/packages/storage-compat/test/unit/index.compat.test.ts +++ b/packages/storage-compat/test/unit/index.test.ts @@ -15,11 +15,11 @@ * limitations under the License. */ import { expect } from 'chai'; -import '../../index'; -import firebase from '@firebase/app'; +import '../../src/index'; +import firebase from '@firebase/app-compat'; // eslint-disable-next-line import/no-extraneous-dependencies -import { StorageServiceCompat } from '../../compat/service'; -import { FirebaseStorageImpl } from '../../../storage/src/service'; +import { StorageServiceCompat } from '../../src/service'; +import { _FirebaseStorageImpl } from '@firebase/storage'; // eslint-disable-next-line @typescript-eslint/no-require-imports const PROJECT_CONFIG = require('../../../../config/project.json'); @@ -39,7 +39,7 @@ describe('Firebase Storage > API', () => { }); const storage = firebase.storage!(); expect( - ((storage as StorageServiceCompat)._delegate as FirebaseStorageImpl) + ((storage as StorageServiceCompat)._delegate as _FirebaseStorageImpl) ._bucket?.bucket ).to.equal(STORAGE_BUCKET); await app.delete(); @@ -53,7 +53,7 @@ describe('Firebase Storage > API', () => { }); const storage = firebase.storage!(app, 'gs://foo-bar.appspot.com'); expect( - ((storage as StorageServiceCompat)._delegate as FirebaseStorageImpl) + ((storage as StorageServiceCompat)._delegate as _FirebaseStorageImpl) ._bucket?.bucket ).to.equal(STORAGE_BUCKET); await app.delete(); diff --git a/packages/storage-compat/test/unit/reference.compat.test.ts b/packages/storage-compat/test/unit/reference.compat.test.ts deleted file mode 100644 index bc725558d08..00000000000 --- a/packages/storage-compat/test/unit/reference.compat.test.ts +++ /dev/null @@ -1,315 +0,0 @@ -/** - * @license - * Copyright 2020 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 { FirebaseApp } from '@firebase/app-types'; -import { StringFormat } from '../../src/implementation/string'; -import { Headers } from '../../src/implementation/connection'; -import { Metadata } from '../../src/metadata'; -import { ReferenceCompat } from '../../compat/reference'; -import { StorageServiceCompat } from '../../compat/service'; -import * as testShared from './testshared'; -import { SendHook, TestingConnection } from './connection'; -import { DEFAULT_HOST } from '../../src/implementation/constants'; -import { FirebaseAuthInternalName } from '@firebase/auth-interop-types'; -import { Provider } from '@firebase/component'; -import { FirebaseStorageImpl } from '../../src/service'; -import { Reference } from '../../src/reference'; -import { AppCheckInternalComponentName } from '@firebase/app-check-interop-types'; - -/* eslint-disable @typescript-eslint/no-floating-promises */ -function makeFakeService( - app: FirebaseApp, - authProvider: Provider, - appCheckProvider: Provider, - sendHook: SendHook -): StorageServiceCompat { - const storageServiceCompat: StorageServiceCompat = new StorageServiceCompat( - app, - new FirebaseStorageImpl( - app, - authProvider, - appCheckProvider, - testShared.makePool(sendHook) - ) - ); - return storageServiceCompat; -} - -function makeStorage(url: string): ReferenceCompat { - const service = new FirebaseStorageImpl( - {} as FirebaseApp, - testShared.emptyAuthProvider, - testShared.fakeAppCheckTokenProvider, - testShared.makePool(null) - ); - const storageServiceCompat: StorageServiceCompat = new StorageServiceCompat( - {} as FirebaseApp, - service - ); - return new ReferenceCompat(new Reference(service, url), storageServiceCompat); -} - -describe('Firebase Storage > Reference', () => { - const root = makeStorage('gs://test-bucket/'); - const child = makeStorage('gs://test-bucket/hello'); - describe('Path constructor', () => { - it('root', () => { - expect(root.toString()).to.equal('gs://test-bucket/'); - }); - it('keeps characters after ? on a gs:// string', () => { - const s = makeStorage('gs://test-bucket/this/ismyobject?hello'); - expect(s.toString()).to.equal('gs://test-bucket/this/ismyobject?hello'); - }); - it("doesn't URL-decode on a gs:// string", () => { - const s = makeStorage('gs://test-bucket/%3F'); - expect(s.toString()).to.equal('gs://test-bucket/%3F'); - }); - it('ignores URL params and fragments on an http URL', () => { - const s = makeStorage( - `http://${DEFAULT_HOST}/v0/b/test-bucket/o/my/object.txt` + - '?ignoreme#please' - ); - expect(s.toString()).to.equal('gs://test-bucket/my/object.txt'); - }); - it('URL-decodes and ignores fragment on an http URL', () => { - const s = makeStorage( - `http://${DEFAULT_HOST}/v0/b/test-bucket/o/%3F?ignore` - ); - expect(s.toString()).to.equal('gs://test-bucket/?'); - }); - - it('ignores URL params and fragments on an https URL', () => { - const s = makeStorage( - `https://${DEFAULT_HOST}/v0/b/test-bucket/o/my/object.txt` + - '?ignoreme#please' - ); - expect(s.toString()).to.equal('gs://test-bucket/my/object.txt'); - }); - - it('URL-decodes and ignores fragment on an https URL', () => { - const s = makeStorage( - `https://${DEFAULT_HOST}/v0/b/test-bucket/o/%3F?ignore` - ); - expect(s.toString()).to.equal('gs://test-bucket/?'); - }); - }); - - describe('toString', () => { - it("Doesn't add trailing slash", () => { - const s = makeStorage('gs://test-bucket/foo'); - expect(s.toString()).to.equal('gs://test-bucket/foo'); - }); - it('Strips trailing slash', () => { - const s = makeStorage('gs://test-bucket/foo/'); - expect(s.toString()).to.equal('gs://test-bucket/foo'); - }); - }); - - describe('parent', () => { - it('Returns null at root', () => { - expect(root.parent).to.be.null; - }); - it('Returns root one level down', () => { - expect(child.parent!.toString()).to.equal('gs://test-bucket/'); - }); - it('Works correctly with empty levels', () => { - const s = makeStorage('gs://test-bucket/a///'); - expect(s.parent!.toString()).to.equal('gs://test-bucket/a/'); - }); - }); - - describe('root', () => { - it('Returns self at root', () => { - expect(root.root.toString()).to.equal('gs://test-bucket/'); - }); - - it('Returns root multiple levels down', () => { - const s = makeStorage('gs://test-bucket/a/b/c/d'); - expect(s.root.toString()).to.equal('gs://test-bucket/'); - }); - }); - - describe('bucket', () => { - it('Returns bucket name', () => { - expect(root.bucket).to.equal('test-bucket'); - }); - }); - - describe('fullPath', () => { - it('Returns full path without leading slash', () => { - const s = makeStorage('gs://test-bucket/full/path'); - expect(s.fullPath).to.equal('full/path'); - }); - }); - - describe('name', () => { - it('Works at top level', () => { - const s = makeStorage('gs://test-bucket/toplevel.txt'); - expect(s.name).to.equal('toplevel.txt'); - }); - - it('Works at not the top level', () => { - const s = makeStorage('gs://test-bucket/not/toplevel.txt'); - expect('toplevel.txt').to.equal(s.name); - }); - }); - - describe('child', () => { - it('works with a simple string', () => { - expect(root.child('a').toString()).to.equal('gs://test-bucket/a'); - }); - it('drops a trailing slash', () => { - expect(root.child('ab/').toString()).to.equal('gs://test-bucket/ab'); - }); - it('compresses repeated slashes', () => { - expect(root.child('//a///b/////').toString()).to.equal( - 'gs://test-bucket/a/b' - ); - }); - it('works chained multiple times with leading slashes', () => { - expect( - root.child('a').child('/b').child('c').child('d/e').toString() - ).to.equal('gs://test-bucket/a/b/c/d/e'); - }); - }); - - it("Doesn't send Authorization on null auth token", done => { - function newSend( - connection: TestingConnection, - url: string, - method: string, - body?: ArrayBufferView | Blob | string | null, - headers?: Headers - ): void { - expect(headers).to.not.be.undefined; - expect(headers!['Authorization']).to.be.undefined; - done(); - } - - const service = makeFakeService( - testShared.fakeApp, - testShared.emptyAuthProvider, - testShared.fakeAppCheckTokenProvider, - newSend - ); - const ref = service.refFromURL('gs://test-bucket'); - ref.child('foo').getMetadata(); - }); - - it('Works if the user logs in before creating the storage reference', done => { - // Regression test for b/27227221 - function newSend( - connection: TestingConnection, - url: string, - method: string, - body?: ArrayBufferView | Blob | string | null, - headers?: Headers - ): void { - expect(headers).to.not.be.undefined; - expect(headers!['Authorization']).to.equal( - 'Firebase ' + testShared.authToken - ); - done(); - } - - const service = makeFakeService( - testShared.fakeApp, - testShared.fakeAuthProvider, - testShared.fakeAppCheckTokenProvider, - newSend - ); - const ref = service.refFromURL('gs://test-bucket'); - ref.child('foo').getMetadata(); - }); - - describe('putString', () => { - it('Uses metadata.contentType for RAW format', () => { - // Regression test for b/30989476 - const task = child.putString('hello', StringFormat.RAW, { - contentType: 'lol/wut' - } as Metadata); - expect(task.snapshot.metadata!.contentType).to.equal('lol/wut'); - task.cancel(); - }); - it('Uses embedded content type in DATA_URL format', () => { - const task = child.putString( - 'data:lol/wat;base64,aaaa', - StringFormat.DATA_URL - ); - expect(task.snapshot.metadata!.contentType).to.equal('lol/wat'); - task.cancel(); - }); - it('Lets metadata.contentType override embedded content type in DATA_URL format', () => { - const task = child.putString( - 'data:ignore/me;base64,aaaa', - StringFormat.DATA_URL, - { contentType: 'tomato/soup' } as Metadata - ); - expect(task.snapshot.metadata!.contentType).to.equal('tomato/soup'); - task.cancel(); - }); - }); - - describe('Argument verification', () => { - describe('list', () => { - it('throws on invalid maxResults', () => { - it('throws on invalid maxResults', async () => { - await expect(child.list({ maxResults: 0 })).to.be.rejectedWith( - 'storage/invalid-argument' - ); - await expect(child.list({ maxResults: -4 })).to.be.rejectedWith( - 'storage/invalid-argument' - ); - await expect(child.list({ maxResults: 1001 })).to.be.rejectedWith( - 'storage/invalid-argument' - ); - }); - }); - }); - }); - - describe('root operations', () => { - it('put throws', () => { - expect(() => root.put(new Uint8Array())).to.throw( - 'storage/invalid-root-operation' - ); - }); - it('putString throws', () => { - expect(() => root.putString('raw', StringFormat.RAW)).to.throw( - 'storage/invalid-root-operation' - ); - }); - it('delete throws', () => { - expect(() => root.delete()).to.throw('storage/invalid-root-operation'); - }); - it('getMetadata throws', async () => { - await expect(root.getMetadata()).to.be.rejectedWith( - 'storage/invalid-root-operation' - ); - }); - it('updateMetadata throws', async () => { - await expect(root.updateMetadata({} as Metadata)).to.be.rejectedWith( - 'storage/invalid-root-operation' - ); - }); - it('getDownloadURL throws', async () => { - await expect(root.getDownloadURL()).to.be.rejectedWith( - 'storage/invalid-root-operation' - ); - }); - }); -}); diff --git a/packages/storage-compat/test/unit/reference.test.ts b/packages/storage-compat/test/unit/reference.test.ts new file mode 100644 index 00000000000..f256bdb9c64 --- /dev/null +++ b/packages/storage-compat/test/unit/reference.test.ts @@ -0,0 +1,318 @@ +// /** +// * @license +// * Copyright 2020 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 { FirebaseApp } from '@firebase/app-types'; +// import { ReferenceCompat } from '../../src/reference'; +// import { StorageServiceCompat } from '../../src/service'; +// import { FirebaseAuthInternalName } from '@firebase/auth-interop-types'; +// import { Provider } from '@firebase/component'; +// import { AppCheckInternalComponentName } from '@firebase/app-check-interop-types'; + +// // imports from the source code from @firebase/storage +// import { FirebaseStorageImpl } from '../../../storage/src/service'; +// import { Reference } from '../../../storage/src/reference'; +// import { StringFormat } from '../../../storage/src/implementation/string'; +// import { Headers } from '../../../storage/src/implementation/connection'; +// import { Metadata } from '../../../storage/src/metadata'; +// import * as testShared from '../../../storage/test/unit/testshared'; +// import { SendHook, TestingConnection } from './connection'; + +// const DEFAULT_HOST = 'test.test.com' + +// /* eslint-disable @typescript-eslint/no-floating-promises */ +// function makeFakeService( +// app: FirebaseApp, +// authProvider: Provider, +// appCheckProvider: Provider, +// sendHook: SendHook +// ): StorageServiceCompat { +// const storageServiceCompat: StorageServiceCompat = new StorageServiceCompat( +// app, +// new FirebaseStorageImpl( +// app, +// authProvider, +// appCheckProvider, +// testShared.makePool(sendHook) +// ) +// ); +// return storageServiceCompat; +// } + +// function makeStorage(url: string): ReferenceCompat { +// const service = new FirebaseStorageImpl( +// {} as FirebaseApp, +// testShared.emptyAuthProvider, +// testShared.fakeAppCheckTokenProvider, +// testShared.makePool(null) +// ); +// const storageServiceCompat: StorageServiceCompat = new StorageServiceCompat( +// {} as FirebaseApp, +// service +// ); +// return new ReferenceCompat(new Reference(service, url), storageServiceCompat); +// } + +// describe('Firebase Storage > Reference', () => { +// const root = makeStorage('gs://test-bucket/'); +// const child = makeStorage('gs://test-bucket/hello'); +// describe('Path constructor', () => { +// it('root', () => { +// expect(root.toString()).to.equal('gs://test-bucket/'); +// }); +// it('keeps characters after ? on a gs:// string', () => { +// const s = makeStorage('gs://test-bucket/this/ismyobject?hello'); +// expect(s.toString()).to.equal('gs://test-bucket/this/ismyobject?hello'); +// }); +// it("doesn't URL-decode on a gs:// string", () => { +// const s = makeStorage('gs://test-bucket/%3F'); +// expect(s.toString()).to.equal('gs://test-bucket/%3F'); +// }); +// it('ignores URL params and fragments on an http URL', () => { +// const s = makeStorage( +// `http://${DEFAULT_HOST}/v0/b/test-bucket/o/my/object.txt` + +// '?ignoreme#please' +// ); +// expect(s.toString()).to.equal('gs://test-bucket/my/object.txt'); +// }); +// it('URL-decodes and ignores fragment on an http URL', () => { +// const s = makeStorage( +// `http://${DEFAULT_HOST}/v0/b/test-bucket/o/%3F?ignore` +// ); +// expect(s.toString()).to.equal('gs://test-bucket/?'); +// }); + +// it('ignores URL params and fragments on an https URL', () => { +// const s = makeStorage( +// `https://${DEFAULT_HOST}/v0/b/test-bucket/o/my/object.txt` + +// '?ignoreme#please' +// ); +// expect(s.toString()).to.equal('gs://test-bucket/my/object.txt'); +// }); + +// it('URL-decodes and ignores fragment on an https URL', () => { +// const s = makeStorage( +// `https://${DEFAULT_HOST}/v0/b/test-bucket/o/%3F?ignore` +// ); +// expect(s.toString()).to.equal('gs://test-bucket/?'); +// }); +// }); + +// describe('toString', () => { +// it("Doesn't add trailing slash", () => { +// const s = makeStorage('gs://test-bucket/foo'); +// expect(s.toString()).to.equal('gs://test-bucket/foo'); +// }); +// it('Strips trailing slash', () => { +// const s = makeStorage('gs://test-bucket/foo/'); +// expect(s.toString()).to.equal('gs://test-bucket/foo'); +// }); +// }); + +// describe('parent', () => { +// it('Returns null at root', () => { +// expect(root.parent).to.be.null; +// }); +// it('Returns root one level down', () => { +// expect(child.parent!.toString()).to.equal('gs://test-bucket/'); +// }); +// it('Works correctly with empty levels', () => { +// const s = makeStorage('gs://test-bucket/a///'); +// expect(s.parent!.toString()).to.equal('gs://test-bucket/a/'); +// }); +// }); + +// describe('root', () => { +// it('Returns self at root', () => { +// expect(root.root.toString()).to.equal('gs://test-bucket/'); +// }); + +// it('Returns root multiple levels down', () => { +// const s = makeStorage('gs://test-bucket/a/b/c/d'); +// expect(s.root.toString()).to.equal('gs://test-bucket/'); +// }); +// }); + +// describe('bucket', () => { +// it('Returns bucket name', () => { +// expect(root.bucket).to.equal('test-bucket'); +// }); +// }); + +// describe('fullPath', () => { +// it('Returns full path without leading slash', () => { +// const s = makeStorage('gs://test-bucket/full/path'); +// expect(s.fullPath).to.equal('full/path'); +// }); +// }); + +// describe('name', () => { +// it('Works at top level', () => { +// const s = makeStorage('gs://test-bucket/toplevel.txt'); +// expect(s.name).to.equal('toplevel.txt'); +// }); + +// it('Works at not the top level', () => { +// const s = makeStorage('gs://test-bucket/not/toplevel.txt'); +// expect('toplevel.txt').to.equal(s.name); +// }); +// }); + +// describe('child', () => { +// it('works with a simple string', () => { +// expect(root.child('a').toString()).to.equal('gs://test-bucket/a'); +// }); +// it('drops a trailing slash', () => { +// expect(root.child('ab/').toString()).to.equal('gs://test-bucket/ab'); +// }); +// it('compresses repeated slashes', () => { +// expect(root.child('//a///b/////').toString()).to.equal( +// 'gs://test-bucket/a/b' +// ); +// }); +// it('works chained multiple times with leading slashes', () => { +// expect( +// root.child('a').child('/b').child('c').child('d/e').toString() +// ).to.equal('gs://test-bucket/a/b/c/d/e'); +// }); +// }); + +// it("Doesn't send Authorization on null auth token", done => { +// function newSend( +// connection: TestingConnection, +// url: string, +// method: string, +// body?: ArrayBufferView | Blob | string | null, +// headers?: Headers +// ): void { +// expect(headers).to.not.be.undefined; +// expect(headers!['Authorization']).to.be.undefined; +// done(); +// } + +// const service = makeFakeService( +// testShared.fakeApp, +// testShared.emptyAuthProvider, +// testShared.fakeAppCheckTokenProvider, +// newSend +// ); +// const ref = service.refFromURL('gs://test-bucket'); +// ref.child('foo').getMetadata(); +// }); + +// it('Works if the user logs in before creating the storage reference', done => { +// // Regression test for b/27227221 +// function newSend( +// connection: TestingConnection, +// url: string, +// method: string, +// body?: ArrayBufferView | Blob | string | null, +// headers?: Headers +// ): void { +// expect(headers).to.not.be.undefined; +// expect(headers!['Authorization']).to.equal( +// 'Firebase ' + testShared.authToken +// ); +// done(); +// } + +// const service = makeFakeService( +// testShared.fakeApp, +// testShared.fakeAuthProvider, +// testShared.fakeAppCheckTokenProvider, +// newSend +// ); +// const ref = service.refFromURL('gs://test-bucket'); +// ref.child('foo').getMetadata(); +// }); + +// describe('putString', () => { +// it('Uses metadata.contentType for RAW format', () => { +// // Regression test for b/30989476 +// const task = child.putString('hello', StringFormat.RAW, { +// contentType: 'lol/wut' +// } as Metadata); +// expect(task.snapshot.metadata!.contentType).to.equal('lol/wut'); +// task.cancel(); +// }); +// it('Uses embedded content type in DATA_URL format', () => { +// const task = child.putString( +// 'data:lol/wat;base64,aaaa', +// StringFormat.DATA_URL +// ); +// expect(task.snapshot.metadata!.contentType).to.equal('lol/wat'); +// task.cancel(); +// }); +// it('Lets metadata.contentType override embedded content type in DATA_URL format', () => { +// const task = child.putString( +// 'data:ignore/me;base64,aaaa', +// StringFormat.DATA_URL, +// { contentType: 'tomato/soup' } as Metadata +// ); +// expect(task.snapshot.metadata!.contentType).to.equal('tomato/soup'); +// task.cancel(); +// }); +// }); + +// describe('Argument verification', () => { +// describe('list', () => { +// it('throws on invalid maxResults', () => { +// it('throws on invalid maxResults', async () => { +// await expect(child.list({ maxResults: 0 })).to.be.rejectedWith( +// 'storage/invalid-argument' +// ); +// await expect(child.list({ maxResults: -4 })).to.be.rejectedWith( +// 'storage/invalid-argument' +// ); +// await expect(child.list({ maxResults: 1001 })).to.be.rejectedWith( +// 'storage/invalid-argument' +// ); +// }); +// }); +// }); +// }); + +// describe('root operations', () => { +// it('put throws', () => { +// expect(() => root.put(new Uint8Array())).to.throw( +// 'storage/invalid-root-operation' +// ); +// }); +// it('putString throws', () => { +// expect(() => root.putString('raw', StringFormat.RAW)).to.throw( +// 'storage/invalid-root-operation' +// ); +// }); +// it('delete throws', () => { +// expect(() => root.delete()).to.throw('storage/invalid-root-operation'); +// }); +// it('getMetadata throws', async () => { +// await expect(root.getMetadata()).to.be.rejectedWith( +// 'storage/invalid-root-operation' +// ); +// }); +// it('updateMetadata throws', async () => { +// await expect(root.updateMetadata({} as Metadata)).to.be.rejectedWith( +// 'storage/invalid-root-operation' +// ); +// }); +// it('getDownloadURL throws', async () => { +// await expect(root.getDownloadURL()).to.be.rejectedWith( +// 'storage/invalid-root-operation' +// ); +// }); +// }); +// }); diff --git a/packages/storage-compat/test/unit/service.compat.test.ts b/packages/storage-compat/test/unit/service.compat.test.ts deleted file mode 100644 index f6796e3de05..00000000000 --- a/packages/storage-compat/test/unit/service.compat.test.ts +++ /dev/null @@ -1,370 +0,0 @@ -/** - * @license - * Copyright 2020 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 { TaskEvent } from '../../src/implementation/taskenums'; -import { Headers } from '../../src/implementation/connection'; -import { ConnectionPool } from '../../src/implementation/connectionPool'; -import { StorageServiceCompat } from '../../compat/service'; -import * as testShared from './testshared'; -import { DEFAULT_HOST } from '../../src/implementation/constants'; -import { FirebaseStorageError } from '../../src/implementation/error'; -import { FirebaseStorageImpl } from '../../src/service'; -import { FirebaseApp } from '@firebase/app-types'; -import { Provider } from '@firebase/component'; -import { FirebaseAuthInternalName } from '@firebase/auth-interop-types'; -import { AppCheckInternalComponentName } from '@firebase/app-check-interop-types'; -import { TestingConnection } from './connection'; - -const fakeAppGs = testShared.makeFakeApp('gs://mybucket'); -const fakeAppGsEndingSlash = testShared.makeFakeApp('gs://mybucket/'); -const fakeAppInvalidGs = testShared.makeFakeApp('gs://mybucket/hello'); -const connectionPool = new ConnectionPool(); - -function makeGsUrl(child: string = ''): string { - return 'gs://' + testShared.bucket + '/' + child; -} - -function makeService( - app: FirebaseApp, - authProvider: Provider, - appCheckProvider: Provider, - pool: ConnectionPool, - url?: string -): StorageServiceCompat { - const storageServiceCompat: StorageServiceCompat = new StorageServiceCompat( - app, - new FirebaseStorageImpl(app, authProvider, appCheckProvider, pool, url) - ); - return storageServiceCompat; -} - -describe('Firebase Storage > Service', () => { - describe('simple constructor', () => { - const service = makeService( - testShared.fakeApp, - testShared.fakeAuthProvider, - testShared.fakeAppCheckTokenProvider, - connectionPool - ); - it('Root refs point to the right place', () => { - const ref = service.ref(); - expect(ref.toString()).to.equal(makeGsUrl()); - }); - it('Child refs point to the right place', () => { - const ref = service.ref('path/to/child'); - expect(ref.toString()).to.equal(makeGsUrl('path/to/child')); - }); - it('Throws calling ref with a gs:// URL', () => { - const error = testShared.assertThrows(() => { - service.ref('gs://bucket/object'); - }, 'storage/invalid-argument'); - expect(error.message).to.match(/refFromURL/); - }); - it('Throws calling ref with an http:// URL', () => { - const error = testShared.assertThrows(() => { - service.ref(`http://${DEFAULT_HOST}/etc`); - }, 'storage/invalid-argument'); - expect(error.message).to.match(/refFromURL/); - }); - it('Throws calling ref with an https:// URL', () => { - const error = testShared.assertThrows(() => { - service.ref(`https://${DEFAULT_HOST}/etc`); - }, 'storage/invalid-argument'); - expect(error.message).to.match(/refFromURL/); - }); - }); - describe('custom bucket constructor', () => { - it('gs:// custom bucket constructor refs point to the right place', () => { - const service = makeService( - testShared.fakeApp, - testShared.fakeAuthProvider, - testShared.fakeAppCheckTokenProvider, - connectionPool, - 'gs://foo-bar.appspot.com' - ); - const ref = service.ref(); - expect(ref.toString()).to.equal('gs://foo-bar.appspot.com/'); - }); - it('http:// custom bucket constructor refs point to the right place', () => { - const service = makeService( - testShared.fakeApp, - testShared.fakeAuthProvider, - testShared.fakeAppCheckTokenProvider, - connectionPool, - `http://${DEFAULT_HOST}/v1/b/foo-bar.appspot.com/o` - ); - const ref = service.ref(); - expect(ref.toString()).to.equal('gs://foo-bar.appspot.com/'); - }); - it('https:// custom bucket constructor refs point to the right place', () => { - const service = makeService( - testShared.fakeApp, - testShared.fakeAuthProvider, - testShared.fakeAppCheckTokenProvider, - connectionPool, - `https://${DEFAULT_HOST}/v1/b/foo-bar.appspot.com/o` - ); - const ref = service.ref(); - expect(ref.toString()).to.equal('gs://foo-bar.appspot.com/'); - }); - - it('Bare bucket name constructor refs point to the right place', () => { - const service = makeService( - testShared.fakeApp, - testShared.fakeAuthProvider, - testShared.fakeAppCheckTokenProvider, - connectionPool, - 'foo-bar.appspot.com' - ); - const ref = service.ref(); - expect(ref.toString()).to.equal('gs://foo-bar.appspot.com/'); - }); - it('Child refs point to the right place', () => { - const service = makeService( - testShared.fakeApp, - testShared.fakeAuthProvider, - testShared.fakeAppCheckTokenProvider, - connectionPool, - 'foo-bar.appspot.com' - ); - const ref = service.ref('path/to/child'); - expect(ref.toString()).to.equal('gs://foo-bar.appspot.com/path/to/child'); - }); - it('Throws trying to construct with a gs:// URL containing an object path', () => { - const error = testShared.assertThrows(() => { - makeService( - testShared.fakeApp, - testShared.fakeAuthProvider, - testShared.fakeAppCheckTokenProvider, - connectionPool, - 'gs://bucket/object/' - ); - }, 'storage/invalid-default-bucket'); - expect(error.message).to.match(/Invalid default bucket/); - }); - }); - describe('default bucket config', () => { - it('gs:// works without ending slash', () => { - const service = makeService( - fakeAppGs, - testShared.fakeAuthProvider, - testShared.fakeAppCheckTokenProvider, - connectionPool - ); - expect(service.ref().toString()).to.equal('gs://mybucket/'); - }); - it('gs:// works with ending slash', () => { - const service = makeService( - fakeAppGsEndingSlash, - testShared.fakeAuthProvider, - testShared.fakeAppCheckTokenProvider, - connectionPool - ); - expect(service.ref().toString()).to.equal('gs://mybucket/'); - }); - it('Throws when config bucket is gs:// with an object path', () => { - testShared.assertThrows(() => { - makeService( - fakeAppInvalidGs, - testShared.fakeAuthProvider, - testShared.fakeAppCheckTokenProvider, - connectionPool - ); - }, 'storage/invalid-default-bucket'); - }); - }); - describe('connectStorageEmulator(service, host, port)', () => { - it('sets emulator host correctly', done => { - function newSend( - connection: TestingConnection, - url: string, - method: string, - body?: ArrayBufferView | Blob | string | null, - headers?: Headers - ): void { - // Expect emulator host to be in url of storage operations requests, - // in this case getDownloadURL. - expect(url).to.match(/^http:\/\/test\.host\.org:1234.+/); - connection.abort(); - done(); - } - const service = makeService( - testShared.fakeApp, - testShared.fakeAuthProvider, - testShared.fakeAppCheckTokenProvider, - testShared.makePool(newSend) - ); - service.useEmulator('test.host.org', 1234); - expect((service._delegate as FirebaseStorageImpl).host).to.equal( - 'http://test.host.org:1234' - ); - void service.ref('test.png').getDownloadURL(); - }); - }); - describe('refFromURL', () => { - const service = makeService( - testShared.fakeApp, - testShared.fakeAuthProvider, - testShared.fakeAppCheckTokenProvider, - connectionPool - ); - it('Works with gs:// URLs', () => { - const ref = service.refFromURL('gs://mybucket/child/path/image.png'); - expect(ref.toString()).to.equal('gs://mybucket/child/path/image.png'); - }); - it('Works with http:// URLs', () => { - const ref = service.refFromURL( - `http://${DEFAULT_HOST}/v0/b/` + - 'mybucket/o/child%2Fpath%2Fimage.png?downloadToken=hello' - ); - expect(ref.toString()).to.equal('gs://mybucket/child/path/image.png'); - }); - it('Works with https:// URLs', () => { - const ref = service.refFromURL( - `https://${DEFAULT_HOST}/v0/b/` + - 'mybucket/o/child%2Fpath%2Fimage.png?downloadToken=hello' - ); - expect(ref.toString()).to.equal('gs://mybucket/child/path/image.png'); - }); - it('Works with storage.googleapis.com URLs', () => { - const ref = service.refFromURL( - `https://storage.googleapis.com/mybucket/path%20with%20space/image.png` - ); - expect(ref.toString()).to.equal( - 'gs://mybucket/path with space/image.png' - ); - }); - it('Works with storage.googleapis.com URLs with query params', () => { - const ref = service.refFromURL( - `https://storage.googleapis.com/mybucket/path%20with%20space/image.png?X-Goog-Algorithm= -GOOG4-RSA-SHA256` - ); - expect(ref.toString()).to.equal( - 'gs://mybucket/path with space/image.png' - ); - }); - it('Works with storage.cloud.google.com URLs', () => { - const ref = service.refFromURL( - `https://storage.cloud.google.com/mybucket/path%20with%20space/image.png` - ); - expect(ref.toString()).to.equal( - 'gs://mybucket/path with space/image.png' - ); - }); - it('Works with storage.cloud.google.com URLs and escaped slash', () => { - const ref = service.refFromURL( - `https://storage.cloud.google.com/mybucket/path%20with%20space%2Fimage.png` - ); - expect(ref.toString()).to.equal( - 'gs://mybucket/path with space/image.png' - ); - }); - }); - describe('Argument verification', () => { - const service = makeService( - testShared.fakeApp, - testShared.fakeAuthProvider, - testShared.fakeAppCheckTokenProvider, - connectionPool - ); - describe('ref', () => { - it('Throws on gs:// argument', () => { - testShared.assertThrows( - testShared.bind(service.ref, service, 'gs://yo'), - 'storage/invalid-argument' - ); - }); - }); - describe('refFromURL', () => { - it('Throws with a non-URL string arg', () => { - const error = testShared.assertThrows( - testShared.bind(service.refFromURL, service, 'child'), - 'storage/invalid-argument' - ); - expect(error.message).to.match( - /expected a full URL but got a child path/i - ); - }); - it('Throws with an invalid URL arg', () => { - testShared.assertThrows( - testShared.bind(service.refFromURL, service, 'notlegit://url'), - 'storage/invalid-argument' - ); - }); - }); - describe('setMaxUploadRetryTime', () => { - it('Throws on negative arg', () => { - testShared.assertThrows( - testShared.bind(service.setMaxUploadRetryTime, service, -10), - 'storage/invalid-argument' - ); - }); - }); - describe('setMaxOperationRetryTime', () => { - it('Throws on negative arg', () => { - testShared.assertThrows( - testShared.bind(service.setMaxOperationRetryTime, service, -10), - 'storage/invalid-argument' - ); - }); - }); - }); - - describe('Deletion', () => { - const service = makeService( - testShared.fakeApp, - testShared.fakeAuthProvider, - testShared.fakeAppCheckTokenProvider, - connectionPool - ); - it('In-flight requests are canceled when the service is deleted', async () => { - const ref = service.refFromURL('gs://mybucket/image.jpg'); - const metadataPromise = ref.getMetadata(); - // eslint-disable-next-line @typescript-eslint/no-floating-promises - service._delegate._delete(); - await expect(metadataPromise).to.be.rejectedWith('storage/app-deleted'); - }); - it('Requests fail when started after the service is deleted', async () => { - const ref = service.refFromURL('gs://mybucket/image.jpg'); - // eslint-disable-next-line @typescript-eslint/no-floating-promises - service._delegate._delete(); - - await expect(ref.getMetadata()).to.be.rejectedWith('storage/app-deleted'); - }); - it('Running uploads fail when the service is deleted', () => { - const ref = service.refFromURL('gs://mybucket/image.jpg'); - const toReturn = new Promise((resolve, reject) => { - ref.put(new Uint8Array([97])).on( - TaskEvent.STATE_CHANGED, - null, - (err: FirebaseStorageError | Error) => { - expect((err as FirebaseStorageError).code).to.equal( - 'storage/app-deleted' - ); - resolve(); - }, - () => { - reject('Upload completed, should have been canceled'); - } - ); - // eslint-disable-next-line @typescript-eslint/no-floating-promises - service._delegate._delete(); - }); - return toReturn; - }); - }); -}); diff --git a/packages/storage-compat/test/unit/service.test.ts b/packages/storage-compat/test/unit/service.test.ts new file mode 100644 index 00000000000..b78f1788326 --- /dev/null +++ b/packages/storage-compat/test/unit/service.test.ts @@ -0,0 +1,195 @@ +/** + * @license + * Copyright 2020 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 '@firebase/storage-compat/test/setup'; +import { expect } from 'chai'; +import { stub } from 'sinon'; +import * as modularStorage from '@firebase/storage'; +import { makeTestCompatStorage, fakeApp, fakeStorage } from '@firebase/storage-compat/test/utils'; +import { FirebaseStorage, getStorage, FirebaseStorageError } from '@firebase/storage'; +import firebase from '@firebase/app-compat'; + +const testCompatApp = firebase.initializeApp({}); +const testModularStorage = getStorage(testCompatApp); + +const DEFAULT_HOST = 'firebasestorage.googleapis.com'; + +describe.only('Firebase Storage > Service', () => { + describe('useEmulator(host, port)', () => { + it('calls connectStorageEmulator() correctly', () => { + const connectStorageEmulatorStub = stub(modularStorage, 'connectStorageEmulator').callsFake(() => { }); + const service = makeTestCompatStorage(fakeApp, fakeStorage); + service.useEmulator('test.host.org', 1234); + + expect(connectStorageEmulatorStub).to.have.been.calledWithExactly( + fakeStorage, + 'test.host.org', + 1234 + ); + }); + }); + + describe('refFromURL', () => { + const service = makeTestCompatStorage( + testCompatApp, + testModularStorage + ); + it('Works with gs:// URLs', () => { + const ref = service.refFromURL('gs://mybucket/child/path/image.png'); + expect(ref.toString()).to.equal('gs://mybucket/child/path/image.png'); + }); + it('Works with http:// URLs', () => { + const ref = service.refFromURL( + `http://${DEFAULT_HOST}/v0/b/` + + 'mybucket/o/child%2Fpath%2Fimage.png?downloadToken=hello' + ); + expect(ref.toString()).to.equal('gs://mybucket/child/path/image.png'); + }); + it('Works with https:// URLs', () => { + const ref = service.refFromURL( + `https://${DEFAULT_HOST}/v0/b/` + + 'mybucket/o/child%2Fpath%2Fimage.png?downloadToken=hello' + ); + expect(ref.toString()).to.equal('gs://mybucket/child/path/image.png'); + }); + it('Works with storage.googleapis.com URLs', () => { + const ref = service.refFromURL( + `https://storage.googleapis.com/mybucket/path%20with%20space/image.png` + ); + expect(ref.toString()).to.equal( + 'gs://mybucket/path with space/image.png' + ); + }); + it('Works with storage.googleapis.com URLs with query params', () => { + const ref = service.refFromURL( + `https://storage.googleapis.com/mybucket/path%20with%20space/image.png?X-Goog-Algorithm= +GOOG4-RSA-SHA256` + ); + expect(ref.toString()).to.equal( + 'gs://mybucket/path with space/image.png' + ); + }); + it('Works with storage.cloud.google.com URLs', () => { + const ref = service.refFromURL( + `https://storage.cloud.google.com/mybucket/path%20with%20space/image.png` + ); + expect(ref.toString()).to.equal( + 'gs://mybucket/path with space/image.png' + ); + }); + it('Works with storage.cloud.google.com URLs and escaped slash', () => { + const ref = service.refFromURL( + `https://storage.cloud.google.com/mybucket/path%20with%20space%2Fimage.png` + ); + expect(ref.toString()).to.equal( + 'gs://mybucket/path with space/image.png' + ); + }); + }); + + describe('Argument verification', () => { + const service = makeTestCompatStorage( + testCompatApp, + testModularStorage + ); + + describe('ref', () => { + it('Throws on gs:// argument', () => { + expect(() => service.ref('gs://yo')).to.throw('storage/invalid-argument'); + }); + }); + + describe('refFromURL', () => { + it('Throws with a non-URL string arg', () => { + expect(() => { service.refFromURL('child') }).to.throw(/expected a full URL but got a child path.*storage\/invalid-argument/i); + }); + it('Throws with an invalid URL arg', () => { + expect(() => { service.refFromURL('notlegit://url') }).to.throw('storage/invalid-argument'); + }); + }); + + describe('MaxUploadRetryTime', () => { + const modularStorage = {} as FirebaseStorage; + const service = makeTestCompatStorage(fakeApp, modularStorage) + it('reads from the modular instance', () => { + modularStorage.maxUploadRetryTime = 999; + expect(service.maxUploadRetryTime).to.equal(999); + }); + + it('sets value on the modular instance', () => { + service.setMaxUploadRetryTime(888); + expect(modularStorage.maxUploadRetryTime).to.equal(888); + }); + }); + describe('MaxOperationRetryTime', () => { + + const modularStorage = {} as FirebaseStorage; + const service = makeTestCompatStorage(fakeApp, modularStorage) + it('reads from the modular instance', () => { + modularStorage.maxOperationRetryTime = 999; + expect(service.maxOperationRetryTime).to.equal(999); + }); + + it('sets value on the modular instance', () => { + service.setMaxOperationRetryTime(888); + expect(modularStorage.maxOperationRetryTime).to.equal(888); + }); + }); + }); + + describe('Deletion', () => { + const service = makeTestCompatStorage( + testCompatApp, + testModularStorage + ); + + it('In-flight requests are canceled when the service is deleted', async () => { + const ref = service.refFromURL('gs://mybucket/image.jpg'); + const metadataPromise = ref.getMetadata(); + // eslint-disable-next-line @typescript-eslint/no-floating-promises + service._delegate._delete(); + await expect(metadataPromise).to.be.rejectedWith('storage/app-deleted'); + }); + it('Requests fail when started after the service is deleted', async () => { + const ref = service.refFromURL('gs://mybucket/image.jpg'); + // eslint-disable-next-line @typescript-eslint/no-floating-promises + service._delegate._delete(); + + await expect(ref.getMetadata()).to.be.rejectedWith('storage/app-deleted'); + }); + it('Running uploads fail when the service is deleted', () => { + const ref = service.refFromURL('gs://mybucket/image.jpg'); + const toReturn = new Promise((resolve, reject) => { + ref.put(new Uint8Array([97])).on( + 'state_changed', + null, + (err: FirebaseStorageError | Error) => { + expect((err as FirebaseStorageError).code).to.equal( + 'storage/app-deleted' + ); + resolve(); + }, + () => { + reject('Upload completed, should have been canceled'); + } + ); + // eslint-disable-next-line @typescript-eslint/no-floating-promises + service._delegate._delete(); + }); + return toReturn; + }); + }); +}); diff --git a/packages/storage-compat/test/utils.ts b/packages/storage-compat/test/utils.ts new file mode 100644 index 00000000000..9df3feb00ed --- /dev/null +++ b/packages/storage-compat/test/utils.ts @@ -0,0 +1,14 @@ +import { FirebaseApp } from '@firebase/app-types'; +import { FirebaseStorage } from '@firebase/storage'; +import { StorageServiceCompat } from '../src/service'; + +export function makeTestCompatStorage(app: FirebaseApp, storage: FirebaseStorage): StorageServiceCompat { + const storageServiceCompat: StorageServiceCompat = new StorageServiceCompat( + app, + storage + ); + return storageServiceCompat; +} + +export const fakeApp = {} as FirebaseApp; +export const fakeStorage = {} as FirebaseStorage; \ No newline at end of file diff --git a/packages/storage/package.json b/packages/storage/package.json index 07dbfafcbc1..986e699061b 100644 --- a/packages/storage/package.json +++ b/packages/storage/package.json @@ -27,7 +27,7 @@ "test:browser:compat": "karma start --single-run --compat", "test:browser:exp": "karma start --single-run --exp", "test:browser": "karma start --single-run", - "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", + "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 src/index.ts --config ../../config/mocharc.node.js", "test:debug": "karma start --browser=Chrome", "prettier": "prettier --write 'src/**/*.ts' 'test/**/*.ts'", "api-report": "api-extractor run --local --verbose && ts-node-script ../../repo-scripts/prune-dts/prune-dts.ts --input dist/storage-public.d.ts --output dist/storage-public.d.ts" @@ -60,5 +60,5 @@ "bugs": { "url": "https://github.com/firebase/firebase-js-sdk/issues" }, - "typings": "dist/storage.d.ts" + "typings": "dist/src/index.d.ts" } diff --git a/packages/storage/rollup.config.js b/packages/storage/rollup.config.js index 0093bcd9ec3..52faffa0c70 100644 --- a/packages/storage/rollup.config.js +++ b/packages/storage/rollup.config.js @@ -21,8 +21,6 @@ import typescript from 'typescript'; import alias from '@rollup/plugin-alias'; import pkg from './package.json'; -import { importPathTransformer } from '../../scripts/exp/ts-transform-import-path'; - function generateAliasConfig(platform) { return { entries: [ @@ -43,8 +41,7 @@ const nodeDeps = [...deps, 'util']; const es5Plugins = [ typescriptPlugin({ typescript, - abortOnError: false, - transformers: [importPathTransformer] + abortOnError: false }), json() ]; @@ -74,8 +71,7 @@ const es2017Plugins = [ target: 'es2017' } }, - abortOnError: false, - transformers: [importPathTransformer] + abortOnError: false }), json({ preferConst: true }) ]; diff --git a/packages/storage/test/unit/service.test.ts b/packages/storage/test/unit/service.test.ts index a5f4c143f3c..3a94ebcc542 100644 --- a/packages/storage/test/unit/service.test.ts +++ b/packages/storage/test/unit/service.test.ts @@ -365,4 +365,29 @@ GOOG4-RSA-SHA256` return toReturn; }); }); + + describe('Argument verification', () => { + const service = new FirebaseStorageImpl( + testShared.fakeApp, + testShared.fakeAuthProvider, + testShared.fakeAppCheckTokenProvider, + connectionPool + ); + describe('setMaxUploadRetryTime', () => { + it('Throws on negative arg', () => { + testShared.assertThrows( + () => service.maxOperationRetryTime = -10, + 'storage/invalid-argument' + ); + }); + }); + describe('setMaxOperationRetryTime', () => { + it('Throws on negative arg', () => { + testShared.assertThrows( + () => service.maxOperationRetryTime = -10, + 'storage/invalid-argument' + ); + }); + }); + }); }); From 0a1d781289319967935839ca4e916ec99d0b4e68 Mon Sep 17 00:00:00 2001 From: Feiyang1 Date: Tue, 10 Aug 2021 00:09:23 -0700 Subject: [PATCH 08/22] format --- .../storage-compat/test/unit/service.test.ts | 55 +++++++++++-------- packages/storage-compat/test/utils.ts | 34 +++++++++--- packages/storage/test/unit/service.test.ts | 4 +- 3 files changed, 61 insertions(+), 32 deletions(-) diff --git a/packages/storage-compat/test/unit/service.test.ts b/packages/storage-compat/test/unit/service.test.ts index b78f1788326..eaaa5b8ee77 100644 --- a/packages/storage-compat/test/unit/service.test.ts +++ b/packages/storage-compat/test/unit/service.test.ts @@ -18,8 +18,16 @@ import '@firebase/storage-compat/test/setup'; import { expect } from 'chai'; import { stub } from 'sinon'; import * as modularStorage from '@firebase/storage'; -import { makeTestCompatStorage, fakeApp, fakeStorage } from '@firebase/storage-compat/test/utils'; -import { FirebaseStorage, getStorage, FirebaseStorageError } from '@firebase/storage'; +import { + makeTestCompatStorage, + fakeApp, + fakeStorage +} from '@firebase/storage-compat/test/utils'; +import { + FirebaseStorage, + getStorage, + FirebaseStorageError +} from '@firebase/storage'; import firebase from '@firebase/app-compat'; const testCompatApp = firebase.initializeApp({}); @@ -30,7 +38,10 @@ const DEFAULT_HOST = 'firebasestorage.googleapis.com'; describe.only('Firebase Storage > Service', () => { describe('useEmulator(host, port)', () => { it('calls connectStorageEmulator() correctly', () => { - const connectStorageEmulatorStub = stub(modularStorage, 'connectStorageEmulator').callsFake(() => { }); + const connectStorageEmulatorStub = stub( + modularStorage, + 'connectStorageEmulator' + ).callsFake(() => {}); const service = makeTestCompatStorage(fakeApp, fakeStorage); service.useEmulator('test.host.org', 1234); @@ -43,10 +54,7 @@ describe.only('Firebase Storage > Service', () => { }); describe('refFromURL', () => { - const service = makeTestCompatStorage( - testCompatApp, - testModularStorage - ); + const service = makeTestCompatStorage(testCompatApp, testModularStorage); it('Works with gs:// URLs', () => { const ref = service.refFromURL('gs://mybucket/child/path/image.png'); expect(ref.toString()).to.equal('gs://mybucket/child/path/image.png'); @@ -54,14 +62,14 @@ describe.only('Firebase Storage > Service', () => { it('Works with http:// URLs', () => { const ref = service.refFromURL( `http://${DEFAULT_HOST}/v0/b/` + - 'mybucket/o/child%2Fpath%2Fimage.png?downloadToken=hello' + 'mybucket/o/child%2Fpath%2Fimage.png?downloadToken=hello' ); expect(ref.toString()).to.equal('gs://mybucket/child/path/image.png'); }); it('Works with https:// URLs', () => { const ref = service.refFromURL( `https://${DEFAULT_HOST}/v0/b/` + - 'mybucket/o/child%2Fpath%2Fimage.png?downloadToken=hello' + 'mybucket/o/child%2Fpath%2Fimage.png?downloadToken=hello' ); expect(ref.toString()).to.equal('gs://mybucket/child/path/image.png'); }); @@ -101,29 +109,34 @@ GOOG4-RSA-SHA256` }); describe('Argument verification', () => { - const service = makeTestCompatStorage( - testCompatApp, - testModularStorage - ); + const service = makeTestCompatStorage(testCompatApp, testModularStorage); describe('ref', () => { it('Throws on gs:// argument', () => { - expect(() => service.ref('gs://yo')).to.throw('storage/invalid-argument'); + expect(() => service.ref('gs://yo')).to.throw( + 'storage/invalid-argument' + ); }); }); describe('refFromURL', () => { it('Throws with a non-URL string arg', () => { - expect(() => { service.refFromURL('child') }).to.throw(/expected a full URL but got a child path.*storage\/invalid-argument/i); + expect(() => { + service.refFromURL('child'); + }).to.throw( + /expected a full URL but got a child path.*storage\/invalid-argument/i + ); }); it('Throws with an invalid URL arg', () => { - expect(() => { service.refFromURL('notlegit://url') }).to.throw('storage/invalid-argument'); + expect(() => { + service.refFromURL('notlegit://url'); + }).to.throw('storage/invalid-argument'); }); }); describe('MaxUploadRetryTime', () => { const modularStorage = {} as FirebaseStorage; - const service = makeTestCompatStorage(fakeApp, modularStorage) + const service = makeTestCompatStorage(fakeApp, modularStorage); it('reads from the modular instance', () => { modularStorage.maxUploadRetryTime = 999; expect(service.maxUploadRetryTime).to.equal(999); @@ -135,9 +148,8 @@ GOOG4-RSA-SHA256` }); }); describe('MaxOperationRetryTime', () => { - const modularStorage = {} as FirebaseStorage; - const service = makeTestCompatStorage(fakeApp, modularStorage) + const service = makeTestCompatStorage(fakeApp, modularStorage); it('reads from the modular instance', () => { modularStorage.maxOperationRetryTime = 999; expect(service.maxOperationRetryTime).to.equal(999); @@ -151,10 +163,7 @@ GOOG4-RSA-SHA256` }); describe('Deletion', () => { - const service = makeTestCompatStorage( - testCompatApp, - testModularStorage - ); + const service = makeTestCompatStorage(testCompatApp, testModularStorage); it('In-flight requests are canceled when the service is deleted', async () => { const ref = service.refFromURL('gs://mybucket/image.jpg'); diff --git a/packages/storage-compat/test/utils.ts b/packages/storage-compat/test/utils.ts index 9df3feb00ed..18da96ea996 100644 --- a/packages/storage-compat/test/utils.ts +++ b/packages/storage-compat/test/utils.ts @@ -1,14 +1,34 @@ +/** + * @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 { FirebaseApp } from '@firebase/app-types'; import { FirebaseStorage } from '@firebase/storage'; import { StorageServiceCompat } from '../src/service'; -export function makeTestCompatStorage(app: FirebaseApp, storage: FirebaseStorage): StorageServiceCompat { - const storageServiceCompat: StorageServiceCompat = new StorageServiceCompat( - app, - storage - ); - return storageServiceCompat; +export function makeTestCompatStorage( + app: FirebaseApp, + storage: FirebaseStorage +): StorageServiceCompat { + const storageServiceCompat: StorageServiceCompat = new StorageServiceCompat( + app, + storage + ); + return storageServiceCompat; } export const fakeApp = {} as FirebaseApp; -export const fakeStorage = {} as FirebaseStorage; \ No newline at end of file +export const fakeStorage = {} as FirebaseStorage; diff --git a/packages/storage/test/unit/service.test.ts b/packages/storage/test/unit/service.test.ts index 3a94ebcc542..0c250d7caf0 100644 --- a/packages/storage/test/unit/service.test.ts +++ b/packages/storage/test/unit/service.test.ts @@ -376,7 +376,7 @@ GOOG4-RSA-SHA256` describe('setMaxUploadRetryTime', () => { it('Throws on negative arg', () => { testShared.assertThrows( - () => service.maxOperationRetryTime = -10, + () => (service.maxOperationRetryTime = -10), 'storage/invalid-argument' ); }); @@ -384,7 +384,7 @@ GOOG4-RSA-SHA256` describe('setMaxOperationRetryTime', () => { it('Throws on negative arg', () => { testShared.assertThrows( - () => service.maxOperationRetryTime = -10, + () => (service.maxOperationRetryTime = -10), 'storage/invalid-argument' ); }); From af3dd186c0b3e877e69b1b75d8289b35d1bcc6c8 Mon Sep 17 00:00:00 2001 From: Feiyang1 Date: Tue, 10 Aug 2021 00:31:42 -0700 Subject: [PATCH 09/22] update import path --- packages/storage-compat/test/unit/service.test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/storage-compat/test/unit/service.test.ts b/packages/storage-compat/test/unit/service.test.ts index eaaa5b8ee77..c534b7dee0a 100644 --- a/packages/storage-compat/test/unit/service.test.ts +++ b/packages/storage-compat/test/unit/service.test.ts @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import '@firebase/storage-compat/test/setup'; +import '../setup'; import { expect } from 'chai'; import { stub } from 'sinon'; import * as modularStorage from '@firebase/storage'; @@ -22,7 +22,7 @@ import { makeTestCompatStorage, fakeApp, fakeStorage -} from '@firebase/storage-compat/test/utils'; +} from '../utils'; import { FirebaseStorage, getStorage, @@ -35,7 +35,7 @@ const testModularStorage = getStorage(testCompatApp); const DEFAULT_HOST = 'firebasestorage.googleapis.com'; -describe.only('Firebase Storage > Service', () => { +describe('Firebase Storage > Service', () => { describe('useEmulator(host, port)', () => { it('calls connectStorageEmulator() correctly', () => { const connectStorageEmulatorStub = stub( From fe257756d4d438ed1b544bf2b2055206b06e0104 Mon Sep 17 00:00:00 2001 From: Feiyang1 Date: Tue, 10 Aug 2021 00:31:53 -0700 Subject: [PATCH 10/22] format --- packages/storage-compat/test/unit/service.test.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/storage-compat/test/unit/service.test.ts b/packages/storage-compat/test/unit/service.test.ts index c534b7dee0a..530aaf658d8 100644 --- a/packages/storage-compat/test/unit/service.test.ts +++ b/packages/storage-compat/test/unit/service.test.ts @@ -18,11 +18,7 @@ import '../setup'; import { expect } from 'chai'; import { stub } from 'sinon'; import * as modularStorage from '@firebase/storage'; -import { - makeTestCompatStorage, - fakeApp, - fakeStorage -} from '../utils'; +import { makeTestCompatStorage, fakeApp, fakeStorage } from '../utils'; import { FirebaseStorage, getStorage, From 63c20aeee8b738cdc298ce069edcdf027fe6cbaf Mon Sep 17 00:00:00 2001 From: Feiyang1 Date: Tue, 10 Aug 2021 12:51:58 -0700 Subject: [PATCH 11/22] get compat tests to work --- packages/storage-compat/.eslintrc.js | 10 - packages/storage-compat/.npmignore | 9 - .../test/integration/integration.test.ts | 1 + .../storage-compat/test/unit/index.test.ts | 1 + .../test/unit/reference.test.ts | 530 +++++++----------- .../storage-compat/test/unit/service.test.ts | 51 +- 6 files changed, 256 insertions(+), 346 deletions(-) delete mode 100644 packages/storage-compat/.npmignore diff --git a/packages/storage-compat/.eslintrc.js b/packages/storage-compat/.eslintrc.js index 00bf88df31c..185597fec61 100644 --- a/packages/storage-compat/.eslintrc.js +++ b/packages/storage-compat/.eslintrc.js @@ -33,16 +33,6 @@ module.exports = { varsIgnorePattern: '^_', args: 'none' } - ], - 'import/no-extraneous-dependencies': [ - 'error', - { - 'packageDir': [ - path.resolve(__dirname, '../../'), - __dirname, - path.resolve(__dirname, 'exp') - ] - } ] } }; diff --git a/packages/storage-compat/.npmignore b/packages/storage-compat/.npmignore deleted file mode 100644 index 682c8f74a52..00000000000 --- a/packages/storage-compat/.npmignore +++ /dev/null @@ -1,9 +0,0 @@ -# Directories not needed by end users -/src -test - -# Files not needed by end users -gulpfile.js -index.ts -karma.conf.js -tsconfig.json \ No newline at end of file diff --git a/packages/storage-compat/test/integration/integration.test.ts b/packages/storage-compat/test/integration/integration.test.ts index e217781f5a6..047410c65d0 100644 --- a/packages/storage-compat/test/integration/integration.test.ts +++ b/packages/storage-compat/test/integration/integration.test.ts @@ -16,6 +16,7 @@ */ import firebase from '@firebase/app-compat'; +// eslint-disable-next-line import/no-extraneous-dependencies import '@firebase/auth-compat'; // See https://github.com/typescript-eslint/typescript-eslint/issues/363 diff --git a/packages/storage-compat/test/unit/index.test.ts b/packages/storage-compat/test/unit/index.test.ts index 23ee39ca483..d048407a0b8 100644 --- a/packages/storage-compat/test/unit/index.test.ts +++ b/packages/storage-compat/test/unit/index.test.ts @@ -14,6 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import '../setup'; import { expect } from 'chai'; import '../../src/index'; import firebase from '@firebase/app-compat'; diff --git a/packages/storage-compat/test/unit/reference.test.ts b/packages/storage-compat/test/unit/reference.test.ts index f256bdb9c64..c8fb5fd9ccb 100644 --- a/packages/storage-compat/test/unit/reference.test.ts +++ b/packages/storage-compat/test/unit/reference.test.ts @@ -1,318 +1,212 @@ -// /** -// * @license -// * Copyright 2020 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 { FirebaseApp } from '@firebase/app-types'; -// import { ReferenceCompat } from '../../src/reference'; -// import { StorageServiceCompat } from '../../src/service'; -// import { FirebaseAuthInternalName } from '@firebase/auth-interop-types'; -// import { Provider } from '@firebase/component'; -// import { AppCheckInternalComponentName } from '@firebase/app-check-interop-types'; - -// // imports from the source code from @firebase/storage -// import { FirebaseStorageImpl } from '../../../storage/src/service'; -// import { Reference } from '../../../storage/src/reference'; -// import { StringFormat } from '../../../storage/src/implementation/string'; -// import { Headers } from '../../../storage/src/implementation/connection'; -// import { Metadata } from '../../../storage/src/metadata'; -// import * as testShared from '../../../storage/test/unit/testshared'; -// import { SendHook, TestingConnection } from './connection'; - -// const DEFAULT_HOST = 'test.test.com' - -// /* eslint-disable @typescript-eslint/no-floating-promises */ -// function makeFakeService( -// app: FirebaseApp, -// authProvider: Provider, -// appCheckProvider: Provider, -// sendHook: SendHook -// ): StorageServiceCompat { -// const storageServiceCompat: StorageServiceCompat = new StorageServiceCompat( -// app, -// new FirebaseStorageImpl( -// app, -// authProvider, -// appCheckProvider, -// testShared.makePool(sendHook) -// ) -// ); -// return storageServiceCompat; -// } - -// function makeStorage(url: string): ReferenceCompat { -// const service = new FirebaseStorageImpl( -// {} as FirebaseApp, -// testShared.emptyAuthProvider, -// testShared.fakeAppCheckTokenProvider, -// testShared.makePool(null) -// ); -// const storageServiceCompat: StorageServiceCompat = new StorageServiceCompat( -// {} as FirebaseApp, -// service -// ); -// return new ReferenceCompat(new Reference(service, url), storageServiceCompat); -// } - -// describe('Firebase Storage > Reference', () => { -// const root = makeStorage('gs://test-bucket/'); -// const child = makeStorage('gs://test-bucket/hello'); -// describe('Path constructor', () => { -// it('root', () => { -// expect(root.toString()).to.equal('gs://test-bucket/'); -// }); -// it('keeps characters after ? on a gs:// string', () => { -// const s = makeStorage('gs://test-bucket/this/ismyobject?hello'); -// expect(s.toString()).to.equal('gs://test-bucket/this/ismyobject?hello'); -// }); -// it("doesn't URL-decode on a gs:// string", () => { -// const s = makeStorage('gs://test-bucket/%3F'); -// expect(s.toString()).to.equal('gs://test-bucket/%3F'); -// }); -// it('ignores URL params and fragments on an http URL', () => { -// const s = makeStorage( -// `http://${DEFAULT_HOST}/v0/b/test-bucket/o/my/object.txt` + -// '?ignoreme#please' -// ); -// expect(s.toString()).to.equal('gs://test-bucket/my/object.txt'); -// }); -// it('URL-decodes and ignores fragment on an http URL', () => { -// const s = makeStorage( -// `http://${DEFAULT_HOST}/v0/b/test-bucket/o/%3F?ignore` -// ); -// expect(s.toString()).to.equal('gs://test-bucket/?'); -// }); - -// it('ignores URL params and fragments on an https URL', () => { -// const s = makeStorage( -// `https://${DEFAULT_HOST}/v0/b/test-bucket/o/my/object.txt` + -// '?ignoreme#please' -// ); -// expect(s.toString()).to.equal('gs://test-bucket/my/object.txt'); -// }); - -// it('URL-decodes and ignores fragment on an https URL', () => { -// const s = makeStorage( -// `https://${DEFAULT_HOST}/v0/b/test-bucket/o/%3F?ignore` -// ); -// expect(s.toString()).to.equal('gs://test-bucket/?'); -// }); -// }); - -// describe('toString', () => { -// it("Doesn't add trailing slash", () => { -// const s = makeStorage('gs://test-bucket/foo'); -// expect(s.toString()).to.equal('gs://test-bucket/foo'); -// }); -// it('Strips trailing slash', () => { -// const s = makeStorage('gs://test-bucket/foo/'); -// expect(s.toString()).to.equal('gs://test-bucket/foo'); -// }); -// }); - -// describe('parent', () => { -// it('Returns null at root', () => { -// expect(root.parent).to.be.null; -// }); -// it('Returns root one level down', () => { -// expect(child.parent!.toString()).to.equal('gs://test-bucket/'); -// }); -// it('Works correctly with empty levels', () => { -// const s = makeStorage('gs://test-bucket/a///'); -// expect(s.parent!.toString()).to.equal('gs://test-bucket/a/'); -// }); -// }); - -// describe('root', () => { -// it('Returns self at root', () => { -// expect(root.root.toString()).to.equal('gs://test-bucket/'); -// }); - -// it('Returns root multiple levels down', () => { -// const s = makeStorage('gs://test-bucket/a/b/c/d'); -// expect(s.root.toString()).to.equal('gs://test-bucket/'); -// }); -// }); - -// describe('bucket', () => { -// it('Returns bucket name', () => { -// expect(root.bucket).to.equal('test-bucket'); -// }); -// }); - -// describe('fullPath', () => { -// it('Returns full path without leading slash', () => { -// const s = makeStorage('gs://test-bucket/full/path'); -// expect(s.fullPath).to.equal('full/path'); -// }); -// }); - -// describe('name', () => { -// it('Works at top level', () => { -// const s = makeStorage('gs://test-bucket/toplevel.txt'); -// expect(s.name).to.equal('toplevel.txt'); -// }); - -// it('Works at not the top level', () => { -// const s = makeStorage('gs://test-bucket/not/toplevel.txt'); -// expect('toplevel.txt').to.equal(s.name); -// }); -// }); - -// describe('child', () => { -// it('works with a simple string', () => { -// expect(root.child('a').toString()).to.equal('gs://test-bucket/a'); -// }); -// it('drops a trailing slash', () => { -// expect(root.child('ab/').toString()).to.equal('gs://test-bucket/ab'); -// }); -// it('compresses repeated slashes', () => { -// expect(root.child('//a///b/////').toString()).to.equal( -// 'gs://test-bucket/a/b' -// ); -// }); -// it('works chained multiple times with leading slashes', () => { -// expect( -// root.child('a').child('/b').child('c').child('d/e').toString() -// ).to.equal('gs://test-bucket/a/b/c/d/e'); -// }); -// }); - -// it("Doesn't send Authorization on null auth token", done => { -// function newSend( -// connection: TestingConnection, -// url: string, -// method: string, -// body?: ArrayBufferView | Blob | string | null, -// headers?: Headers -// ): void { -// expect(headers).to.not.be.undefined; -// expect(headers!['Authorization']).to.be.undefined; -// done(); -// } - -// const service = makeFakeService( -// testShared.fakeApp, -// testShared.emptyAuthProvider, -// testShared.fakeAppCheckTokenProvider, -// newSend -// ); -// const ref = service.refFromURL('gs://test-bucket'); -// ref.child('foo').getMetadata(); -// }); - -// it('Works if the user logs in before creating the storage reference', done => { -// // Regression test for b/27227221 -// function newSend( -// connection: TestingConnection, -// url: string, -// method: string, -// body?: ArrayBufferView | Blob | string | null, -// headers?: Headers -// ): void { -// expect(headers).to.not.be.undefined; -// expect(headers!['Authorization']).to.equal( -// 'Firebase ' + testShared.authToken -// ); -// done(); -// } - -// const service = makeFakeService( -// testShared.fakeApp, -// testShared.fakeAuthProvider, -// testShared.fakeAppCheckTokenProvider, -// newSend -// ); -// const ref = service.refFromURL('gs://test-bucket'); -// ref.child('foo').getMetadata(); -// }); - -// describe('putString', () => { -// it('Uses metadata.contentType for RAW format', () => { -// // Regression test for b/30989476 -// const task = child.putString('hello', StringFormat.RAW, { -// contentType: 'lol/wut' -// } as Metadata); -// expect(task.snapshot.metadata!.contentType).to.equal('lol/wut'); -// task.cancel(); -// }); -// it('Uses embedded content type in DATA_URL format', () => { -// const task = child.putString( -// 'data:lol/wat;base64,aaaa', -// StringFormat.DATA_URL -// ); -// expect(task.snapshot.metadata!.contentType).to.equal('lol/wat'); -// task.cancel(); -// }); -// it('Lets metadata.contentType override embedded content type in DATA_URL format', () => { -// const task = child.putString( -// 'data:ignore/me;base64,aaaa', -// StringFormat.DATA_URL, -// { contentType: 'tomato/soup' } as Metadata -// ); -// expect(task.snapshot.metadata!.contentType).to.equal('tomato/soup'); -// task.cancel(); -// }); -// }); - -// describe('Argument verification', () => { -// describe('list', () => { -// it('throws on invalid maxResults', () => { -// it('throws on invalid maxResults', async () => { -// await expect(child.list({ maxResults: 0 })).to.be.rejectedWith( -// 'storage/invalid-argument' -// ); -// await expect(child.list({ maxResults: -4 })).to.be.rejectedWith( -// 'storage/invalid-argument' -// ); -// await expect(child.list({ maxResults: 1001 })).to.be.rejectedWith( -// 'storage/invalid-argument' -// ); -// }); -// }); -// }); -// }); - -// describe('root operations', () => { -// it('put throws', () => { -// expect(() => root.put(new Uint8Array())).to.throw( -// 'storage/invalid-root-operation' -// ); -// }); -// it('putString throws', () => { -// expect(() => root.putString('raw', StringFormat.RAW)).to.throw( -// 'storage/invalid-root-operation' -// ); -// }); -// it('delete throws', () => { -// expect(() => root.delete()).to.throw('storage/invalid-root-operation'); -// }); -// it('getMetadata throws', async () => { -// await expect(root.getMetadata()).to.be.rejectedWith( -// 'storage/invalid-root-operation' -// ); -// }); -// it('updateMetadata throws', async () => { -// await expect(root.updateMetadata({} as Metadata)).to.be.rejectedWith( -// 'storage/invalid-root-operation' -// ); -// }); -// it('getDownloadURL throws', async () => { -// await expect(root.getDownloadURL()).to.be.rejectedWith( -// 'storage/invalid-root-operation' -// ); -// }); -// }); -// }); +/** + * @license + * Copyright 2020 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 '../setup'; +import { expect } from 'chai'; +import { ReferenceCompat } from '../../src/reference'; +import { StorageServiceCompat } from '../../src/service'; +import { makeTestCompatStorage, fakeApp, fakeStorage } from '../utils'; +import firebase from '@firebase/app-compat'; +import { StorageReference, getStorage, FirebaseStorage } from '@firebase/storage'; +import { fake } from 'sinon'; +import { FirebaseApp } from '@firebase/app-types'; +import { Reference } from '@firebase/storage-types'; + +describe('Firebase Storage > Reference', () => { + let testCompatApp: FirebaseApp; + let testModularStorage: FirebaseStorage; + let service: StorageServiceCompat; + before(() => { + testCompatApp = firebase.initializeApp({}); + testModularStorage = getStorage(testCompatApp); + service = makeTestCompatStorage(testCompatApp, testModularStorage); + }); + + after(() => { + return testCompatApp.delete(); + }); + describe('toString', () => { + it("delegates to the modular Reference.toString()", () => { + const fakeToString = fake.returns('test123'); + const ref = new ReferenceCompat({ + toString: fakeToString + } as unknown as StorageReference, makeTestCompatStorage(fakeApp, fakeStorage)); + + expect(ref.toString()).to.equal('test123'); + expect(fakeToString).to.have.been.calledOnceWithExactly(); + }); + }); + + describe('parent', () => { + it('Returns null at root', () => { + const root = service.refFromURL('gs://test-bucket'); + expect(root.parent).to.be.null; + }); + it('Returns root one level down', () => { + const child = service.refFromURL('gs://test-bucket/hello'); + expect(child.parent!.toString()).to.equal('gs://test-bucket/'); + }); + it('Works correctly with empty levels', () => { + const s = service.refFromURL('gs://test-bucket/a///'); + expect(s.parent!.toString()).to.equal('gs://test-bucket/a/'); + }); + }); + + describe('root', () => { + it('Returns self at root', () => { + const root = service.refFromURL('gs://test-bucket'); + expect(root.root.toString()).to.equal('gs://test-bucket/'); + }); + + it('Returns root multiple levels down', () => { + const s = service.refFromURL('gs://test-bucket/a/b/c/d'); + expect(s.root.toString()).to.equal('gs://test-bucket/'); + }); + }); + + describe('bucket', () => { + it('Returns bucket name', () => { + const root = service.refFromURL('gs://test-bucket'); + expect(root.bucket).to.equal('test-bucket'); + }); + }); + + describe('fullPath', () => { + it('Returns full path without leading slash', () => { + const s = service.refFromURL('gs://test-bucket/full/path'); + expect(s.fullPath).to.equal('full/path'); + }); + }); + + describe('name', () => { + it('Works at top level', () => { + const s = service.refFromURL('gs://test-bucket/toplevel.txt'); + expect(s.name).to.equal('toplevel.txt'); + }); + + it('Works at not the top level', () => { + const s = service.refFromURL('gs://test-bucket/not/toplevel.txt'); + expect('toplevel.txt').to.equal(s.name); + }); + }); + + describe('child', () => { + let root: Reference; + before(() => { + root = service.refFromURL('gs://test-bucket'); + }); + it('works with a simple string', () => { + expect(root.child('a').toString()).to.equal('gs://test-bucket/a'); + }); + it('drops a trailing slash', () => { + expect(root.child('ab/').toString()).to.equal('gs://test-bucket/ab'); + }); + it('compresses repeated slashes', () => { + expect(root.child('//a///b/////').toString()).to.equal( + 'gs://test-bucket/a/b' + ); + }); + it('works chained multiple times with leading slashes', () => { + expect( + root.child('a').child('/b').child('c').child('d/e').toString() + ).to.equal('gs://test-bucket/a/b/c/d/e'); + }); + }); + + describe('putString', () => { + let child: Reference; + before(() => { + child = service.refFromURL('gs://test-bucket/hello'); + }); + it('Uses metadata.contentType for RAW format', () => { + // Regression test for b/30989476 + const task = child.putString('hello', 'raw', { + contentType: 'lol/wut' + }); + expect(task.snapshot.metadata!.contentType).to.equal('lol/wut'); + task.cancel(); + }); + it('Uses embedded content type in DATA_URL format', () => { + const task = child.putString( + 'data:lol/wat;base64,aaaa', + 'data_url' + ); + expect(task.snapshot.metadata!.contentType).to.equal('lol/wat'); + task.cancel(); + }); + it('Lets metadata.contentType override embedded content type in DATA_URL format', () => { + const task = child.putString( + 'data:ignore/me;base64,aaaa', + 'data_url', + { contentType: 'tomato/soup' } + ); + expect(task.snapshot.metadata!.contentType).to.equal('tomato/soup'); + task.cancel(); + }); + }); + + describe('Argument verification', () => { + describe('list', () => { + it('throws on invalid maxResults', async () => { + const child = service.refFromURL('gs://test-bucket/hello'); + await expect(child.list({ maxResults: 0 })).to.be.rejectedWith( + 'storage/invalid-argument' + ); + await expect(child.list({ maxResults: -4 })).to.be.rejectedWith( + 'storage/invalid-argument' + ); + await expect(child.list({ maxResults: 1001 })).to.be.rejectedWith( + 'storage/invalid-argument' + ); + }); + }); + }); + + describe('root operations', () => { + let root: Reference; + before(() => { + root = service.refFromURL('gs://test-bucket'); + }); + it('put throws', () => { + expect(() => root.put(new Uint8Array())).to.throw( + 'storage/invalid-root-operation' + ); + }); + it('putString throws', () => { + expect(() => root.putString('raw', 'raw')).to.throw( + 'storage/invalid-root-operation' + ); + }); + it('delete throws', () => { + expect(() => root.delete()).to.throw('storage/invalid-root-operation'); + }); + it('getMetadata throws', async () => { + await expect(root.getMetadata()).to.be.rejectedWith( + 'storage/invalid-root-operation' + ); + }); + it('updateMetadata throws', async () => { + await expect(root.updateMetadata({})).to.be.rejectedWith( + 'storage/invalid-root-operation' + ); + }); + it('getDownloadURL throws', async () => { + await expect(root.getDownloadURL()).to.be.rejectedWith( + 'storage/invalid-root-operation' + ); + }); + }); +}); diff --git a/packages/storage-compat/test/unit/service.test.ts b/packages/storage-compat/test/unit/service.test.ts index 530aaf658d8..b8540ab01d9 100644 --- a/packages/storage-compat/test/unit/service.test.ts +++ b/packages/storage-compat/test/unit/service.test.ts @@ -25,9 +25,8 @@ import { FirebaseStorageError } from '@firebase/storage'; import firebase from '@firebase/app-compat'; - -const testCompatApp = firebase.initializeApp({}); -const testModularStorage = getStorage(testCompatApp); +import { StorageServiceCompat } from '../../src/service'; +import { FirebaseApp } from '@firebase/app-types'; const DEFAULT_HOST = 'firebasestorage.googleapis.com'; @@ -37,7 +36,7 @@ describe('Firebase Storage > Service', () => { const connectStorageEmulatorStub = stub( modularStorage, 'connectStorageEmulator' - ).callsFake(() => {}); + ).callsFake(() => { }); const service = makeTestCompatStorage(fakeApp, fakeStorage); service.useEmulator('test.host.org', 1234); @@ -50,7 +49,19 @@ describe('Firebase Storage > Service', () => { }); describe('refFromURL', () => { - const service = makeTestCompatStorage(testCompatApp, testModularStorage); + let service: StorageServiceCompat; + let testCompatApp: FirebaseApp; + let testModularStorage: FirebaseStorage; + before(() => { + testCompatApp = firebase.initializeApp({}); + testModularStorage = getStorage(testCompatApp); + service = makeTestCompatStorage(testCompatApp, testModularStorage); + }); + + after(() => { + return testCompatApp.delete(); + }); + it('Works with gs:// URLs', () => { const ref = service.refFromURL('gs://mybucket/child/path/image.png'); expect(ref.toString()).to.equal('gs://mybucket/child/path/image.png'); @@ -58,14 +69,14 @@ describe('Firebase Storage > Service', () => { it('Works with http:// URLs', () => { const ref = service.refFromURL( `http://${DEFAULT_HOST}/v0/b/` + - 'mybucket/o/child%2Fpath%2Fimage.png?downloadToken=hello' + 'mybucket/o/child%2Fpath%2Fimage.png?downloadToken=hello' ); expect(ref.toString()).to.equal('gs://mybucket/child/path/image.png'); }); it('Works with https:// URLs', () => { const ref = service.refFromURL( `https://${DEFAULT_HOST}/v0/b/` + - 'mybucket/o/child%2Fpath%2Fimage.png?downloadToken=hello' + 'mybucket/o/child%2Fpath%2Fimage.png?downloadToken=hello' ); expect(ref.toString()).to.equal('gs://mybucket/child/path/image.png'); }); @@ -105,7 +116,18 @@ GOOG4-RSA-SHA256` }); describe('Argument verification', () => { - const service = makeTestCompatStorage(testCompatApp, testModularStorage); + let service: StorageServiceCompat; + let testCompatApp: FirebaseApp; + let testModularStorage: FirebaseStorage; + before(() => { + testCompatApp = firebase.initializeApp({}); + testModularStorage = getStorage(testCompatApp); + service = makeTestCompatStorage(testCompatApp, testModularStorage); + }); + + after(() => { + return testCompatApp.delete(); + }); describe('ref', () => { it('Throws on gs:// argument', () => { @@ -159,7 +181,18 @@ GOOG4-RSA-SHA256` }); describe('Deletion', () => { - const service = makeTestCompatStorage(testCompatApp, testModularStorage); + let service: StorageServiceCompat; + let testCompatApp: FirebaseApp; + let testModularStorage: FirebaseStorage; + before(() => { + testCompatApp = firebase.initializeApp({}); + testModularStorage = getStorage(testCompatApp); + service = makeTestCompatStorage(testCompatApp, testModularStorage); + }); + + after(() => { + return testCompatApp.delete(); + }); it('In-flight requests are canceled when the service is deleted', async () => { const ref = service.refFromURL('gs://mybucket/image.jpg'); From c47721f7609701c4c7c3631acc2a5c2b711800d9 Mon Sep 17 00:00:00 2001 From: Feiyang1 Date: Tue, 10 Aug 2021 12:52:06 -0700 Subject: [PATCH 12/22] format --- .../test/unit/reference.test.ts | 324 +++++++++--------- .../storage-compat/test/unit/service.test.ts | 8 +- 2 files changed, 167 insertions(+), 165 deletions(-) diff --git a/packages/storage-compat/test/unit/reference.test.ts b/packages/storage-compat/test/unit/reference.test.ts index c8fb5fd9ccb..0d809a3c823 100644 --- a/packages/storage-compat/test/unit/reference.test.ts +++ b/packages/storage-compat/test/unit/reference.test.ts @@ -20,193 +20,195 @@ import { ReferenceCompat } from '../../src/reference'; import { StorageServiceCompat } from '../../src/service'; import { makeTestCompatStorage, fakeApp, fakeStorage } from '../utils'; import firebase from '@firebase/app-compat'; -import { StorageReference, getStorage, FirebaseStorage } from '@firebase/storage'; +import { + StorageReference, + getStorage, + FirebaseStorage +} from '@firebase/storage'; import { fake } from 'sinon'; import { FirebaseApp } from '@firebase/app-types'; import { Reference } from '@firebase/storage-types'; describe('Firebase Storage > Reference', () => { - let testCompatApp: FirebaseApp; - let testModularStorage: FirebaseStorage; - let service: StorageServiceCompat; - before(() => { - testCompatApp = firebase.initializeApp({}); - testModularStorage = getStorage(testCompatApp); - service = makeTestCompatStorage(testCompatApp, testModularStorage); - }); + let testCompatApp: FirebaseApp; + let testModularStorage: FirebaseStorage; + let service: StorageServiceCompat; + before(() => { + testCompatApp = firebase.initializeApp({}); + testModularStorage = getStorage(testCompatApp); + service = makeTestCompatStorage(testCompatApp, testModularStorage); + }); - after(() => { - return testCompatApp.delete(); - }); - describe('toString', () => { - it("delegates to the modular Reference.toString()", () => { - const fakeToString = fake.returns('test123'); - const ref = new ReferenceCompat({ - toString: fakeToString - } as unknown as StorageReference, makeTestCompatStorage(fakeApp, fakeStorage)); + after(() => { + return testCompatApp.delete(); + }); + describe('toString', () => { + it('delegates to the modular Reference.toString()', () => { + const fakeToString = fake.returns('test123'); + const ref = new ReferenceCompat( + { + toString: fakeToString + } as unknown as StorageReference, + makeTestCompatStorage(fakeApp, fakeStorage) + ); - expect(ref.toString()).to.equal('test123'); - expect(fakeToString).to.have.been.calledOnceWithExactly(); - }); + expect(ref.toString()).to.equal('test123'); + expect(fakeToString).to.have.been.calledOnceWithExactly(); }); + }); - describe('parent', () => { - it('Returns null at root', () => { - const root = service.refFromURL('gs://test-bucket'); - expect(root.parent).to.be.null; - }); - it('Returns root one level down', () => { - const child = service.refFromURL('gs://test-bucket/hello'); - expect(child.parent!.toString()).to.equal('gs://test-bucket/'); - }); - it('Works correctly with empty levels', () => { - const s = service.refFromURL('gs://test-bucket/a///'); - expect(s.parent!.toString()).to.equal('gs://test-bucket/a/'); - }); + describe('parent', () => { + it('Returns null at root', () => { + const root = service.refFromURL('gs://test-bucket'); + expect(root.parent).to.be.null; + }); + it('Returns root one level down', () => { + const child = service.refFromURL('gs://test-bucket/hello'); + expect(child.parent!.toString()).to.equal('gs://test-bucket/'); }); + it('Works correctly with empty levels', () => { + const s = service.refFromURL('gs://test-bucket/a///'); + expect(s.parent!.toString()).to.equal('gs://test-bucket/a/'); + }); + }); - describe('root', () => { - it('Returns self at root', () => { - const root = service.refFromURL('gs://test-bucket'); - expect(root.root.toString()).to.equal('gs://test-bucket/'); - }); + describe('root', () => { + it('Returns self at root', () => { + const root = service.refFromURL('gs://test-bucket'); + expect(root.root.toString()).to.equal('gs://test-bucket/'); + }); - it('Returns root multiple levels down', () => { - const s = service.refFromURL('gs://test-bucket/a/b/c/d'); - expect(s.root.toString()).to.equal('gs://test-bucket/'); - }); + it('Returns root multiple levels down', () => { + const s = service.refFromURL('gs://test-bucket/a/b/c/d'); + expect(s.root.toString()).to.equal('gs://test-bucket/'); }); + }); - describe('bucket', () => { - it('Returns bucket name', () => { - const root = service.refFromURL('gs://test-bucket'); - expect(root.bucket).to.equal('test-bucket'); - }); + describe('bucket', () => { + it('Returns bucket name', () => { + const root = service.refFromURL('gs://test-bucket'); + expect(root.bucket).to.equal('test-bucket'); }); + }); - describe('fullPath', () => { - it('Returns full path without leading slash', () => { - const s = service.refFromURL('gs://test-bucket/full/path'); - expect(s.fullPath).to.equal('full/path'); - }); + describe('fullPath', () => { + it('Returns full path without leading slash', () => { + const s = service.refFromURL('gs://test-bucket/full/path'); + expect(s.fullPath).to.equal('full/path'); }); + }); - describe('name', () => { - it('Works at top level', () => { - const s = service.refFromURL('gs://test-bucket/toplevel.txt'); - expect(s.name).to.equal('toplevel.txt'); - }); + describe('name', () => { + it('Works at top level', () => { + const s = service.refFromURL('gs://test-bucket/toplevel.txt'); + expect(s.name).to.equal('toplevel.txt'); + }); - it('Works at not the top level', () => { - const s = service.refFromURL('gs://test-bucket/not/toplevel.txt'); - expect('toplevel.txt').to.equal(s.name); - }); + it('Works at not the top level', () => { + const s = service.refFromURL('gs://test-bucket/not/toplevel.txt'); + expect('toplevel.txt').to.equal(s.name); }); + }); - describe('child', () => { - let root: Reference; - before(() => { - root = service.refFromURL('gs://test-bucket'); - }); - it('works with a simple string', () => { - expect(root.child('a').toString()).to.equal('gs://test-bucket/a'); - }); - it('drops a trailing slash', () => { - expect(root.child('ab/').toString()).to.equal('gs://test-bucket/ab'); - }); - it('compresses repeated slashes', () => { - expect(root.child('//a///b/////').toString()).to.equal( - 'gs://test-bucket/a/b' - ); - }); - it('works chained multiple times with leading slashes', () => { - expect( - root.child('a').child('/b').child('c').child('d/e').toString() - ).to.equal('gs://test-bucket/a/b/c/d/e'); - }); + describe('child', () => { + let root: Reference; + before(() => { + root = service.refFromURL('gs://test-bucket'); + }); + it('works with a simple string', () => { + expect(root.child('a').toString()).to.equal('gs://test-bucket/a'); + }); + it('drops a trailing slash', () => { + expect(root.child('ab/').toString()).to.equal('gs://test-bucket/ab'); + }); + it('compresses repeated slashes', () => { + expect(root.child('//a///b/////').toString()).to.equal( + 'gs://test-bucket/a/b' + ); + }); + it('works chained multiple times with leading slashes', () => { + expect( + root.child('a').child('/b').child('c').child('d/e').toString() + ).to.equal('gs://test-bucket/a/b/c/d/e'); }); + }); - describe('putString', () => { - let child: Reference; - before(() => { - child = service.refFromURL('gs://test-bucket/hello'); - }); - it('Uses metadata.contentType for RAW format', () => { - // Regression test for b/30989476 - const task = child.putString('hello', 'raw', { - contentType: 'lol/wut' - }); - expect(task.snapshot.metadata!.contentType).to.equal('lol/wut'); - task.cancel(); - }); - it('Uses embedded content type in DATA_URL format', () => { - const task = child.putString( - 'data:lol/wat;base64,aaaa', - 'data_url' - ); - expect(task.snapshot.metadata!.contentType).to.equal('lol/wat'); - task.cancel(); - }); - it('Lets metadata.contentType override embedded content type in DATA_URL format', () => { - const task = child.putString( - 'data:ignore/me;base64,aaaa', - 'data_url', - { contentType: 'tomato/soup' } - ); - expect(task.snapshot.metadata!.contentType).to.equal('tomato/soup'); - task.cancel(); - }); + describe('putString', () => { + let child: Reference; + before(() => { + child = service.refFromURL('gs://test-bucket/hello'); + }); + it('Uses metadata.contentType for RAW format', () => { + // Regression test for b/30989476 + const task = child.putString('hello', 'raw', { + contentType: 'lol/wut' + }); + expect(task.snapshot.metadata!.contentType).to.equal('lol/wut'); + task.cancel(); + }); + it('Uses embedded content type in DATA_URL format', () => { + const task = child.putString('data:lol/wat;base64,aaaa', 'data_url'); + expect(task.snapshot.metadata!.contentType).to.equal('lol/wat'); + task.cancel(); }); + it('Lets metadata.contentType override embedded content type in DATA_URL format', () => { + const task = child.putString('data:ignore/me;base64,aaaa', 'data_url', { + contentType: 'tomato/soup' + }); + expect(task.snapshot.metadata!.contentType).to.equal('tomato/soup'); + task.cancel(); + }); + }); - describe('Argument verification', () => { - describe('list', () => { - it('throws on invalid maxResults', async () => { - const child = service.refFromURL('gs://test-bucket/hello'); - await expect(child.list({ maxResults: 0 })).to.be.rejectedWith( - 'storage/invalid-argument' - ); - await expect(child.list({ maxResults: -4 })).to.be.rejectedWith( - 'storage/invalid-argument' - ); - await expect(child.list({ maxResults: 1001 })).to.be.rejectedWith( - 'storage/invalid-argument' - ); - }); - }); + describe('Argument verification', () => { + describe('list', () => { + it('throws on invalid maxResults', async () => { + const child = service.refFromURL('gs://test-bucket/hello'); + await expect(child.list({ maxResults: 0 })).to.be.rejectedWith( + 'storage/invalid-argument' + ); + await expect(child.list({ maxResults: -4 })).to.be.rejectedWith( + 'storage/invalid-argument' + ); + await expect(child.list({ maxResults: 1001 })).to.be.rejectedWith( + 'storage/invalid-argument' + ); + }); }); + }); - describe('root operations', () => { - let root: Reference; - before(() => { - root = service.refFromURL('gs://test-bucket'); - }); - it('put throws', () => { - expect(() => root.put(new Uint8Array())).to.throw( - 'storage/invalid-root-operation' - ); - }); - it('putString throws', () => { - expect(() => root.putString('raw', 'raw')).to.throw( - 'storage/invalid-root-operation' - ); - }); - it('delete throws', () => { - expect(() => root.delete()).to.throw('storage/invalid-root-operation'); - }); - it('getMetadata throws', async () => { - await expect(root.getMetadata()).to.be.rejectedWith( - 'storage/invalid-root-operation' - ); - }); - it('updateMetadata throws', async () => { - await expect(root.updateMetadata({})).to.be.rejectedWith( - 'storage/invalid-root-operation' - ); - }); - it('getDownloadURL throws', async () => { - await expect(root.getDownloadURL()).to.be.rejectedWith( - 'storage/invalid-root-operation' - ); - }); + describe('root operations', () => { + let root: Reference; + before(() => { + root = service.refFromURL('gs://test-bucket'); + }); + it('put throws', () => { + expect(() => root.put(new Uint8Array())).to.throw( + 'storage/invalid-root-operation' + ); + }); + it('putString throws', () => { + expect(() => root.putString('raw', 'raw')).to.throw( + 'storage/invalid-root-operation' + ); + }); + it('delete throws', () => { + expect(() => root.delete()).to.throw('storage/invalid-root-operation'); + }); + it('getMetadata throws', async () => { + await expect(root.getMetadata()).to.be.rejectedWith( + 'storage/invalid-root-operation' + ); + }); + it('updateMetadata throws', async () => { + await expect(root.updateMetadata({})).to.be.rejectedWith( + 'storage/invalid-root-operation' + ); + }); + it('getDownloadURL throws', async () => { + await expect(root.getDownloadURL()).to.be.rejectedWith( + 'storage/invalid-root-operation' + ); }); + }); }); diff --git a/packages/storage-compat/test/unit/service.test.ts b/packages/storage-compat/test/unit/service.test.ts index b8540ab01d9..8ca7d05299e 100644 --- a/packages/storage-compat/test/unit/service.test.ts +++ b/packages/storage-compat/test/unit/service.test.ts @@ -36,7 +36,7 @@ describe('Firebase Storage > Service', () => { const connectStorageEmulatorStub = stub( modularStorage, 'connectStorageEmulator' - ).callsFake(() => { }); + ).callsFake(() => {}); const service = makeTestCompatStorage(fakeApp, fakeStorage); service.useEmulator('test.host.org', 1234); @@ -69,14 +69,14 @@ describe('Firebase Storage > Service', () => { it('Works with http:// URLs', () => { const ref = service.refFromURL( `http://${DEFAULT_HOST}/v0/b/` + - 'mybucket/o/child%2Fpath%2Fimage.png?downloadToken=hello' + 'mybucket/o/child%2Fpath%2Fimage.png?downloadToken=hello' ); expect(ref.toString()).to.equal('gs://mybucket/child/path/image.png'); }); it('Works with https:// URLs', () => { const ref = service.refFromURL( `https://${DEFAULT_HOST}/v0/b/` + - 'mybucket/o/child%2Fpath%2Fimage.png?downloadToken=hello' + 'mybucket/o/child%2Fpath%2Fimage.png?downloadToken=hello' ); expect(ref.toString()).to.equal('gs://mybucket/child/path/image.png'); }); @@ -184,7 +184,7 @@ GOOG4-RSA-SHA256` let service: StorageServiceCompat; let testCompatApp: FirebaseApp; let testModularStorage: FirebaseStorage; - before(() => { + before(() => { testCompatApp = firebase.initializeApp({}); testModularStorage = getStorage(testCompatApp); service = makeTestCompatStorage(testCompatApp, testModularStorage); From 56aa473b76d97e846691f872c7c966b1742d647c Mon Sep 17 00:00:00 2001 From: Feiyang1 Date: Tue, 10 Aug 2021 14:45:34 -0700 Subject: [PATCH 13/22] update package json --- packages/storage-compat/package.json | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/packages/storage-compat/package.json b/packages/storage-compat/package.json index 955157b9eae..3c64b594710 100644 --- a/packages/storage-compat/package.json +++ b/packages/storage-compat/package.json @@ -8,22 +8,22 @@ "module": "./dist/index.esm2017.js", "esm5": "./dist/index.esm5.js", "license": "Apache-2.0", - "typings": "./dist/storage-compat/src/index.d.ts", + "typings": "./dist/src/index.d.ts", "scripts": { "lint": "eslint -c .eslintrc.js '**/*.ts' --ignore-path '../../.gitignore'", "lint:fix": "eslint --fix -c .eslintrc.js '**/*.ts' --ignore-path '../../.gitignore'", - "build": "rollup -c rollup.config.js", + "build": "rollup -c rollup.config.js && yarn add-compat-overloads", "build:deps": "lerna run --scope @firebase/storage-compat --include-dependencies build", "dev": "rollup -c -w", "test": "run-p test:browser test:node lint", "test:ci": "node ../../scripts/run_tests_in_ci.js -s test:browser test:node", - "test:browser:unit": "karma start --single-run --compat --unit", - "test:browser:integration": "karma start --single-run --compat --integration", + "test:browser:unit": "karma start --single-run --unit", + "test:browser:integration": "karma start --single-run --integration", "test:browser": "karma start --single-run", "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 src/index.ts --config ../../config/mocharc.node.js", "test:debug": "karma start --browser=Chrome", "prettier": "prettier --write 'src/**/*.ts' 'test/**/*.ts'", - "add-compat-overloads": "ts-node-script ../../scripts/exp/create-overloads.ts -i ../storage/dist/storage-public.d.ts -o dist/storage-compat/src/index.d.ts -a -r FirebaseStorage:types.FirebaseStorage -r StorageReference:types.Reference -r FirebaseApp:FirebaseAppCompat --moduleToEnhance @firebase/storage" + "add-compat-overloads": "ts-node-script ../../scripts/exp/create-overloads.ts -i ../storage/dist/storage-public.d.ts -o dist/src/index.d.ts -a -r FirebaseStorage:types.FirebaseStorage -r StorageReference:types.Reference -r FirebaseApp:FirebaseAppCompat --moduleToEnhance @firebase/storage" }, "peerDependencies": { "@firebase/app-compat": "0.x" @@ -37,7 +37,6 @@ }, "devDependencies": { "rollup": "2.52.2", - "@rollup/plugin-alias": "3.1.2", "@rollup/plugin-json": "4.1.0", "rollup-plugin-typescript2": "0.30.0", "typescript": "4.2.2" From 307ca6c8d4698d521bdedbc0c169665aff62c10d Mon Sep 17 00:00:00 2001 From: Feiyang1 Date: Tue, 10 Aug 2021 14:55:19 -0700 Subject: [PATCH 14/22] cleanup --- packages/storage-compat/.eslintrc.js | 1 - packages/storage-compat/package.json | 1 + packages/storage/.eslintrc.js | 11 ----------- packages/storage/.npmignore | 9 --------- packages/storage/karma.conf.js | 8 -------- packages/storage/package.json | 12 +++--------- 6 files changed, 4 insertions(+), 38 deletions(-) delete mode 100644 packages/storage/.npmignore diff --git a/packages/storage-compat/.eslintrc.js b/packages/storage-compat/.eslintrc.js index 185597fec61..ffe0e481071 100644 --- a/packages/storage-compat/.eslintrc.js +++ b/packages/storage-compat/.eslintrc.js @@ -26,7 +26,6 @@ module.exports = { tsconfigRootDir: __dirname }, rules: { - 'no-throw-literal': 'off', '@typescript-eslint/no-unused-vars': [ 'error', { diff --git a/packages/storage-compat/package.json b/packages/storage-compat/package.json index 3c64b594710..27f4f341b35 100644 --- a/packages/storage-compat/package.json +++ b/packages/storage-compat/package.json @@ -36,6 +36,7 @@ "tslib": "^2.1.0" }, "devDependencies": { + "@firebase/app-compat": "0.x", "rollup": "2.52.2", "@rollup/plugin-json": "4.1.0", "rollup-plugin-typescript2": "0.30.0", diff --git a/packages/storage/.eslintrc.js b/packages/storage/.eslintrc.js index 00bf88df31c..ffe0e481071 100644 --- a/packages/storage/.eslintrc.js +++ b/packages/storage/.eslintrc.js @@ -26,23 +26,12 @@ module.exports = { tsconfigRootDir: __dirname }, rules: { - 'no-throw-literal': 'off', '@typescript-eslint/no-unused-vars': [ 'error', { varsIgnorePattern: '^_', args: 'none' } - ], - 'import/no-extraneous-dependencies': [ - 'error', - { - 'packageDir': [ - path.resolve(__dirname, '../../'), - __dirname, - path.resolve(__dirname, 'exp') - ] - } ] } }; diff --git a/packages/storage/.npmignore b/packages/storage/.npmignore deleted file mode 100644 index 682c8f74a52..00000000000 --- a/packages/storage/.npmignore +++ /dev/null @@ -1,9 +0,0 @@ -# Directories not needed by end users -/src -test - -# Files not needed by end users -gulpfile.js -index.ts -karma.conf.js -tsconfig.json \ No newline at end of file diff --git a/packages/storage/karma.conf.js b/packages/storage/karma.conf.js index daa472b2fe2..3b5d7e3f39b 100644 --- a/packages/storage/karma.conf.js +++ b/packages/storage/karma.conf.js @@ -34,14 +34,6 @@ function getTestFiles(argv) { let unitTestFiles = ['test/unit/*']; let integrationTestFiles = ['test/integration/*']; - // if (argv.compat) { - // unitTestFiles = unitTestFiles.filter( - // filename => !filename.includes('.exp.') - // ); - // integrationTestFiles = ['test/integration/*compat*']; - // } else { - // integrationTestFiles = ['test/integration/*']; - // } if (argv.unit) { return unitTestFiles; } else if (argv.integration) { diff --git a/packages/storage/package.json b/packages/storage/package.json index 986e699061b..072a1275fa3 100644 --- a/packages/storage/package.json +++ b/packages/storage/package.json @@ -8,8 +8,7 @@ "browser": "dist/index.esm2017.js", "esm5": "dist/index.esm5.js", "files": [ - "dist", - "exp/dist" + "dist" ], "scripts": { "bundle": "rollup -c", @@ -20,12 +19,8 @@ "dev": "rollup -c -w", "test": "run-p test:browser test:node lint", "test:ci": "node ../../scripts/run_tests_in_ci.js -s test:browser test:node", - "test:browser:compat:unit": "karma start --single-run --compat --unit", - "test:browser:exp:unit": "karma start --single-run --exp --unit", - "test:browser:compat:integration": "karma start --single-run --compat --integration", - "test:browser:exp:integration": "karma start --single-run --exp --integration", - "test:browser:compat": "karma start --single-run --compat", - "test:browser:exp": "karma start --single-run --exp", + "test:browser:unit": "karma start --single-run --unit", + "test:browser:integration": "karma start --single-run --integration", "test:browser": "karma start --single-run", "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 src/index.ts --config ../../config/mocharc.node.js", "test:debug": "karma start --browser=Chrome", @@ -34,7 +29,6 @@ }, "license": "Apache-2.0", "dependencies": { - "@firebase/storage-types": "0.4.1", "@firebase/util": "1.2.0", "@firebase/component": "0.5.5", "node-fetch": "2.6.1", From 3097128a0404e0f560a8b1c1daf8976949172c5c Mon Sep 17 00:00:00 2001 From: Feiyang1 Date: Tue, 10 Aug 2021 14:58:21 -0700 Subject: [PATCH 15/22] format --- packages/rules-unit-testing/src/api/index.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/rules-unit-testing/src/api/index.ts b/packages/rules-unit-testing/src/api/index.ts index 51d16209187..9cf12e24af9 100644 --- a/packages/rules-unit-testing/src/api/index.ts +++ b/packages/rules-unit-testing/src/api/index.ts @@ -160,7 +160,7 @@ export type FirebaseEmulatorOptions = { function trimmedBase64Encode(val: string): string { // Use base64url encoding and remove padding in the end (dot characters). - return base64Encode(val).replace(/\./g, ""); + return base64Encode(val).replace(/\./g, ''); } function createUnsecuredJwt(token: TokenOptions, projectId?: string): string { @@ -498,7 +498,7 @@ function initializeApp( ComponentType.PRIVATE ); - ((app as unknown) as _FirebaseApp)._addOrOverwriteComponent( + (app as unknown as _FirebaseApp)._addOrOverwriteComponent( mockAuthComponent ); } @@ -703,7 +703,7 @@ export function assertFails(pr: Promise): any { errCode === 'permission-denied' || errCode === 'permission_denied' || errMessage.indexOf('permission_denied') >= 0 || - errMessage.indexOf('permission denied') >= 0 || + errMessage.indexOf('permission denied') >= 0 || // Storage permission errors contain message: (storage/unauthorized) errMessage.indexOf('unauthorized') >= 0; From d3723ad9c3e56a8d71077ce1d42fe6ac8051ab2a Mon Sep 17 00:00:00 2001 From: Feiyang1 Date: Thu, 12 Aug 2021 16:44:13 -0700 Subject: [PATCH 16/22] address comments --- packages/storage-compat/src/reference.ts | 2 +- packages/storage/src/implementation/observer.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/storage-compat/src/reference.ts b/packages/storage-compat/src/reference.ts index 9d6bb19ee95..0494c5a41de 100644 --- a/packages/storage-compat/src/reference.ts +++ b/packages/storage-compat/src/reference.ts @@ -35,7 +35,7 @@ import { _FbsBlob, _dataFromString, _invalidRootOperation -} from '@firebase/storage'; // import from the exp public API +} from '@firebase/storage'; import { UploadTaskCompat } from './task'; import { ListResultCompat } from './list'; diff --git a/packages/storage/src/implementation/observer.ts b/packages/storage/src/implementation/observer.ts index 910cf8fe008..d1ab432610d 100644 --- a/packages/storage/src/implementation/observer.ts +++ b/packages/storage/src/implementation/observer.ts @@ -81,8 +81,8 @@ export class Observer implements StorageObserver { isFunction(nextOrObserver) || error != null || complete != null; if (asFunctions) { this.next = nextOrObserver as NextFn; - this.error = error || undefined; - this.complete = complete || undefined; + this.error = error ?? undefined; + this.complete = complete ?? undefined; } else { const observer = nextOrObserver as { next?: NextFn; From fb7e7c644123a3017e4c599c907aba5c76b64647 Mon Sep 17 00:00:00 2001 From: Feiyang Date: Tue, 17 Aug 2021 23:45:54 -0700 Subject: [PATCH 17/22] Update packages/storage-compat/test/unit/service.test.ts Co-authored-by: Christina Holland --- packages/storage-compat/test/unit/service.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/storage-compat/test/unit/service.test.ts b/packages/storage-compat/test/unit/service.test.ts index 8ca7d05299e..5059052218b 100644 --- a/packages/storage-compat/test/unit/service.test.ts +++ b/packages/storage-compat/test/unit/service.test.ts @@ -43,7 +43,8 @@ describe('Firebase Storage > Service', () => { expect(connectStorageEmulatorStub).to.have.been.calledWithExactly( fakeStorage, 'test.host.org', - 1234 + 1234, + {} ); }); }); From 572294d8f40ec56cd79e1e50572a757c349500a4 Mon Sep 17 00:00:00 2001 From: Feiyang1 Date: Wed, 18 Aug 2021 12:20:11 -0700 Subject: [PATCH 18/22] add missing dev dep --- packages/storage-compat/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/storage-compat/package.json b/packages/storage-compat/package.json index 27f4f341b35..28dd8792155 100644 --- a/packages/storage-compat/package.json +++ b/packages/storage-compat/package.json @@ -37,6 +37,7 @@ }, "devDependencies": { "@firebase/app-compat": "0.x", + "@firebase/auth-compat": "0.x", "rollup": "2.52.2", "@rollup/plugin-json": "4.1.0", "rollup-plugin-typescript2": "0.30.0", From 37fba27cbc1abe50f40a26659c275bd9f80efe6d Mon Sep 17 00:00:00 2001 From: Christina Holland Date: Wed, 18 Aug 2021 15:20:13 -0700 Subject: [PATCH 19/22] Update packages/storage-compat/package.json --- packages/storage-compat/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/storage-compat/package.json b/packages/storage-compat/package.json index 28dd8792155..d5540264e97 100644 --- a/packages/storage-compat/package.json +++ b/packages/storage-compat/package.json @@ -29,7 +29,7 @@ "@firebase/app-compat": "0.x" }, "dependencies": { - "@firebase/storage": "0.6.1", + "@firebase/storage": "0.6.2", "@firebase/storage-types": "0.4.1", "@firebase/util": "1.2.0", "@firebase/component": "0.5.5", From 5afdd505cce2a4c236ad02b40c3918ec9fee2750 Mon Sep 17 00:00:00 2001 From: Christina Holland Date: Thu, 19 Aug 2021 14:07:37 -0700 Subject: [PATCH 20/22] Update packages/storage-compat/package.json --- packages/storage-compat/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/storage-compat/package.json b/packages/storage-compat/package.json index d5540264e97..2c0bbe0f53d 100644 --- a/packages/storage-compat/package.json +++ b/packages/storage-compat/package.json @@ -29,7 +29,7 @@ "@firebase/app-compat": "0.x" }, "dependencies": { - "@firebase/storage": "0.6.2", + "@firebase/storage": "0.7.0", "@firebase/storage-types": "0.4.1", "@firebase/util": "1.2.0", "@firebase/component": "0.5.5", From 6c2ddcb8dae75c55b4a8bde70a834ef9a8ae3d16 Mon Sep 17 00:00:00 2001 From: Christina Holland Date: Thu, 19 Aug 2021 14:13:44 -0700 Subject: [PATCH 21/22] Update deps after v8 release --- packages/storage-compat/package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/storage-compat/package.json b/packages/storage-compat/package.json index 2c0bbe0f53d..67d9923f172 100644 --- a/packages/storage-compat/package.json +++ b/packages/storage-compat/package.json @@ -30,9 +30,9 @@ }, "dependencies": { "@firebase/storage": "0.7.0", - "@firebase/storage-types": "0.4.1", - "@firebase/util": "1.2.0", - "@firebase/component": "0.5.5", + "@firebase/storage-types": "0.5.0", + "@firebase/util": "1.3.0", + "@firebase/component": "0.5.6", "tslib": "^2.1.0" }, "devDependencies": { @@ -46,4 +46,4 @@ "files": [ "dist" ] -} +} \ No newline at end of file From 773f579addb34b195475c2c581a0e3dce4a00622 Mon Sep 17 00:00:00 2001 From: Feiyang1 Date: Thu, 19 Aug 2021 16:43:18 -0700 Subject: [PATCH 22/22] update compat version --- packages/storage-compat/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/storage-compat/package.json b/packages/storage-compat/package.json index 67d9923f172..b629bf8298a 100644 --- a/packages/storage-compat/package.json +++ b/packages/storage-compat/package.json @@ -1,6 +1,6 @@ { "name": "@firebase/storage-compat", - "version": "0.1.0", + "version": "0.0.900", "description": "The Firebase Firestore compatibility package", "author": "Firebase (https://firebase.google.com/)", "main": "./dist/index.cjs.js",