UNPKG

12.4 kBJavaScriptView Raw
1import { Observable, of, from } from 'rxjs';
2import { debounceTime, map, switchMap, tap } from 'rxjs/operators';
3import * as i1 from '@angular/fire';
4import { observeOutsideAngular, keepUnstableUntilFirst, VERSION } from '@angular/fire';
5import * as i0 from '@angular/core';
6import { InjectionToken, PLATFORM_ID, Injectable, Inject, Optional, Pipe, NgModule } from '@angular/core';
7import { ɵfirebaseAppFactory, ɵcacheInstance, FIREBASE_OPTIONS, FIREBASE_APP_NAME } from '@angular/fire/compat';
8import 'firebase/compat/storage';
9import * as i2 from '@angular/fire/app-check';
10import { AsyncPipe } from '@angular/common';
11import * as i2$1 from '@angular/platform-browser';
12import { makeStateKey } from '@angular/platform-browser';
13import firebase from 'firebase/compat/app';
14
15// Things aren't working great, I'm having to put in a lot of work-arounds for what
16// appear to be Firebase JS SDK bugs https://github.com/firebase/firebase-js-sdk/issues/4158
17function fromTask(task) {
18 return new Observable(subscriber => {
19 const progress = (snap) => subscriber.next(snap);
20 const error = e => subscriber.error(e);
21 const complete = () => subscriber.complete();
22 // emit the current snapshot, so they don't have to wait for state_changes
23 // to fire next... this is stale if the task is no longer running :(
24 progress(task.snapshot);
25 const unsub = task.on('state_changed', progress);
26 // it turns out that neither task snapshot nor 'state_changed' fire the last
27 // snapshot before completion, the one with status 'success" and 100% progress
28 // so let's use the promise form of the task for that
29 task.then(snapshot => {
30 progress(snapshot);
31 complete();
32 }, e => {
33 // TODO investigate, again this is stale, we never fire a canceled or error it seems
34 progress(task.snapshot);
35 error(e);
36 });
37 // on's type if Function, rather than () => void, need to wrap
38 return function unsubscribe() {
39 unsub();
40 };
41 }).pipe(
42 // deal with sync emissions from first emitting `task.snapshot`, this makes sure
43 // that if the task is already finished we don't emit the old running state
44 debounceTime(0));
45}
46
47/**
48 * Create an AngularFireUploadTask from a regular UploadTask from the Storage SDK.
49 * This method creates an observable of the upload and returns on object that provides
50 * multiple methods for controlling and monitoring the file upload.
51 */
52function createUploadTask(task) {
53 const inner$ = fromTask(task);
54 return {
55 task,
56 then: task.then.bind(task),
57 catch: task.catch.bind(task),
58 pause: task.pause.bind(task),
59 cancel: task.cancel.bind(task),
60 resume: task.resume.bind(task),
61 snapshotChanges: () => inner$,
62 percentageChanges: () => inner$.pipe(map(s => s.bytesTransferred / s.totalBytes * 100))
63 };
64}
65
66/**
67 * Create an AngularFire wrapped Storage Reference. This object
68 * creates observable methods from promise based methods.
69 */
70function createStorageRef(ref) {
71 return {
72 getDownloadURL: () => of(undefined).pipe(observeOutsideAngular, switchMap(() => ref.getDownloadURL()), keepUnstableUntilFirst),
73 getMetadata: () => of(undefined).pipe(observeOutsideAngular, switchMap(() => ref.getMetadata()), keepUnstableUntilFirst),
74 delete: () => from(ref.delete()),
75 child: (path) => createStorageRef(ref.child(path)),
76 updateMetadata: (meta) => from(ref.updateMetadata(meta)),
77 put: (data, metadata) => {
78 const task = ref.put(data, metadata);
79 return createUploadTask(task);
80 },
81 putString: (data, format, metadata) => {
82 const task = ref.putString(data, format, metadata);
83 return createUploadTask(task);
84 },
85 list: (options) => from(ref.list(options)),
86 listAll: () => from(ref.listAll())
87 };
88}
89
90const BUCKET = new InjectionToken('angularfire2.storageBucket');
91const MAX_UPLOAD_RETRY_TIME = new InjectionToken('angularfire2.storage.maxUploadRetryTime');
92const MAX_OPERATION_RETRY_TIME = new InjectionToken('angularfire2.storage.maxOperationRetryTime');
93const USE_EMULATOR = new InjectionToken('angularfire2.storage.use-emulator');
94/**
95 * AngularFireStorage Service
96 *
97 * This service is the main entry point for this feature module. It provides
98 * an API for uploading and downloading binary files from Cloud Storage for
99 * Firebase.
100 */
101class AngularFireStorage {
102 constructor(options, name, storageBucket,
103 // tslint:disable-next-line:ban-types
104 platformId, zone, schedulers, maxUploadRetryTime, maxOperationRetryTime, _useEmulator, _appCheckInstances) {
105 const app = ɵfirebaseAppFactory(options, zone, name);
106 this.storage = ɵcacheInstance(`${app.name}.storage.${storageBucket}`, 'AngularFireStorage', app.name, () => {
107 const storage = zone.runOutsideAngular(() => app.storage(storageBucket || undefined));
108 const useEmulator = _useEmulator;
109 if (useEmulator) {
110 storage.useEmulator(...useEmulator);
111 }
112 if (maxUploadRetryTime) {
113 storage.setMaxUploadRetryTime(maxUploadRetryTime);
114 }
115 if (maxOperationRetryTime) {
116 storage.setMaxOperationRetryTime(maxOperationRetryTime);
117 }
118 return storage;
119 }, [maxUploadRetryTime, maxOperationRetryTime]);
120 }
121 ref(path) {
122 return createStorageRef(this.storage.ref(path));
123 }
124 refFromURL(path) {
125 return createStorageRef(this.storage.refFromURL(path));
126 }
127 upload(path, data, metadata) {
128 const storageRef = this.storage.ref(path);
129 const ref = createStorageRef(storageRef);
130 return ref.put(data, metadata);
131 }
132}
133AngularFireStorage.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.3", ngImport: i0, type: AngularFireStorage, deps: [{ token: FIREBASE_OPTIONS }, { token: FIREBASE_APP_NAME, optional: true }, { token: BUCKET, optional: true }, { token: PLATFORM_ID }, { token: i0.NgZone }, { token: i1.ɵAngularFireSchedulers }, { token: MAX_UPLOAD_RETRY_TIME, optional: true }, { token: MAX_OPERATION_RETRY_TIME, optional: true }, { token: USE_EMULATOR, optional: true }, { token: i2.AppCheckInstances, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
134AngularFireStorage.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.1.3", ngImport: i0, type: AngularFireStorage, providedIn: 'any' });
135i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.3", ngImport: i0, type: AngularFireStorage, decorators: [{
136 type: Injectable,
137 args: [{
138 providedIn: 'any'
139 }]
140 }], ctorParameters: function () { return [{ type: undefined, decorators: [{
141 type: Inject,
142 args: [FIREBASE_OPTIONS]
143 }] }, { type: undefined, decorators: [{
144 type: Optional
145 }, {
146 type: Inject,
147 args: [FIREBASE_APP_NAME]
148 }] }, { type: undefined, decorators: [{
149 type: Optional
150 }, {
151 type: Inject,
152 args: [BUCKET]
153 }] }, { type: Object, decorators: [{
154 type: Inject,
155 args: [PLATFORM_ID]
156 }] }, { type: i0.NgZone }, { type: i1.ɵAngularFireSchedulers }, { type: undefined, decorators: [{
157 type: Optional
158 }, {
159 type: Inject,
160 args: [MAX_UPLOAD_RETRY_TIME]
161 }] }, { type: undefined, decorators: [{
162 type: Optional
163 }, {
164 type: Inject,
165 args: [MAX_OPERATION_RETRY_TIME]
166 }] }, { type: undefined, decorators: [{
167 type: Optional
168 }, {
169 type: Inject,
170 args: [USE_EMULATOR]
171 }] }, { type: i2.AppCheckInstances, decorators: [{
172 type: Optional
173 }] }]; } });
174
175/** to be used with in combination with | async */
176class GetDownloadURLPipe {
177 constructor(storage, cdr, state) {
178 this.storage = storage;
179 this.state = state;
180 this.asyncPipe = new AsyncPipe(cdr);
181 }
182 transform(path) {
183 var _a;
184 if (path !== this.path) {
185 this.path = path;
186 const key = makeStateKey(`|getDownloadURL|${path}`);
187 const existing = (_a = this.state) === null || _a === void 0 ? void 0 : _a.get(key, undefined);
188 this.downloadUrl$ = existing ? of(existing) : this.storage.ref(path).getDownloadURL().pipe(tap(it => { var _a; return (_a = this.state) === null || _a === void 0 ? void 0 : _a.set(key, it); }));
189 }
190 return this.asyncPipe.transform(this.downloadUrl$);
191 }
192 ngOnDestroy() {
193 this.asyncPipe.ngOnDestroy();
194 }
195}
196GetDownloadURLPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.3", ngImport: i0, type: GetDownloadURLPipe, deps: [{ token: AngularFireStorage }, { token: i0.ChangeDetectorRef }, { token: i2$1.TransferState, optional: true }], target: i0.ɵɵFactoryTarget.Pipe });
197GetDownloadURLPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "12.0.0", version: "12.1.3", ngImport: i0, type: GetDownloadURLPipe, name: "getDownloadURL", pure: false });
198i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.3", ngImport: i0, type: GetDownloadURLPipe, decorators: [{
199 type: Pipe,
200 args: [{
201 name: 'getDownloadURL',
202 pure: false,
203 }]
204 }], ctorParameters: function () { return [{ type: AngularFireStorage }, { type: i0.ChangeDetectorRef }, { type: i2$1.TransferState, decorators: [{
205 type: Optional
206 }] }]; } });
207class GetDownloadURLPipeModule {
208}
209GetDownloadURLPipeModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.3", ngImport: i0, type: GetDownloadURLPipeModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
210GetDownloadURLPipeModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.1.3", ngImport: i0, type: GetDownloadURLPipeModule, declarations: [GetDownloadURLPipe], exports: [GetDownloadURLPipe] });
211GetDownloadURLPipeModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.1.3", ngImport: i0, type: GetDownloadURLPipeModule });
212i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.3", ngImport: i0, type: GetDownloadURLPipeModule, decorators: [{
213 type: NgModule,
214 args: [{
215 declarations: [GetDownloadURLPipe],
216 exports: [GetDownloadURLPipe],
217 }]
218 }] });
219
220class AngularFireStorageModule {
221 constructor() {
222 firebase.registerVersion('angularfire', VERSION.full, 'gcs-compat');
223 }
224}
225AngularFireStorageModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.3", ngImport: i0, type: AngularFireStorageModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
226AngularFireStorageModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.1.3", ngImport: i0, type: AngularFireStorageModule, exports: [GetDownloadURLPipeModule] });
227AngularFireStorageModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.1.3", ngImport: i0, type: AngularFireStorageModule, providers: [AngularFireStorage], imports: [GetDownloadURLPipeModule] });
228i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.3", ngImport: i0, type: AngularFireStorageModule, decorators: [{
229 type: NgModule,
230 args: [{
231 exports: [GetDownloadURLPipeModule],
232 providers: [AngularFireStorage]
233 }]
234 }], ctorParameters: function () { return []; } });
235
236/**
237 * Generated bundle index. Do not edit.
238 */
239
240export { AngularFireStorage, AngularFireStorageModule, BUCKET, GetDownloadURLPipe, GetDownloadURLPipeModule, MAX_OPERATION_RETRY_TIME, MAX_UPLOAD_RETRY_TIME, USE_EMULATOR, createStorageRef, createUploadTask, fromTask };
241//# sourceMappingURL=angular-fire-compat-storage.js.map