├── .gitignore ├── .idea ├── bashsupport_project.xml ├── inspectionProfiles │ └── Project_Default.xml ├── misc.xml └── modules.xml ├── CHANGELOG.md ├── README.md ├── docs ├── firebase-rxjs-angular │ ├── assets │ │ ├── css │ │ │ ├── main.css │ │ │ └── main.css.map │ │ ├── images │ │ │ ├── icons.png │ │ │ ├── icons@2x.png │ │ │ ├── widgets.png │ │ │ └── widgets@2x.png │ │ └── js │ │ │ ├── main.js │ │ │ └── search.js │ ├── classes │ │ └── firebaserxjsmodule.html │ ├── globals.html │ └── index.html └── firebase-rxjs │ ├── assets │ ├── css │ │ ├── main.css │ │ └── main.css.map │ ├── images │ │ ├── icons.png │ │ ├── icons@2x.png │ │ ├── widgets.png │ │ └── widgets@2x.png │ └── js │ │ ├── main.js │ │ └── search.js │ ├── classes │ ├── datasnapshotobservable.html │ ├── emailauthprovider.html │ ├── event.html │ ├── facebookauthprovider.html │ ├── firebaseapp.html │ ├── firebaseauth.html │ ├── firebasedatabase.html │ ├── firebasedatabaseref.html │ ├── firebasequery.html │ ├── firebaseuser.html │ ├── firebaseusercredential.html │ ├── githubauthprovider.html │ ├── googleauthprovider.html │ ├── infoschema.html │ ├── nativefirebaseapp.html │ ├── nativefirebaseauth.html │ ├── nativefirebasedatabase.html │ ├── twitterauthprovider.html │ └── zonehelper.html │ ├── globals.html │ ├── index.html │ └── interfaces │ ├── actioncodeerror.html │ ├── actioncodeinfo.html │ ├── autherror.html │ ├── confirmpasswordreseterror.html │ ├── createuserwithemailandpassworderror.html │ ├── deleteusererror.html │ ├── extendeddatasnapshot.html │ ├── extras.html │ ├── fetchprovidersforemailerror.html │ ├── firebaseappconfig.html │ ├── firebaseerror.html │ ├── getredirectresulterror.html │ ├── linkusererror.html │ ├── linkuserwithpopuperror.html │ ├── linkuserwithredirecterror.html │ ├── reauthenticateerror.html │ ├── sendpasswordresetemailerror.html │ ├── signinanonymouslyerror.html │ ├── signinwithcredentialerror.html │ ├── signinwithcustomtokenerror.html │ ├── signinwithemailandpassworderror.html │ ├── signinwithpopuperror.html │ ├── signinwithredirecterror.html │ ├── updateemailerror.html │ ├── updatepassworderror.html │ └── verifypasswordresetcodeerror.html ├── examples └── database-schema.ts ├── firebase-rxjs.iml ├── karma.conf.js ├── package.json ├── packages ├── firebase-rxjs-angular │ ├── firebase-rxjs-angular.ts │ ├── index.ts │ ├── package.json │ ├── rollup.config.js │ ├── src │ │ ├── firebase-rxjs-module.spec.ts │ │ └── firebase-rxjs-module.ts │ └── tsconfig.dist.json ├── firebase-rxjs │ ├── firebase-rxjs.ts │ ├── index.ts │ ├── package.json │ ├── rollup.config.js │ ├── src │ │ ├── app.ts │ │ ├── auth.spec.ts │ │ ├── auth.ts │ │ ├── data-snapshot-observable.ts │ │ ├── database.spec.ts │ │ ├── database.ts │ │ ├── interfaces.ts │ │ ├── native-firebase.ts │ │ ├── user.spec.ts │ │ ├── user.ts │ │ ├── zone-helper.spec.no-zone.ts │ │ └── zone-helper.ts │ ├── testing │ │ ├── jasmine.ts │ │ ├── log-spec.ts │ │ └── testing.ts │ └── tsconfig.dist.json ├── tests.no-zone.ts ├── tests.ts ├── tsconfig.json └── typings.d.ts ├── scripts ├── build.sh ├── e2e-test.sh └── version.js ├── testing ├── karma.conf.common.js ├── karma.conf.no-zone.js └── ng-project │ ├── .angular-cli.json │ ├── .editorconfig │ ├── .gitignore │ ├── README.md │ ├── e2e │ ├── app.e2e-spec.ts │ ├── app.po.ts │ └── tsconfig.e2e.json │ ├── karma.conf.js │ ├── package.json │ ├── protractor.conf.js │ ├── src │ ├── app │ │ ├── app.component.css │ │ ├── app.component.html │ │ ├── app.component.spec.ts │ │ ├── app.component.ts │ │ └── app.module.ts │ ├── assets │ │ └── .gitkeep │ ├── environments │ │ ├── environment.prod.ts │ │ └── environment.ts │ ├── favicon.ico │ ├── index.html │ ├── main.ts │ ├── polyfills.ts │ ├── styles.css │ ├── test.ts │ ├── tsconfig.app.json │ ├── tsconfig.spec.json │ └── typings.d.ts │ ├── tsconfig.json │ ├── tslint.json │ └── yarn.lock ├── typedoc.json └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Linux template 3 | *~ 4 | 5 | # temporary files which can be created if a process still has a handle open of a deleted file 6 | .fuse_hidden* 7 | 8 | # KDE directory preferences 9 | .directory 10 | 11 | # Linux trash folder which might appear on any partition or disk 12 | .Trash-* 13 | ### JetBrains template 14 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm 15 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 16 | 17 | # User-specific stuff: 18 | .idea/workspace.xml 19 | .idea/tasks.xml 20 | .idea/dictionaries 21 | .idea/vcs.xml 22 | .idea/jsLibraryMappings.xml 23 | 24 | # Sensitive or high-churn files: 25 | .idea/dataSources.ids 26 | .idea/dataSources.xml 27 | .idea/dataSources.local.xml 28 | .idea/sqlDataSources.xml 29 | .idea/dynamic.xml 30 | .idea/uiDesigner.xml 31 | 32 | # Gradle: 33 | .idea/gradle.xml 34 | .idea/libraries 35 | 36 | # Mongo Explorer plugin: 37 | .idea/mongoSettings.xml 38 | 39 | ## File-based project format: 40 | *.iws 41 | 42 | ## Plugin-specific files: 43 | 44 | # IntelliJ 45 | /out/ 46 | 47 | # mpeltonen/sbt-idea plugin 48 | .idea_modules/ 49 | 50 | # JIRA plugin 51 | atlassian-ide-plugin.xml 52 | 53 | # Crashlytics plugin (for Android Studio and IntelliJ) 54 | com_crashlytics_export_strings.xml 55 | crashlytics.properties 56 | crashlytics-build.properties 57 | fabric.properties 58 | ### OSX template 59 | *.DS_Store 60 | .AppleDouble 61 | .LSOverride 62 | 63 | # Icon must end with two \r 64 | Icon 65 | 66 | # Thumbnails 67 | ._* 68 | 69 | # Files that might appear in the root of a volume 70 | .DocumentRevisions-V100 71 | .fseventsd 72 | .Spotlight-V100 73 | .TemporaryItems 74 | .Trashes 75 | .VolumeIcon.icns 76 | .com.apple.timemachine.donotpresent 77 | 78 | # Directories potentially created on remote AFP share 79 | .AppleDB 80 | .AppleDesktop 81 | Network Trash Folder 82 | Temporary Items 83 | .apdisk 84 | ### Windows template 85 | # Windows image file caches 86 | Thumbs.db 87 | ehthumbs.db 88 | 89 | # Folder config file 90 | Desktop.ini 91 | 92 | # Recycle Bin used on file shares 93 | $RECYCLE.BIN/ 94 | 95 | # Windows Installer files 96 | *.cab 97 | *.msi 98 | *.msm 99 | *.msp 100 | 101 | # Windows shortcuts 102 | *.lnk 103 | ### Node template 104 | # Logs 105 | logs 106 | *.log 107 | npm-debug.log* 108 | 109 | # Runtime data 110 | pids 111 | *.pid 112 | *.seed 113 | 114 | # Directory for instrumented libs generated by jscoverage/JSCover 115 | lib-cov 116 | 117 | # Coverage directory used by tools like istanbul 118 | coverage 119 | 120 | # nyc test coverage 121 | .nyc_output 122 | 123 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 124 | .grunt 125 | 126 | # node-waf configuration 127 | .lock-wscript 128 | 129 | # Compiled binary addons (http://nodejs.org/api/addons.html) 130 | build/Release 131 | 132 | # Dependency directories 133 | node_modules 134 | jspm_packages 135 | 136 | # Optional npm cache directory 137 | .npm 138 | 139 | # Optional REPL history 140 | .node_repl_history 141 | 142 | firebase.config.local.json 143 | dist/ 144 | -------------------------------------------------------------------------------- /.idea/bashsupport_project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | Java 18 | 19 | 20 | Logging issuesJava 21 | 22 | 23 | 24 | 25 | Android 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. 4 | 5 | 6 | ## [0.1.2](https://github.com/blaugold/firebase-rxjs/compare/v0.1.1...v0.1.2) (2017-09-01) 7 | 8 | 9 | ### Bug Fixes 10 | 11 | * use zone helper to wrap callback in `transaction` method ([31e3dc3](https://github.com/blaugold/firebase-rxjs/commit/31e3dc3)), closes [#2](https://github.com/blaugold/firebase-rxjs/issues/2) 12 | 13 | 14 | 15 | 16 | ## [0.1.1](https://github.com/blaugold/firebase-rxjs/compare/v0.1.0...v0.1.1) (2017-04-21) 17 | 18 | 19 | ### Bug Fixes 20 | 21 | * **DataSnapshot:** replace ExtendedDataSnapshot DataSnapshot with correct typing and .ref set correctly ([95d86fe](https://github.com/blaugold/firebase-rxjs/commit/95d86fe)) 22 | * **zoneHelper:** Prevent errors when Zone is not used ([9977009](https://github.com/blaugold/firebase-rxjs/commit/9977009)) 23 | 24 | 25 | 26 | 27 | # 0.1.0 (2017-03-29) 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FirebaseRxJS 2 | 3 | Firebase with Observables, Type Checking of Schema, Zone.js aware and Angular ready. 4 | 5 | - Asynchronous results are returned as observables. 6 | - Strings in `.child("pathSegment")` can be validated through static type checking and a schema interface. 7 | - If zone.js is in scope firebase sdk runs in separate zone. 8 | - For use in angular apps `FirebaseRxJSModule` is provided. 9 | 10 | TypeScript@2.1.0 and angular@4.0.0 are required. 11 | 12 | TypeScript Docs: 13 | 14 | - [firebase-rxjs](https://blaugold.github.io/firebase-rxjs/firebase-rxjs/) 15 | - [firebase-rxjs-angular](https://blaugold.github.io/firebase-rxjs/firebase-rxjs-angular/) 16 | 17 | ```bash 18 | npm install --save firebase-rxjs 19 | # For angular module 20 | npm install --save firebase-rxjs-angular 21 | ``` 22 | 23 | ## Configuration 24 | 25 | Create a new `FirebaseApp` by passing in the config from [Firebase Console](https://console.firebase.google.com/). 26 | 27 | ```typescript 28 | import { FirebaseApp } from 'firebase-rxjs' 29 | 30 | const app = new FirebaseApp({ options: { 31 | apiKey: "...", 32 | authDomain: "...", 33 | databaseURL: "...", 34 | storageBucket: "...", 35 | messagingSenderId: "..." 36 | }}); 37 | 38 | // Get a reference to `FirebaseAuth` 39 | const auth = app.auth() 40 | 41 | auth.createUserWithEmailAndPassword("...", "...").subscribe(user => { 42 | ... 43 | }) 44 | ``` 45 | 46 | ## Usage 47 | 48 | To get static type checking when accessing the database define a database schema interface. 49 | Its best to compose the schema out of smaller interfaces. This keeps your schema clear and 50 | allows you to easily access subsections with `db.ref('path/to/something')`. 51 | 52 | ```typescript 53 | // database-schema.ts 54 | export interface UserProfile { 55 | firstName: string 56 | lastName: string 57 | twitter: string 58 | profileImg: string 59 | } 60 | 61 | export interface Comment { 62 | text: string 63 | createdAt: number 64 | author: string 65 | authorId: string 66 | } 67 | 68 | export interface Comments { 69 | [commentId: string]: Comment 70 | } 71 | 72 | export interface BlogPost { 73 | title: string 74 | summary: string 75 | body: string 76 | author: string 77 | authorId: string 78 | publishedAt: number 79 | updatedAt: number 80 | comments: Comments 81 | } 82 | 83 | export interface DBSchema { 84 | users: { 85 | [userId: string]: UserProfile 86 | } 87 | blogPosts: { 88 | [postId: string]: BlogPost 89 | } 90 | } 91 | ``` 92 | 93 | Now when getting a reference of the database use the schema interface as the type parameter. 94 | 95 | ```typescript 96 | import { FirebaseApp } from 'firebase-rxjs' 97 | import { DBSchema } from './database-schema.ts' 98 | 99 | const app: FirebaseApp 100 | const db = app.database() 101 | 102 | // Now the compiler will yell at you if you use the wrong path segments. 103 | db.ref().child('userz') 104 | 105 | // Or if you go deeper in the tree pass a sub schema as the type parameter. 106 | const commentsRef = db.ref('blogPosts/1/comments') 107 | 108 | // Using a schema will also give you better IntelliSense when accessing the retrieved data. 109 | commentsRef.onValue().list().subscribe(comments => { 110 | comments[0].key 111 | comments[0].val.body 112 | }) 113 | ``` 114 | 115 | The result of onValue, onChildAdded, etc is a `DataSnapshotObservable` which is typed 116 | according to the previous calls and the schema. It provides some helpful methods to make working 117 | with `DataSnapshots` easier, but the snapshots can be accessed directly too. 118 | 119 | Most methods overall mirror the firebase sdk and behave the same. 120 | 121 | ## Angular 122 | 123 | Include the `FirebaseRxJSModule` in your root module. It is possible to provide multiple apps for 124 | injection but only one primary app. The primary `FirebaseApp` will make itself, `FirebaseAuth` and 125 | `FirebaseDatabase` injectable directly. Secondary apps have to be configured with an 126 | `InjectionToken` which will inject the `FirebaseApp`. 127 | 128 | ```typescript 129 | import { NgModule, InjectionToken } from '@angular/core' 130 | import { FirebaseRxJSModule, FirebaseApp } from 'firebase-rxjs-angular' 131 | 132 | const secondaryApp = new InjectionToken() 133 | 134 | @NgModule({ 135 | ... 136 | imports: [ 137 | FirebaseRxJSModule.primaryApp({options: ... }), 138 | FirebaseRxJSModule.secondaryApp(secondaryApp, {options: ... }), 139 | ], 140 | ... 141 | }) 142 | export class AppModule {} 143 | ``` 144 | 145 | ## Zone.js 146 | 147 | If `Zone` is globally available all calls to the firebase sdk will run in an isolated zone, forked 148 | from the root zone. Alternatively a zone can be passed to the `FirebaseApp` constructor. All other 149 | methods take the zone of their call site and schedule tasks with it. 150 | 151 | Motivation for this feature is a problem which lets all protractor tests timeout unless synchronization is 152 | turned off. The cause lies in how protractor determines when changes stemming from the last input 153 | have propagated and the next instruction or expectation can be executed. It does this by observing 154 | whether or not MicroTasks and MacroTasks are scheduled to run. Once the queues of theses tasks are 155 | empty it's safe to assume the dom wont change. EventTasks like listeners on `WebSocket.onmessage` 156 | could run and change the dom but that is unpredictable and can not be factored in to the decision 157 | when to proceed with the test. Now what if micro and macro tasks schedule new tasks themselves? 158 | Protractor again will wait until all tasks have run. And this is what is problematic. When using 159 | the database the firebase sdk sends a heartbeat by setting up a timeout which first sends the 160 | heartbeat and then reschedules the next timeout. The result is a recursive chain of never ending 161 | MacroTasks keeping the task queue dirty. Independently of that the firebase sdk sets up a long 162 | running (around 30 seconds) timeout during initialization timing out any test by itself. 163 | 164 | ## Real Time 165 | 166 | Its worth noting that all write operations and one off reads are scheduled as MacroTasks, 167 | meaning protractor or angular's `async` test helper will wait until these tasks have run. This is not 168 | true for observables returned from `.{on}{Value,ChildAdded,ChildRemove,ChildChanged,ChildMoved}()`. 169 | The semantics of MacroTasks are that they are 170 |
guaranteed to execute at least once after some well understood delay.
171 | For a real time databases like Firebase the correct tasks to use is the EventTask. This type of task 172 | is expected to run zero or multiple times with unpredictable timing. So when using the methods 173 | starting with `on`, tests relying on zone.js will not wait for them to complete, unless the framework 174 | is configured to wait for all EventTasks to be canceled. For each observable 175 | which emits real time database events the library schedules an EventTask on subscription and cancels 176 | it when the observable is unsubscribed. To make testing these kinds of observables simpler a test helper for 177 | the jasmine testing framework is included: 178 | 179 | ```typescript 180 | import { asyncEvents } from 'firebase-rxjs' 181 | 182 | describe('Suite', () => { 183 | it('should wait for EventTasks to clear', asyncEvents(async () => { 184 | const db: FirebaseDatabase 185 | // This observable will unsubscribe itself after emitting 3 events. 186 | db.ref().child('foo').onValue().take(3).subscribe() 187 | 188 | // Multiple observables or other asynchronous tasks will block the test until their 189 | // resolution too. 190 | const res = await fetch('https://www.google.com') 191 | })) 192 | }) 193 | ``` 194 | 195 | End-to-end tests should poll content on the page under test, which is dependent on real time changes, 196 | until a expected state is reached or timeout. 197 | 198 | -------------------------------------------------------------------------------- /docs/firebase-rxjs-angular/assets/css/main.css.map: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "mappings": "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", 4 | "sources": ["../../../../src/default/assets/css/vendors/_normalize.sass","../../../../src/default/assets/css/vendors/_highlight.js.sass","../../../../src/default/assets/css/setup/_mixins.sass","../../../../src/default/assets/css/setup/_grid.sass","../../../../src/default/assets/css/setup/_icons.scss","../../../../src/default/assets/css/setup/_animations.sass","../../../../src/default/assets/css/setup/_typography.sass","../../../../src/default/assets/css/_constants.sass","../../../../src/default/assets/css/layouts/_default.sass","../../../../src/default/assets/css/layouts/_minimal.sass","../../../../src/default/assets/css/elements/_comment.sass","../../../../src/default/assets/css/elements/_filter.sass","../../../../src/default/assets/css/elements/_footer.sass","../../../../src/default/assets/css/elements/_hierarchy.sass","../../../../src/default/assets/css/elements/_index.sass","../../../../src/default/assets/css/elements/_member.sass","../../../../src/default/assets/css/elements/_navigation.sass","../../../../src/default/assets/css/elements/_panel.sass","../../../../src/default/assets/css/elements/_search.sass","../../../../src/default/assets/css/elements/_signatures.sass","../../../../src/default/assets/css/elements/_sources.sass","../../../../src/default/assets/css/elements/_toolbar.sass","../../../../src/default/assets/css/elements/_images.sass"], 5 | "names": [], 6 | "file": "main.css" 7 | } 8 | -------------------------------------------------------------------------------- /docs/firebase-rxjs-angular/assets/images/icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blaugold/firebase-rxjs/cc0a0a0e92c43f8deb1030b222f0ee23b0494d54/docs/firebase-rxjs-angular/assets/images/icons.png -------------------------------------------------------------------------------- /docs/firebase-rxjs-angular/assets/images/icons@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blaugold/firebase-rxjs/cc0a0a0e92c43f8deb1030b222f0ee23b0494d54/docs/firebase-rxjs-angular/assets/images/icons@2x.png -------------------------------------------------------------------------------- /docs/firebase-rxjs-angular/assets/images/widgets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blaugold/firebase-rxjs/cc0a0a0e92c43f8deb1030b222f0ee23b0494d54/docs/firebase-rxjs-angular/assets/images/widgets.png -------------------------------------------------------------------------------- /docs/firebase-rxjs-angular/assets/images/widgets@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blaugold/firebase-rxjs/cc0a0a0e92c43f8deb1030b222f0ee23b0494d54/docs/firebase-rxjs-angular/assets/images/widgets@2x.png -------------------------------------------------------------------------------- /docs/firebase-rxjs-angular/assets/js/search.js: -------------------------------------------------------------------------------- 1 | var typedoc = typedoc || {}; 2 | typedoc.search = typedoc.search || {}; 3 | typedoc.search.data = {"kinds":{},"rows":[]}; -------------------------------------------------------------------------------- /docs/firebase-rxjs/assets/css/main.css.map: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "mappings": "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", 4 | "sources": ["../../../../src/default/assets/css/vendors/_normalize.sass","../../../../src/default/assets/css/vendors/_highlight.js.sass","../../../../src/default/assets/css/setup/_mixins.sass","../../../../src/default/assets/css/setup/_grid.sass","../../../../src/default/assets/css/setup/_icons.scss","../../../../src/default/assets/css/setup/_animations.sass","../../../../src/default/assets/css/setup/_typography.sass","../../../../src/default/assets/css/_constants.sass","../../../../src/default/assets/css/layouts/_default.sass","../../../../src/default/assets/css/layouts/_minimal.sass","../../../../src/default/assets/css/elements/_comment.sass","../../../../src/default/assets/css/elements/_filter.sass","../../../../src/default/assets/css/elements/_footer.sass","../../../../src/default/assets/css/elements/_hierarchy.sass","../../../../src/default/assets/css/elements/_index.sass","../../../../src/default/assets/css/elements/_member.sass","../../../../src/default/assets/css/elements/_navigation.sass","../../../../src/default/assets/css/elements/_panel.sass","../../../../src/default/assets/css/elements/_search.sass","../../../../src/default/assets/css/elements/_signatures.sass","../../../../src/default/assets/css/elements/_sources.sass","../../../../src/default/assets/css/elements/_toolbar.sass","../../../../src/default/assets/css/elements/_images.sass"], 5 | "names": [], 6 | "file": "main.css" 7 | } 8 | -------------------------------------------------------------------------------- /docs/firebase-rxjs/assets/images/icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blaugold/firebase-rxjs/cc0a0a0e92c43f8deb1030b222f0ee23b0494d54/docs/firebase-rxjs/assets/images/icons.png -------------------------------------------------------------------------------- /docs/firebase-rxjs/assets/images/icons@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blaugold/firebase-rxjs/cc0a0a0e92c43f8deb1030b222f0ee23b0494d54/docs/firebase-rxjs/assets/images/icons@2x.png -------------------------------------------------------------------------------- /docs/firebase-rxjs/assets/images/widgets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blaugold/firebase-rxjs/cc0a0a0e92c43f8deb1030b222f0ee23b0494d54/docs/firebase-rxjs/assets/images/widgets.png -------------------------------------------------------------------------------- /docs/firebase-rxjs/assets/images/widgets@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blaugold/firebase-rxjs/cc0a0a0e92c43f8deb1030b222f0ee23b0494d54/docs/firebase-rxjs/assets/images/widgets@2x.png -------------------------------------------------------------------------------- /docs/firebase-rxjs/assets/js/search.js: -------------------------------------------------------------------------------- 1 | var typedoc = typedoc || {}; 2 | typedoc.search = typedoc.search || {}; 3 | typedoc.search.data = {"kinds":{"65536":"Type literal"},"rows":[{"id":0,"kind":65536,"name":"__type","url":"interfaces/firebaseappconfig.html#options.__type","classes":"tsd-kind-type-literal tsd-parent-kind-property tsd-is-not-exported","parent":"FirebaseAppConfig.options"}]}; -------------------------------------------------------------------------------- /examples/database-schema.ts: -------------------------------------------------------------------------------- 1 | import 'rxjs/add/operator/map' 2 | import { FirebaseApp } from '../' 3 | 4 | /** 5 | * This example demonstrates the type checking ability when the database is used with a schema. 6 | * Open this file with an ide like VS Code or WebStorm and you should see error highlighting. 7 | */ 8 | 9 | interface DBSchema { 10 | todoLists: { 11 | [listId: string]: { 12 | name: string 13 | todoItems: { 14 | [itemId: string]: { 15 | title: string 16 | checked: boolean 17 | } 18 | } 19 | } 20 | } 21 | } 22 | 23 | let app = new FirebaseApp({ options: {} } as any) 24 | let db = app.database() 25 | 26 | // Should compile. 27 | db.ref().child('todoLists').child('1').child('todoItems') 28 | 29 | db.ref().child('todoLists').child('1').child('name').onValue().val() 30 | .map((name: string /* Compiles since `name`has type string. */) => {}) 31 | 32 | db.ref().child('todoLists') 33 | .orderByChild('name').startAt('A') 34 | .onChildChanged().val() 35 | .map(c => c.name) 36 | 37 | // Should not compile. 38 | db.ref().child('todoLists').child('1').child('todoItemz') // todoItemz should be todoItems. 39 | 40 | db.ref().child('todoLists').child('1').child('name').onValue().val() 41 | .map((name: number /* Fails since `name` has type string. */) => {}) -------------------------------------------------------------------------------- /firebase-rxjs.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const {getKarmaConfig} = require("./testing/karma.conf.common"); 3 | 4 | module.exports = function (karma) { 5 | karma.set(getKarmaConfig({testBundle: './packages/tests.ts', karma})) 6 | }; 7 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "firebase-rxjs", 3 | "version": "0.1.2", 4 | "description": "Firebase with Observables, Type Checking of Schema, Zone.js aware and Angular ready.", 5 | "keywords": [ 6 | "Firebase", 7 | "zone.js", 8 | "Observables", 9 | "TypeScript", 10 | "Schema", 11 | "Static Typing", 12 | "RxJS" 13 | ], 14 | "main": "./bundles/firebase-rxjs.umd.js", 15 | "module": "./bundles/firebase-rxjs.es5.js", 16 | "es2015": "./index.js", 17 | "typings": "./index.d.ts", 18 | "scripts": { 19 | "docs": "./scripts/build.sh build docs", 20 | "upload-coverage": "coveralls < coverage/lcov.info", 21 | "karma": "karma", 22 | "test:with-zone": "COVERAGE=true karma start --single-run", 23 | "test:no-zone": "karma start testing/karma.conf.no-zone.js --single-run", 24 | "test": "npm run test:with-zone && npm run test:no-zone", 25 | "e2e": "./scripts/e2e-test.sh", 26 | "build": "./scripts/build.sh build", 27 | "release": "standard-version" 28 | }, 29 | "author": "Gabriel Terwesten ", 30 | "license": "MIT", 31 | "dependencies": { 32 | "@angular/core": "^4.0.3", 33 | "firebase": "^3.8.0", 34 | "rxjs": "^5.3.0", 35 | "zone.js": "^0.8.0" 36 | }, 37 | "devDependencies": { 38 | "@angular/common": "^4.0.3", 39 | "@angular/compiler": "^4.0.3", 40 | "@angular/compiler-cli": "^4.0.3", 41 | "@angular/platform-browser": "^4.0.3", 42 | "@angular/platform-browser-dynamic": "^4.0.3", 43 | "@types/jasmine": "^2.5.47", 44 | "@types/node": "^7.0.13", 45 | "awesome-typescript-loader": "^3.1.2", 46 | "core-js": "^2.4.1", 47 | "coveralls": "^2.13.0", 48 | "cpy-cli": "^1.0.1", 49 | "jasmine": "^2.5.3", 50 | "karma": "^1.6.0", 51 | "karma-chrome-launcher": "^2.0.0", 52 | "karma-jasmine": "^1.1.0", 53 | "karma-jasmine-html-reporter": "^0.2.2", 54 | "karma-mocha-reporter": "^2.2.3", 55 | "karma-remap-istanbul": "^0.6.0", 56 | "karma-webpack": "^2.0.3", 57 | "rimraf": "^2.6.1", 58 | "rollup": "^0.41.6", 59 | "sourcemap-istanbul-instrumenter-loader": "^0.2.0", 60 | "standard-version": "^4.0.0", 61 | "typedoc": "^0.5.10", 62 | "typescript": "^2.2.2", 63 | "uglifyjs": "^2.4.10", 64 | "webpack": "^2.4.1" 65 | }, 66 | "directories": { 67 | "doc": "docs" 68 | }, 69 | "repository": { 70 | "type": "git", 71 | "url": "git+https://github.com/blaugold/firebase-rxjs.git" 72 | }, 73 | "bugs": { 74 | "url": "https://github.com/blaugold/firebase-rxjs/issues" 75 | }, 76 | "homepage": "https://github.com/blaugold/firebase-rxjs#readme" 77 | } 78 | -------------------------------------------------------------------------------- /packages/firebase-rxjs-angular/firebase-rxjs-angular.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @module 3 | */ 4 | export { FirebaseRxJSModule } from './src/firebase-rxjs-module' 5 | -------------------------------------------------------------------------------- /packages/firebase-rxjs-angular/index.ts: -------------------------------------------------------------------------------- 1 | export * from './firebase-rxjs-angular' -------------------------------------------------------------------------------- /packages/firebase-rxjs-angular/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "firebase-rxjs-angular", 3 | "version": "<--VERION_PLACEHOLDER-->", 4 | "main": "./bundles/firebase-rxjs-angular.umd.js", 5 | "module": "./firebase-rxjs-angular.js", 6 | "typings": "./firebase-rxjs-angular.d.ts", 7 | "author": "Gabriel Terwesten ", 8 | "peerDependencies": { 9 | "@angular/core": "^4.0.0", 10 | "firebase-rxjs": "^<--VERION_PLACEHOLDER-->" 11 | }, 12 | "license": "MIT", 13 | "repository": { 14 | "type": "git", 15 | "url": "git+https://github.com/blaugold/firebase-rxjs.git" 16 | }, 17 | "bugs": { 18 | "url": "https://github.com/blaugold/firebase-rxjs/issues" 19 | }, 20 | "homepage": "https://github.com/blaugold/firebase-rxjs#readme" 21 | } 22 | -------------------------------------------------------------------------------- /packages/firebase-rxjs-angular/rollup.config.js: -------------------------------------------------------------------------------- 1 | 2 | export default { 3 | entry: './dist/packages/firebase-rxjs-angular/firebase-rxjs-angular.js', 4 | dest: './dist/packages/firebase-rxjs-angular/bundles/firebase-rxjs-angular.umd.js', 5 | format: 'umd', 6 | moduleName: 'firebaseRxJS.ng', 7 | sourceMap: true, 8 | exports: 'named', 9 | context: 'this', 10 | onwarn: () => {}, 11 | globals: { 12 | "@angular/core": "ng.core", 13 | "firebase-rxjs": "firebaseRxJS" 14 | }, 15 | } 16 | -------------------------------------------------------------------------------- /packages/firebase-rxjs-angular/src/firebase-rxjs-module.spec.ts: -------------------------------------------------------------------------------- 1 | import { InjectionToken } from '@angular/core' 2 | import { TestBed } from '@angular/core/testing' 3 | import { FirebaseApp, FirebaseAuth, FirebaseDatabase } from 'firebase-rxjs' 4 | import { FirebaseRxJSModule } from './firebase-rxjs-module' 5 | 6 | const fbOptionsA = { 7 | apiKey: "a", 8 | authDomain: "a.firebaseapp.com", 9 | databaseURL: "https://a.firebaseio.com", 10 | storageBucket: "a.appspot.com", 11 | messagingSenderId: "99999999999" 12 | } 13 | 14 | const fbOptionsB = { 15 | apiKey: "b", 16 | authDomain: "b.firebaseapp.com", 17 | databaseURL: "https://b.firebaseio.com", 18 | storageBucket: "b.appspot.com", 19 | messagingSenderId: "00000000000" 20 | } 21 | 22 | describe('Module: FirebaseRxJSModule', () => { 23 | 24 | it('support a primary app', () => { 25 | TestBed.configureTestingModule({ 26 | imports: [ 27 | FirebaseRxJSModule.primaryApp({ 28 | options: fbOptionsA 29 | }), 30 | ] 31 | }) 32 | 33 | const defaultApp = TestBed.get(FirebaseApp) 34 | const defaultAuth = TestBed.get(FirebaseAuth) 35 | const defaultDatabase = TestBed.get(FirebaseDatabase) 36 | 37 | expect(defaultApp).toBeDefined() 38 | expect(defaultAuth).toBe(defaultApp.auth()) 39 | expect(defaultDatabase).toBe(defaultApp.database()) 40 | }) 41 | 42 | it('support a secondary app', () => { 43 | const secondAppToken = new InjectionToken('App two') 44 | 45 | TestBed.configureTestingModule({ 46 | imports: [ 47 | FirebaseRxJSModule.primaryApp({ 48 | options: fbOptionsA 49 | }), 50 | FirebaseRxJSModule.secondaryApp(secondAppToken, { 51 | options: fbOptionsB 52 | }), 53 | ] 54 | }) 55 | 56 | const defaultApp = TestBed.get(FirebaseApp) 57 | const defaultAuth = TestBed.get(FirebaseAuth) 58 | const defaultDatabase = TestBed.get(FirebaseDatabase) 59 | 60 | const secondApp: FirebaseApp = TestBed.get(secondAppToken) 61 | const secondAuth = secondApp.auth() 62 | const secondDatabase = secondApp.database() 63 | 64 | expect(secondApp).toBeDefined() 65 | 66 | expect(defaultApp).not.toBe(secondApp) 67 | expect(defaultAuth).not.toBe(secondAuth) 68 | expect(defaultDatabase).not.toBe(secondDatabase) 69 | }) 70 | }) 71 | -------------------------------------------------------------------------------- /packages/firebase-rxjs-angular/src/firebase-rxjs-module.ts: -------------------------------------------------------------------------------- 1 | import { InjectionToken, ModuleWithProviders, NgModule } from '@angular/core' 2 | import { FirebaseApp, FirebaseAppConfig, FirebaseAuth, FirebaseDatabase } from 'firebase-rxjs' 3 | 4 | /** @internal */ 5 | export function appFactory(config: FirebaseAppConfig) { 6 | return new FirebaseApp(config) 7 | } 8 | 9 | /** @internal */ 10 | export function authFactory(app: FirebaseApp) { 11 | return app.auth() 12 | } 13 | 14 | /** @internal */ 15 | export function databaseFactory(app: FirebaseApp) { 16 | return app.database() 17 | } 18 | 19 | @NgModule({}) 20 | export class FirebaseRxJSModule { 21 | /** 22 | * Provides a firebase app which will be be injected for {@link FirebaseApp}. Further the app's 23 | * {@link FirebaseAuth} and {@link FirebaseDatabase} can be injected in the same way. 24 | * @param config Firebase app config. 25 | */ 26 | static primaryApp(config: FirebaseAppConfig): ModuleWithProviders { 27 | 28 | return { 29 | ngModule: FirebaseRxJSModule, 30 | providers: [ 31 | { 32 | provide: 'firebase-config-' + config.options.apiKey, 33 | useValue: config 34 | }, 35 | { 36 | provide: FirebaseApp, 37 | useFactory: appFactory, 38 | deps: ['firebase-config-' + config.options.apiKey] 39 | }, 40 | { 41 | provide: FirebaseAuth, 42 | useFactory: authFactory, 43 | deps: [FirebaseApp] 44 | }, 45 | { 46 | provide: FirebaseDatabase, 47 | useFactory: databaseFactory, 48 | deps: [FirebaseApp] 49 | } 50 | ] 51 | } 52 | } 53 | 54 | /** 55 | * Provides a {@link FirebaseApp} which will be injected for token. 56 | * 57 | * @param token Token for which {@link FirebaseApp} will be injected. 58 | * @param config Firebase app config. 59 | */ 60 | static secondaryApp(token: InjectionToken, config: FirebaseAppConfig) { 61 | return { 62 | ngModule: FirebaseRxJSModule, 63 | providers: [ 64 | { 65 | provide: 'firebase-config-' + config.options.apiKey, 66 | useValue: config 67 | }, 68 | { 69 | provide: token, 70 | useFactory: appFactory, 71 | deps: ['firebase-config-' + config.options.apiKey,] 72 | } 73 | ] 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /packages/firebase-rxjs-angular/tsconfig.dist.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "moduleResolution": "node", 4 | "rootDir": ".", 5 | "baseUrl": ".", 6 | "outDir": "../../dist/packages/firebase-rxjs-angular", 7 | "target": "es5", 8 | "module": "es2015", 9 | "declaration": true, 10 | "sourceMap": true, 11 | "inlineSources": true, 12 | "experimentalDecorators": true, 13 | "emitDecoratorMetadata": true, 14 | "noImplicitAny": true, 15 | "lib":[ 16 | "dom", 17 | "es2015" 18 | ], 19 | "paths": { 20 | "@angular/core": [ 21 | "node_modules/@angular/core" 22 | ], 23 | "firebase-rxjs": [ 24 | "../../dist/packages/firebase-rxjs" 25 | ] 26 | }, 27 | "types": [] 28 | }, 29 | "files": [ 30 | "firebase-rxjs-angular.ts", 31 | "../../node_modules/zone.js/dist/zone.js.d.ts" 32 | ], 33 | "angularCompilerOptions": { 34 | "strictMetadataEmit": true 35 | } 36 | } -------------------------------------------------------------------------------- /packages/firebase-rxjs/firebase-rxjs.ts: -------------------------------------------------------------------------------- 1 | export * from './src/app' 2 | export * from './src/auth' 3 | export * from './src/database' 4 | export * from './src/user' 5 | export * from './src/interfaces' 6 | export * from './src/data-snapshot-observable' 7 | -------------------------------------------------------------------------------- /packages/firebase-rxjs/index.ts: -------------------------------------------------------------------------------- 1 | export * from './firebase-rxjs' 2 | export { asyncEvents } from './testing/jasmine' -------------------------------------------------------------------------------- /packages/firebase-rxjs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "firebase-rxjs", 3 | "version": "<--VERION_PLACEHOLDER-->", 4 | "description": "Firebase with Observables and Database Schema Static Typing + zone.js aware.", 5 | "keywords": [ 6 | "Firebase", 7 | "Zone.js", 8 | "Observable", 9 | "TypeScript", 10 | "Schema", 11 | "Static Typing", 12 | "RxJS" 13 | ], 14 | "main": "./bundles/firebase-rxjs.umd.js", 15 | "module": "./firebase-rxjs.js", 16 | "typings": "./firebase-rxjs.d.ts", 17 | "author": "Gabriel Terwesten ", 18 | "license": "MIT", 19 | "dependencies": { 20 | "firebase": "^3.8.0" 21 | }, 22 | "peerDependencies": { 23 | "rxjs": "^5.0.0" 24 | }, 25 | "repository": { 26 | "type": "git", 27 | "url": "git+https://github.com/blaugold/firebase-rxjs.git" 28 | }, 29 | "bugs": { 30 | "url": "https://github.com/blaugold/firebase-rxjs/issues" 31 | }, 32 | "homepage": "https://github.com/blaugold/firebase-rxjs#readme" 33 | } 34 | -------------------------------------------------------------------------------- /packages/firebase-rxjs/rollup.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by gabrielterwesten on 24/03/2017. 3 | */ 4 | 5 | export default { 6 | entry: './dist/packages/firebase-rxjs/firebase-rxjs.js', 7 | dest: './dist/packages/firebase-rxjs/bundles/firebase-rxjs.umd.js', 8 | exports: 'named', 9 | format: 'umd', 10 | moduleName: 'firebaseRxJS', 11 | sourceMap: true, 12 | context: 'this', 13 | onwarn: () => {}, 14 | globals: { 15 | 'firebase': 'firebase', 16 | 'rxjs/Observable': 'Rx', 17 | 'rxjs/Subscriber': 'Rx', 18 | 'rxjs/observable/fromPromise': 'Rx.Observable', 19 | 'rxjs/observable/of': 'Rx.Observable', 20 | 'rxjs/operator/map': 'Rx.Observable.prototype', 21 | 'rxjs/operator/mapTo': 'Rx.Observable.prototype', 22 | 'rxjs/operator/mergeMap': 'Rx.Observable.prototype', 23 | 'rxjs/operator/toArray': 'Rx.Observable.prototype', 24 | 'rxjs/operator/share': 'Rx.Observable.prototype', 25 | }, 26 | } 27 | -------------------------------------------------------------------------------- /packages/firebase-rxjs/src/app.ts: -------------------------------------------------------------------------------- 1 | import * as firebase from 'firebase' 2 | import { Observable } from 'rxjs/Observable' 3 | import { FirebaseAuth } from './auth' 4 | import { FirebaseDatabase } from './database' 5 | import { NativeFirebaseApp } from './native-firebase' 6 | import { ZoneHelper } from './zone-helper' 7 | import { Extras, FirebaseAppConfig } from './interfaces' 8 | 9 | let lastAppId = 0 10 | 11 | export class FirebaseApp { 12 | nativeApp: NativeFirebaseApp 13 | 14 | private _auth: FirebaseAuth 15 | private _database: FirebaseDatabase 16 | 17 | /** @internal */ 18 | zoneHelper: ZoneHelper 19 | 20 | constructor(public config: FirebaseAppConfig, { firebaseZone }: Extras = {}) { 21 | config.name = config.name || `app-${lastAppId++}` 22 | this.zoneHelper = new ZoneHelper(firebaseZone) 23 | this.nativeApp = this.zoneHelper.runInFirebase(() => 24 | firebase.initializeApp(config.options, config.name)) 25 | } 26 | 27 | delete(): Observable { 28 | return this.zoneHelper.wrapPromise(() => this.nativeApp.delete()) 29 | } 30 | 31 | /** 32 | * Get the with this {@link FirebaseApp} associated {@link FirebaseAuth} instance. 33 | */ 34 | auth(): FirebaseAuth { 35 | if (!this._auth) { 36 | this._auth = 37 | new FirebaseAuth(this.zoneHelper.runInFirebase(() => this.nativeApp.auth()), this) 38 | } 39 | return this._auth 40 | } 41 | 42 | /** 43 | * Get the with this {@link FirebaseApp} associated {@link FirebaseDatabase}. 44 | * 45 | * The type parameter T is used to supply the schema of your database. If you do not want to 46 | * use one set it to `any`. Using a schema provides type safety when accessing the database. 47 | */ 48 | database(): FirebaseDatabase { 49 | if (!this._database) { 50 | this._database = 51 | new FirebaseDatabase(this.zoneHelper.runInFirebase(() => this.nativeApp.database()), this) 52 | } 53 | return this._database 54 | } 55 | } -------------------------------------------------------------------------------- /packages/firebase-rxjs/src/auth.spec.ts: -------------------------------------------------------------------------------- 1 | import { asyncEvents } from '../testing/jasmine' 2 | /* tslint:disable:no-unused-variable */ 3 | import { FirebaseApp } from './app' 4 | import { FirebaseAuth } from './auth' 5 | 6 | let firebaseApp: FirebaseApp 7 | let auth: FirebaseAuth 8 | 9 | const userFixture = { 10 | email: 'user@foobar.foobar', 11 | password: 'onetwothree' 12 | } 13 | 14 | describe('Service: FirebaseAuth', () => { 15 | beforeEach(() => { 16 | firebaseApp = new FirebaseApp({ options: firebaseConfig }) 17 | auth = firebaseApp.auth() 18 | }); 19 | 20 | afterEach(done => { 21 | firebaseApp.delete().toPromise().then(done, done) 22 | }) 23 | 24 | it('should run observable of #user as event task', done => { 25 | let eventTaskScheduled = false 26 | let eventTaskCanceledScheduled = false 27 | Zone.current.fork({ 28 | name: 'user-observable-test', 29 | onScheduleTask: (parentZoneDelegate, currentZone, targetZone, task) => { 30 | if (task.source === 'firebaseRxJS.Observable.next') { 31 | eventTaskScheduled = true 32 | } 33 | return parentZoneDelegate.scheduleTask(targetZone, task) 34 | }, 35 | onCancelTask: (parentZoneDelegate, currentZone, targetZone, task) => { 36 | if (task.source === 'firebaseRxJS.Observable.next') { 37 | eventTaskCanceledScheduled = true 38 | } 39 | return parentZoneDelegate.cancelTask(targetZone, task) 40 | } 41 | }).run(() => { 42 | auth.signOut().toPromise().then(() => { 43 | auth.user.take(1).subscribe(user => { 44 | expect(user).toBeNull() 45 | setTimeout(() => { 46 | expect(eventTaskCanceledScheduled).toBeTruthy('eventTaskCanceledScheduled') 47 | done() 48 | }, 0) 49 | }) 50 | expect(eventTaskScheduled).toBeTruthy('eventTaskScheduled') 51 | }) 52 | }) 53 | }) 54 | 55 | it('should support observing authentication state', asyncEvents(async () => { 56 | let user 57 | 58 | await auth.signOut().toPromise() 59 | 60 | // Tests how state changes are observed 61 | auth.user.bufferCount(3).take(1).subscribe(events => { 62 | expect(events[0]).toBeNull() // Initial state 63 | expect(events[1].email).toBe(userFixture.email) // User signs in 64 | expect(events[2]).toBeNull() // User signs out 65 | }) 66 | 67 | // User is singed out so null should be replayed 68 | user = await auth.user.take(1).toPromise() 69 | expect(user).toBeNull() 70 | 71 | try { 72 | user = await auth.signInWithEmailAndPassword( 73 | userFixture.email, 74 | userFixture.password).toPromise() 75 | } catch (e) { 76 | user = await auth.createUserWithEmailAndPassword( 77 | userFixture.email, 78 | userFixture.password).toPromise() 79 | } 80 | 81 | // User is singed in so user should be replayed 82 | user = await auth.user.take(1).toPromise() 83 | expect(user.email).toBe(userFixture.email) 84 | 85 | await auth.signOut().toPromise() 86 | })) 87 | }); 88 | -------------------------------------------------------------------------------- /packages/firebase-rxjs/src/auth.ts: -------------------------------------------------------------------------------- 1 | import { auth, User } from 'firebase' 2 | import { Observable } from 'rxjs/Observable' 3 | import { map } from 'rxjs/operator/map' 4 | import { FirebaseApp } from './app' 5 | import { ActionCodeInfo, AuthCredential, AuthProvider } from './interfaces' 6 | import { NativeFirebaseAuth } from './native-firebase' 7 | import { FirebaseUser, FirebaseUserCredential } from './user' 8 | 9 | export class FirebaseAuth { 10 | 11 | /** 12 | * Observable which emits when authorization state of the user changes. 13 | */ 14 | get user(): Observable { 15 | return map.call( 16 | this.app.zoneHelper.createObservable( 17 | (observer) => this.fbAuth.onAuthStateChanged(observer) 18 | ), 19 | (user: firebase.User) => user ? new FirebaseUser(user, this.app) : null 20 | ) 21 | } 22 | 23 | constructor(private fbAuth: NativeFirebaseAuth, 24 | private app: FirebaseApp) {} 25 | 26 | /** 27 | * @param code 28 | * @returns {Observable} - Returns {@link ActionCodeError} if operation fails. 29 | */ 30 | applyActionCode(code: string): Observable { 31 | return this.app.zoneHelper.wrapPromise(() => this.fbAuth.applyActionCode(code)) 32 | } 33 | 34 | /** 35 | * @param code 36 | * @returns {Observable} - Returns {@link ActionCodeError} if operation fails. 37 | */ 38 | checkActionCode(code: string): Observable { 39 | return this.app.zoneHelper.wrapPromise(() => this.fbAuth.checkActionCode(code)) 40 | } 41 | 42 | /** 43 | * @param code 44 | * @param newPassword 45 | * @returns {Observable} - Returns {@link ConfirmPasswordResetError} if operation fails. 46 | */ 47 | confirmPasswordReset(code: string, newPassword: string): Observable { 48 | return this.app.zoneHelper.wrapPromise(() => 49 | this.fbAuth.confirmPasswordReset(code, newPassword)) 50 | } 51 | 52 | /** 53 | * 54 | * @param email 55 | * @param password 56 | * @returns {Observable} - Returns {@link CreateUserWithEmailAndPasswordError} if 57 | * operation fails. 58 | */ 59 | createUserWithEmailAndPassword(email: string, password: string): Observable { 60 | return map.call( 61 | this.app.zoneHelper.wrapPromise(() => 62 | this.fbAuth.createUserWithEmailAndPassword(email, password)), 63 | (user: User) => new FirebaseUser(user, this.app) 64 | ) 65 | } 66 | 67 | /** 68 | * 69 | * @param email 70 | * @returns {Observable} - Returns {@link FetchProvidersForEmailError} if operation 71 | * fails. 72 | */ 73 | fetchProvidersForEmail(email: string): Observable { 74 | return this.app.zoneHelper.wrapPromise(() => this.fbAuth.fetchProvidersForEmail(email)) 75 | } 76 | 77 | /** 78 | * @returns {Observable} - Returns {@link GetRedirectResultError} if 79 | * operation fails. 80 | */ 81 | getRedirectResult(): Observable { 82 | return map.call( 83 | this.app.zoneHelper.wrapPromise(() => this.fbAuth.getRedirectResult()), 84 | (cred: auth.UserCredential) => new FirebaseUserCredential(cred, this.app) 85 | ); 86 | } 87 | 88 | /** 89 | * @param email 90 | * @returns {Observable} - Returns {@link SendPasswordResetEmailError} if operation fails. 91 | */ 92 | sendPasswordResetEmail(email: string): Observable { 93 | return this.app.zoneHelper.wrapPromise(() => this.fbAuth.sendPasswordResetEmail(email)) 94 | } 95 | 96 | /** 97 | * 98 | * @returns {Observable} - Returns {@link SignInAnonymouslyError} if operation 99 | * fails. 100 | */ 101 | signInAnonymously(): Observable { 102 | return map.call( 103 | this.app.zoneHelper.wrapPromise(() => this.fbAuth.signInAnonymously()), 104 | (user: User) => new FirebaseUser(user, this.app) 105 | ); 106 | } 107 | 108 | /** 109 | * @param credential 110 | * @returns {Observable} - Returns {@link SignInWithCredentialError} if operation 111 | * fails. 112 | */ 113 | signInWithCredential(credential: AuthCredential): Observable { 114 | return map.call( 115 | this.app.zoneHelper.wrapPromise(() => this.fbAuth.signInWithCredential(credential)), 116 | (user: User) => new FirebaseUser(user, this.app) 117 | ); 118 | } 119 | 120 | /** 121 | * @param token 122 | * @returns {Observable} - Returns {@link SignInWithCustomTokenError} if operation 123 | * fails. 124 | */ 125 | signInWithCustomToken(token: string): Observable { 126 | return map.call( 127 | this.app.zoneHelper.wrapPromise(() => this.fbAuth.signInWithCustomToken(token)), 128 | (user: User) => new FirebaseUser(user, this.app) 129 | ); 130 | } 131 | 132 | /** 133 | * @param email 134 | * @param password 135 | * @returns {Observable} - Returns {@link SignInWithEmailAndPasswordError} if 136 | * operation fails. 137 | */ 138 | signInWithEmailAndPassword(email: string, password: string): Observable { 139 | return map.call( 140 | this.app.zoneHelper.wrapPromise(() => 141 | this.fbAuth.signInWithEmailAndPassword(email, password)), 142 | (user: User) => new FirebaseUser(user, this.app) 143 | ) 144 | } 145 | 146 | /** 147 | * @param provider 148 | * @returns {Observable} - Returns {@link SignInWithPopupError} if operation fails. 149 | */ 150 | signInWithPopup(provider: AuthProvider): Observable { 151 | return map.call( 152 | this.app.zoneHelper.wrapPromise(() => this.fbAuth.signInWithPopup(provider)), 153 | (cred: auth.UserCredential) => new FirebaseUserCredential(cred, this.app) 154 | ); 155 | } 156 | 157 | /** 158 | * @param provider 159 | * @returns {Observable} - Returns {@link SignInWithRedirectError} if operation 160 | * fails. 161 | */ 162 | signInWithRedirect(provider: AuthProvider): Observable { 163 | return map.call( 164 | this.app.zoneHelper.wrapPromise(() => this.fbAuth.signInWithRedirect(provider)), 165 | (cred: auth.UserCredential) => new FirebaseUserCredential(cred, this.app) 166 | ); 167 | } 168 | 169 | signOut(): Observable { 170 | return this.app.zoneHelper.wrapPromise(() => this.fbAuth.signOut()) 171 | } 172 | 173 | /** 174 | * 175 | * @param code 176 | * @returns {Observable} - Returns {@link VerifyPasswordResetCodeError} if operation 177 | * fails. 178 | */ 179 | verifyPasswordResetCode(code: string): Observable { 180 | return this.app.zoneHelper.wrapPromise(() => this.fbAuth.verifyPasswordResetCode(code)) 181 | } 182 | } 183 | -------------------------------------------------------------------------------- /packages/firebase-rxjs/src/data-snapshot-observable.ts: -------------------------------------------------------------------------------- 1 | import { database } from 'firebase' 2 | import { Observable } from 'rxjs/Observable' 3 | import { map } from 'rxjs/operator/map' 4 | import { mergeMap } from 'rxjs/operator/mergeMap' 5 | import { toArray } from 'rxjs/operator/toArray' 6 | import { DataSnapshot, ExportedSnapshot, Priority } from './interfaces' 7 | 8 | export function makeDataSnapshotObservable(observable: Observable>): DataSnapshotObservable { 9 | return new DataSnapshotObservable(subscriber => { 10 | const sub = observable.subscribe(subscriber) 11 | return () => sub.unsubscribe() 12 | }) 13 | } 14 | 15 | export class DataSnapshotObservable extends Observable> { 16 | 17 | exists(): Observable { 18 | return map.call(this, (snapshot: DataSnapshot) => snapshot.exists()); 19 | } 20 | 21 | children(): Observable> { 22 | return map.call(this, 23 | (snapshot: DataSnapshot) => new DataSnapshotObservable(sub => { 24 | snapshot.forEach(childSnapshot => { 25 | sub.next(childSnapshot); 26 | return false 27 | }) 28 | sub.complete() 29 | })) 30 | } 31 | 32 | /** 33 | * This operator takes the result of .val() for all children of the snapshot and emits 34 | * them as an array. 35 | * Contents of source snapshot: 36 | * ``` 37 | * { 38 | * childA: { prop: 'Hello' }, 39 | * childB: { prop: 'World!' }, 40 | * } 41 | * ``` 42 | * Result of operator: 43 | * ``` 44 | * [ 45 | * { prop: 'Hello' }, 46 | * { prop: 'World!' }, 47 | * ] 48 | * ``` 49 | * @returns {Observable} 50 | */ 51 | toValArray(): Observable { 52 | return mergeMap.call(this.children(), 53 | (children: DataSnapshotObservable) => toArray.call(children.val())) 54 | } 55 | 56 | values(): Observable { 57 | return this.toValArray(); 58 | } 59 | 60 | keys(): Observable { 61 | return mergeMap.call(this.children(), 62 | (children: DataSnapshotObservable) => toArray.call(children.key())) 63 | } 64 | 65 | list(): Observable<{ val: T[keyof T], key: string }[]> { 66 | return mergeMap.call(this.children(), 67 | (children: DataSnapshotObservable) => toArray.call(children.entry())) 68 | } 69 | 70 | entry(): Observable<{ val: T, key: string | null }> { 71 | return map.call(this, 72 | (snapshot: DataSnapshot) => ({ val: snapshot.val(), key: snapshot.key })) 73 | } 74 | 75 | key(): Observable { 76 | return map.call(this, (snapshot: DataSnapshot) => snapshot.key) 77 | } 78 | 79 | /** 80 | * When listening to events such as {@link Event.ChildMoved} the snapshot includes 81 | * the key of the child before this snapshots one. This operator maps to this key. 82 | * @returns {Observable} 83 | */ 84 | prevKey(): Observable { 85 | return map.call(this, (snapshot: DataSnapshot) => snapshot.prevKey) 86 | } 87 | 88 | val(): Observable { 89 | return map.call(this, (snapshot: DataSnapshot) => snapshot.val()) 90 | } 91 | 92 | getPriority(): Observable { 93 | return map.call(this, (snapshot: DataSnapshot) => snapshot.getPriority()) 94 | } 95 | 96 | exportVal(): Observable> { 97 | return map.call(this, (snapshot: DataSnapshot) => snapshot.exportVal()) 98 | } 99 | 100 | hasChild(path: keyof T): Observable { 101 | return map.call(this, (snapshot: DataSnapshot) => snapshot.hasChild(path)) 102 | } 103 | 104 | hasChildren(): Observable { 105 | return map.call(this, (snapshot: DataSnapshot) => snapshot.hasChildren()) 106 | } 107 | 108 | numChildren(): Observable { 109 | return map.call(this, (snapshot: DataSnapshot) => snapshot.numChildren()) 110 | } 111 | 112 | child

(path: P): DataSnapshotObservable { 113 | return new DataSnapshotObservable(sub => { 114 | const subscription = map.call(this, 115 | (snapshot: DataSnapshot) => snapshot.child(path)) 116 | .subscribe(sub) 117 | 118 | return () => subscription.unsubscribe() 119 | }) 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /packages/firebase-rxjs/src/database.spec.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable:no-unused-variable */ 2 | import { Observable } from 'rxjs' 3 | import 'rxjs' 4 | import { asyncEvents } from '../testing/jasmine' 5 | import { FirebaseApp } from './app' 6 | import { DataSnapshotObservable } from './data-snapshot-observable' 7 | import { FirebaseDatabase } from './database' 8 | 9 | interface DBSchema { 10 | parent: { 11 | child: string 12 | }, 13 | addedChild?: string 14 | list: { 15 | [key: string]: { 16 | c: string 17 | } 18 | } 19 | } 20 | 21 | let dbFixture: DBSchema = { 22 | parent: { 23 | child: 'childValue' 24 | }, 25 | list: { 26 | c: { c: 'c' }, 27 | a: { c: 'a' }, 28 | d: { c: 'd' }, 29 | b: { c: 'b' }, 30 | } 31 | } 32 | 33 | let firebaseApp: FirebaseApp 34 | let db: FirebaseDatabase 35 | 36 | describe('Service: FirebaseDatabase', () => { 37 | 38 | beforeAll(() => { 39 | firebaseApp = new FirebaseApp({ options: firebaseConfig }) 40 | db = firebaseApp.database() 41 | }); 42 | 43 | afterAll(asyncEvents(() => { 44 | firebaseApp.delete().subscribe() 45 | })) 46 | 47 | beforeEach(asyncEvents(() => { 48 | db.ref().setWithPriority(dbFixture, 42).subscribe() 49 | })) 50 | 51 | it('should set node', asyncEvents(() => { 52 | const ref = db.ref().child('addedChild') 53 | 54 | ref.set('bar') 55 | .mergeMapTo(ref.onceValue().val()) 56 | .subscribe(val => { 57 | expect(val).toBe('bar') 58 | }) 59 | })) 60 | 61 | it('should wrap callbacks to stay in current zone', asyncEvents(() => { 62 | const zone = Zone.current 63 | db.ref().child('parent') 64 | .onceValue() 65 | .subscribe(() => { 66 | expect(Zone.current).toBe(zone) 67 | }) 68 | })) 69 | 70 | it('should update node', asyncEvents(() => { 71 | const ref = db.ref().child('parent') 72 | ref.update({ child: 'newValue' }) 73 | .mergeMapTo(ref.onceValue().val()) 74 | .subscribe(node => expect(node).toEqual({ child: 'newValue' })) 75 | })) 76 | 77 | it('push node', asyncEvents(() => { 78 | const parent = db.ref().child('list') 79 | const newNode = { c: 'c' } 80 | 81 | parent.push(newNode) 82 | .mergeMap(child => child.onceValue().val()) 83 | .subscribe(node => expect(node).toEqual(newNode)) 84 | })) 85 | 86 | it('listen to updates', asyncEvents(() => { 87 | const node = db.ref().child('parent').child('child') 88 | 89 | node.onValue().val().bufferCount(2).take(1).subscribe(values => { 90 | expect(values).toEqual(['a', 'b']) 91 | }) 92 | 93 | Observable.concat(node.set('a'), node.set('b')).subscribe() 94 | })) 95 | 96 | it('orderByChild', asyncEvents(() => { 97 | const node = db.ref().child('list') 98 | 99 | node.orderByChild('c') 100 | .onceValue() 101 | .toValArray() 102 | .subscribe(children => expect(children).toEqual([ 103 | { c: 'a' }, 104 | { c: 'b' }, 105 | { c: 'c' }, 106 | { c: 'd' } 107 | ])) 108 | })) 109 | 110 | describe('DataSnapshotObservable', () => { 111 | let snapshotObsFixt: DataSnapshotObservable 112 | 113 | beforeEach(() => snapshotObsFixt = db.ref().onceValue()) 114 | 115 | it('.values()', asyncEvents(() => { 116 | db.ref().child('parent').onceValue().values().subscribe(values => { 117 | expect(values).toEqual(['childValue']) 118 | }) 119 | })) 120 | 121 | it('.keys()', asyncEvents(() => { 122 | snapshotObsFixt.keys().subscribe(keys => { 123 | expect(keys).toEqual(['list', 'parent']) 124 | }) 125 | })) 126 | 127 | it('.list()', asyncEvents(() => { 128 | db.ref().child('parent').onceValue().list().subscribe(entries => { 129 | expect(entries).toEqual([{ key: 'child', val: 'childValue' }]) 130 | }) 131 | })) 132 | 133 | it('.entry()', asyncEvents(() => { 134 | snapshotObsFixt.entry().subscribe(entry => { 135 | expect(entry).toEqual({ key: null, val: dbFixture }) 136 | }) 137 | snapshotObsFixt.child('parent').entry().subscribe(entry => { 138 | expect(entry).toEqual({ key: 'parent', val: dbFixture.parent }) 139 | }) 140 | })) 141 | 142 | it('.key()', asyncEvents(() => { 143 | snapshotObsFixt.child('parent').key().subscribe(entry => { 144 | expect(entry).toEqual('parent') 145 | }) 146 | })) 147 | 148 | it('.prevKey()', asyncEvents(() => { 149 | const initialKeys = Object.keys(dbFixture.list) 150 | db.ref().child('list').onChildAdded().prevKey().bufferCount(initialKeys.length).take(1) 151 | .subscribe(prevKey => expect(prevKey).toEqual([null, 'a', 'b', 'c'])); 152 | })) 153 | 154 | it('.exportVal()', asyncEvents(() => { 155 | snapshotObsFixt.exportVal() 156 | .subscribe(val => expect(val).toEqual(Object.assign({ '.priority': 42 }, dbFixture))); 157 | })) 158 | 159 | it('.exists()', asyncEvents(() => { 160 | snapshotObsFixt.exists() 161 | .subscribe(exists => expect(exists).toBeTruthy()); 162 | })) 163 | 164 | it('.getPriority()', asyncEvents(() => { 165 | snapshotObsFixt.getPriority() 166 | .subscribe(priority => expect(priority).toBe(42)); 167 | })) 168 | 169 | it('.hasChildren()', asyncEvents(() => { 170 | snapshotObsFixt.hasChildren() 171 | .subscribe(hasChildren => expect(hasChildren).toBeTruthy()); 172 | })) 173 | 174 | it('.hasChild()', asyncEvents(() => { 175 | snapshotObsFixt.hasChild('parent') 176 | .subscribe(hasChild => expect(hasChild).toBeTruthy()); 177 | })) 178 | 179 | it('.numChildren()', asyncEvents(() => { 180 | snapshotObsFixt.numChildren() 181 | .subscribe(numChildren => expect(numChildren).toBe(Object.keys(dbFixture).length)); 182 | })) 183 | }) 184 | 185 | it('transaction', asyncEvents(() => { 186 | db.ref().child('parent').transaction(parent => { 187 | // TODO investigate why parent is null 188 | // expect(parent).toBe(dbFixture.parent) 189 | return { child: 'newValue' } 190 | }).switchMapTo(db.ref().child('parent').onceValue().val()) 191 | .subscribe(parent => expect(parent.child).toBe('newValue')) 192 | })) 193 | }) 194 | -------------------------------------------------------------------------------- /packages/firebase-rxjs/src/database.ts: -------------------------------------------------------------------------------- 1 | import { database } from 'firebase' 2 | import { Observable } from 'rxjs/Observable' 3 | import { of } from 'rxjs/observable/of' 4 | import { map } from 'rxjs/operator/map' 5 | import { mapTo } from 'rxjs/operator/mapTo' 6 | import { Subscriber } from 'rxjs/Subscriber' 7 | import { FirebaseApp } from './app' 8 | import { DataSnapshotObservable, makeDataSnapshotObservable } from './data-snapshot-observable' 9 | import { 10 | DataSnapshot, 11 | EventType, 12 | NativeDatabaseRef, 13 | Priority, 14 | Query, 15 | TransactionResult 16 | } from './interfaces' 17 | import { NativeFirebaseDatabase } from './native-firebase' 18 | 19 | /** 20 | * Enum of event types. 21 | */ 22 | export class Event { 23 | static Value: EventType = 'value' 24 | static ChildAdded: EventType = 'child_added' 25 | static ChildChanged: EventType = 'child_changed' 26 | static ChildRemoved: EventType = 'child_removed' 27 | static ChildMoved: EventType = 'child_moved' 28 | } 29 | 30 | export class FirebaseQuery { 31 | private query: Query 32 | protected wrappedRef: FirebaseDatabaseRef 33 | 34 | get ref(): FirebaseDatabaseRef { 35 | return this.wrappedRef 36 | } 37 | 38 | constructor(protected _ref: NativeDatabaseRef, protected app: FirebaseApp) {} 39 | 40 | orderByChild(child: keyof T[keyof T]): FirebaseQuery { 41 | this._call('orderByChild', child) 42 | return this 43 | } 44 | 45 | orderByKey(): FirebaseQuery { 46 | this._call('orderByKey') 47 | return this 48 | } 49 | 50 | orderByPriority(): FirebaseQuery { 51 | this._call('orderByPriority') 52 | return this 53 | } 54 | 55 | orderByValue(): FirebaseQuery { 56 | this._call('orderByValue') 57 | return this 58 | } 59 | 60 | startAt(value: number | string | boolean | null, key?: keyof T[keyof T]): FirebaseQuery { 61 | this._call('startAt', value, key) 62 | return this 63 | } 64 | 65 | endAt(value: number | string | boolean | null, key?: keyof T[keyof T]): FirebaseQuery { 66 | this._call('endAt', value, key) 67 | return this 68 | } 69 | 70 | equalTo(value: number | string | boolean | null, key?: keyof T[keyof T]): FirebaseQuery { 71 | this._call('equalTo', value, key) 72 | return this 73 | } 74 | 75 | limitToFirst(limit: number): FirebaseQuery { 76 | this._call('limitToFirst', limit) 77 | return this 78 | } 79 | 80 | limitToLast(limit: number): FirebaseQuery { 81 | this._call('limitToLast', limit) 82 | return this 83 | } 84 | 85 | once(event: 'value'): DataSnapshotObservable 86 | once(event: 'child_added'): DataSnapshotObservable 87 | once(event: 'child_changed'): DataSnapshotObservable 88 | once(event: 'child_moved'): DataSnapshotObservable 89 | once(event: 'child_removed'): DataSnapshotObservable 90 | once(event: EventType): DataSnapshotObservable { 91 | return makeDataSnapshotObservable(this._once(event)) 92 | } 93 | 94 | onceValue(): DataSnapshotObservable { 95 | return this.once('value') 96 | } 97 | 98 | onceChildAdded(): DataSnapshotObservable { 99 | return this.once('child_added') 100 | } 101 | 102 | onceChildChanged(): DataSnapshotObservable { 103 | return this.once('child_changed') 104 | } 105 | 106 | onceChildMoved(): DataSnapshotObservable { 107 | return this.once('child_moved') 108 | } 109 | 110 | onceChildRemoved(): DataSnapshotObservable { 111 | return this.once('child_removed') 112 | } 113 | 114 | on(event: 'value'): DataSnapshotObservable 115 | on(event: 'child_added'): DataSnapshotObservable 116 | on(event: 'child_changed'): DataSnapshotObservable 117 | on(event: 'child_moved'): DataSnapshotObservable 118 | on(event: 'child_removed'): DataSnapshotObservable 119 | on(event: EventType): DataSnapshotObservable { 120 | return makeDataSnapshotObservable(this._on(event as any)) 121 | } 122 | 123 | onValue(): DataSnapshotObservable { 124 | return this.on('value') 125 | } 126 | 127 | onChildAdded(): DataSnapshotObservable { 128 | return this.on('child_added') 129 | } 130 | 131 | onChildChanged(): DataSnapshotObservable { 132 | return this.on('child_changed') 133 | } 134 | 135 | onChildMoved(): DataSnapshotObservable { 136 | return this.on('child_moved') 137 | } 138 | 139 | onChildRemoved(): DataSnapshotObservable { 140 | return this.on('child_removed') 141 | } 142 | 143 | isEqual(query: FirebaseQuery): boolean { 144 | return this.getQueryOrRef().isEqual(query.getQueryOrRef()) 145 | } 146 | 147 | private _once(event: string): Observable> { 148 | return map.call( 149 | this.app.zoneHelper.wrapPromise(() => this.getQueryOrRef().once(event)), 150 | (nativeSnapshot: any) => this.makeDataSnapshot(nativeSnapshot) 151 | ) 152 | } 153 | 154 | private _on(event: string): Observable> { 155 | return this.app.zoneHelper.createObservable(sub => { 156 | const cb = this.getQueryOrRef().on( 157 | event, this.getEventHandler(sub), 158 | (err: any) => sub.error(err) 159 | ) 160 | 161 | return () => this.getQueryOrRef().off(event, cb) 162 | }) 163 | } 164 | 165 | protected makeDataSnapshot(snapshot: any, prevKey?: string) { 166 | if (typeof prevKey !== 'undefined') { 167 | snapshot.prevKey = prevKey 168 | } 169 | Object.defineProperty(snapshot, 'ref', { 170 | get: () => this 171 | }) 172 | return snapshot 173 | } 174 | 175 | private getEventHandler(sub: Subscriber, complete?: boolean) { 176 | return (snapshot: any, prevKey: any) => { 177 | sub.next(this.makeDataSnapshot(snapshot, prevKey)) 178 | if (complete) { 179 | sub.complete() 180 | } 181 | } 182 | } 183 | 184 | private getQueryOrRef() { 185 | if (this.query) { 186 | return this.query 187 | } 188 | return this._ref 189 | } 190 | 191 | private _call(fnName: string, ...args: any[]) { 192 | this.app.zoneHelper.runInFirebase(() => { 193 | if (this.query) { 194 | this.query = (this.query as any)[fnName](...args) 195 | } 196 | else { 197 | this.query = (this._ref as any)[fnName](...args) 198 | } 199 | }) 200 | } 201 | } 202 | 203 | export class FirebaseDatabaseRef extends FirebaseQuery { 204 | 205 | get key(): string | null { 206 | return this._ref.key 207 | } 208 | 209 | constructor(public parent: FirebaseDatabaseRef | null, 210 | ref: NativeDatabaseRef, 211 | app: FirebaseApp) { 212 | super(ref, app) 213 | 214 | this.wrappedRef = this 215 | } 216 | 217 | child

(path: P): FirebaseDatabaseRef { 218 | return new FirebaseDatabaseRef(this, this._ref.child(path), this.app) 219 | } 220 | 221 | set(value: T): Observable { 222 | return this.app.zoneHelper.wrapPromise(() => this._ref.set(value)) 223 | } 224 | 225 | setPriority(priority: Priority): Observable { 226 | // There seems to be a bug with the typing for #setPriority(priority, onComplete): Promise 227 | // The firebase library, in every other case, declares the onComplete function optional since a 228 | // Promise is returned as well. 229 | return this.app.zoneHelper.wrapPromise(() => (this._ref as any).setPriority(priority)) 230 | } 231 | 232 | setWithPriority(newVal: T, priority: Priority): Observable { 233 | return this.app.zoneHelper.wrapPromise(() => this._ref.setWithPriority(newVal, priority)) 234 | } 235 | 236 | push

(value?: P): Observable> { 237 | const pushRef = this._ref.push(value) 238 | const ref = new FirebaseDatabaseRef

(this, pushRef, this.app) 239 | 240 | // Only if a value to push was given, use ref as promise, since otherwise 241 | // pushRef.then will be undefined 242 | if (value) { 243 | return mapTo.call(this.app.zoneHelper.wrapPromise>(() => pushRef), ref) 244 | } 245 | return of(ref) 246 | } 247 | 248 | update(value: T): Observable { 249 | return this.app.zoneHelper.wrapPromise(() => this._ref.update(value)) 250 | } 251 | 252 | remove(): Observable { 253 | return this.app.zoneHelper.wrapPromise(() => this._ref.remove()) 254 | } 255 | 256 | transaction(transactionHandler: (node: T | null) => T | null | never, 257 | applyLocally?: boolean): Observable> { 258 | if (Zone) { 259 | transactionHandler = this.app.zoneHelper.wrap(transactionHandler, 'firebaseRxJS.transaction') 260 | } 261 | return this.app.zoneHelper.wrapPromise>( 262 | () => new Promise((resolve, reject) => this._ref.transaction( 263 | transactionHandler, 264 | (err, committed, snapshot: any) => { 265 | return err ? reject(err) : resolve({ 266 | committed, 267 | snapshot: this.makeDataSnapshot(snapshot) 268 | }) 269 | }, 270 | applyLocally 271 | )) 272 | ) 273 | } 274 | } 275 | 276 | /** 277 | * A special object with information about the connection between client and server which can be 278 | * accessed by using `db.ref('.info')`. 279 | */ 280 | export class InfoSchema { 281 | /** 282 | * Whether or not the client is connected to the server. 283 | */ 284 | connected: boolean 285 | /** 286 | * The estimated offset of time in milliseconds between client and server. 287 | */ 288 | serverTimeOffset: number 289 | } 290 | 291 | export class FirebaseDatabase { 292 | 293 | /** 294 | * A collection of special constants which can be used when writing data. Their values will be 295 | * substituted on the server with server generated values. 296 | * E.g {@link FirebaseDatabase.ServerValue.TIMESTAMP} will be substituted for the server time 297 | * when committing a write. 298 | */ 299 | static ServerValue = database.ServerValue 300 | 301 | constructor(private db: NativeFirebaseDatabase, private app: FirebaseApp) { } 302 | 303 | /** 304 | * Get a {@link FirebaseDatabaseRef} to a location in the database. 305 | * 306 | * @howToUse 307 | * If you have defined a database schema you should use {@link FirebaseDatabase.ref} without 308 | * specifying a path in the database. At least not without giving a type parameter for the data 309 | * at that location. When using a schema you get the benefit of correct typing when using 310 | * {@link FirebaseDatabaseRef.child}. The TypeScript compiler can infer from the path segments 311 | * given to {@link FirebaseDatabaseRef.child} whether the path segment is valid at this 312 | * location in the database and what the type of the data is that will be returned when 313 | * fetching it. 314 | */ 315 | ref(): FirebaseDatabaseRef 316 | ref(path: '.info'): FirebaseDatabaseRef 317 | ref(path: string): FirebaseDatabaseRef 318 | ref(path: string): FirebaseDatabaseRef 319 | ref(path?: string): FirebaseDatabaseRef { 320 | return new FirebaseDatabaseRef(null, this.db.ref(path), this.app) 321 | } 322 | } 323 | -------------------------------------------------------------------------------- /packages/firebase-rxjs/src/interfaces.ts: -------------------------------------------------------------------------------- 1 | import * as firebase from 'firebase' 2 | import { database } from 'firebase' 3 | import { FirebaseDatabaseRef } from './database' 4 | import { FirebaseError } from './native-firebase' 5 | import AuthCredential = firebase.auth.AuthCredential 6 | import { auth } from 'firebase' 7 | 8 | /* 9 | * App Interfaces 10 | */ 11 | 12 | export interface FirebaseAppConfig { 13 | /** 14 | * Name of the app internally used by firebase. If non is given one will be generated. 15 | */ 16 | name?: string 17 | /** 18 | * Firebase App configuration. 19 | */ 20 | options: { 21 | apiKey: string 22 | authDomain?: string 23 | databaseURL?: string 24 | storageBucket?: string 25 | messagingSenderId?: string 26 | } 27 | } 28 | 29 | export interface Extras { 30 | firebaseZone?: any 31 | } 32 | 33 | /* 34 | * Database Interfaces 35 | */ 36 | 37 | export type Priority = number | string | null 38 | 39 | export interface PriorityField { 40 | '.priority'?: Priority // TODO define Priority type 41 | } 42 | 43 | export type ExportedSnapshot = { 44 | [P in keyof T]: ExportedSnapshot 45 | } & PriorityField 46 | 47 | // Implements firebase.database.DataSnapshot but with some changes which TypeScript can't express. 48 | export interface DataSnapshot { 49 | child

(path: P): DataSnapshot; 50 | exists(): boolean; 51 | exportVal(): ExportedSnapshot; 52 | forEach(action: (a: DataSnapshot) => boolean): boolean; 53 | getPriority(): Priority; 54 | hasChild(path: keyof T): boolean; 55 | hasChildren(): boolean; 56 | key: string | null; 57 | numChildren(): number; 58 | ref: FirebaseDatabaseRef; 59 | toJSON(): T | null; 60 | val(): T | null; 61 | 62 | prevKey?: string; 63 | } 64 | 65 | export type NativeDatabaseRef = database.Reference 66 | export type Query = database.Query 67 | 68 | /** 69 | * Events which can be listened for. 70 | */ 71 | export type EventType = 72 | 'value' 73 | | 'child_added' 74 | | 'child_changed' 75 | | 'child_removed' 76 | | 'child_moved' 77 | 78 | export interface TransactionResult { 79 | committed: boolean, 80 | snapshot: DataSnapshot | null 81 | } 82 | 83 | /* 84 | * Auth Interfaces 85 | */ 86 | 87 | /** 88 | * General error codes which may occur with every operation. 89 | */ 90 | export type AuthErrorCodeType = 91 | 'auth/app-deleted' 92 | | 'auth/app-not-authorized' 93 | | 'auth/argument-error' 94 | | 'auth/invalid-api-key' 95 | | 'auth/invalid-user-token' 96 | | 'auth/network-request-failed' 97 | | 'auth/operation-not-allowed' 98 | | 'auth/requires-recent-login' 99 | | 'auth/too-many-requests' 100 | | 'auth/unauthorized-domain' 101 | | 'auth/user-disabled' 102 | | 'auth/user-token-expired' 103 | | 'auth/web-storage-unsupported' 104 | 105 | export interface AuthError extends FirebaseError { 106 | code: AuthErrorCodeType | string 107 | email?: string 108 | credential?: AuthCredential 109 | } 110 | 111 | export interface ActionCodeError extends AuthError { 112 | code: AuthErrorCodeType 113 | | 'auth/expired-action-code' 114 | | 'auth/invalid-action-code' 115 | | 'auth/user-disabled' 116 | | 'auth/user-not-found' 117 | } 118 | 119 | /** 120 | * Error codes which can occur when calling {@link FirebaseAuth.confirmPasswordReset} 121 | */ 122 | export interface ConfirmPasswordResetError extends AuthError { 123 | code: AuthErrorCodeType 124 | | 'auth/expired-action-code' 125 | | 'auth/invalid-action-code' 126 | | 'auth/user-disabled' 127 | | 'auth/user-not-found' 128 | | 'auth/weak-password' 129 | } 130 | 131 | /** 132 | * Error codes which can occur when calling {@link FirebaseAuth.createUserWithEmailAndPassword} 133 | */ 134 | export interface CreateUserWithEmailAndPasswordError extends AuthError { 135 | code: AuthErrorCodeType 136 | | 'auth/email-already-in-use' 137 | | 'auth/invalid-email' 138 | | 'auth/operation-not-allowed' 139 | | 'auth/weak-password' 140 | } 141 | 142 | /** 143 | * Error codes which can occur when calling {@link FirebaseAuth.fetchProvidersForEmail} 144 | */ 145 | export interface FetchProvidersForEmailError extends AuthError { 146 | code: AuthErrorCodeType 147 | | 'auth/invalid-email' 148 | } 149 | 150 | /** 151 | * Error codes which can occur when calling {@link FirebaseAuth.getRedirectResult} 152 | */ 153 | export interface GetRedirectResultError extends AuthError { 154 | code: AuthErrorCodeType 155 | | 'auth/invalid-email' 156 | | 'auth/user-not-found' 157 | } 158 | 159 | /** 160 | * Error codes which can occur when calling {@link FirebaseAuth.sendPasswordResetEmail} 161 | */ 162 | export interface SendPasswordResetEmailError extends AuthError { 163 | code: AuthErrorCodeType 164 | | 'auth/invalid-email' 165 | | 'auth/user-not-found' 166 | } 167 | 168 | /** 169 | * Error codes which can occur when calling {@link FirebaseAuth.signInAnonymously} 170 | */ 171 | export interface SignInAnonymouslyError extends AuthError { 172 | code: AuthErrorCodeType 173 | | 'auth/operation-not-allowed' 174 | } 175 | 176 | /** 177 | * Error codes which can occur when calling {@link FirebaseAuth.signInWithCredential} 178 | */ 179 | export interface SignInWithCredentialError extends AuthError { 180 | code: AuthErrorCodeType 181 | | 'auth/account-exists-with-different-credential' 182 | | 'auth/invalid-credential' 183 | | 'auth/operation-not-allowed' 184 | | 'auth/user-disabled' 185 | | 'auth/user-not-found' 186 | | 'auth/wrong-password' 187 | } 188 | 189 | /** 190 | * Error codes which can occur when calling {@link FirebaseAuth.signInWithCustomToken} 191 | */ 192 | export interface SignInWithCustomTokenError extends AuthError { 193 | code: AuthErrorCodeType 194 | | 'auth/custom-token-mismatch' 195 | | 'auth/invalid-custom-token' 196 | } 197 | 198 | /** 199 | * Error codes which can occur when calling {@link FirebaseAuth.signInWithEmailAndPassword} 200 | */ 201 | export interface SignInWithEmailAndPasswordError extends AuthError { 202 | code: AuthErrorCodeType 203 | | 'auth/invalid-email' 204 | | 'auth/user-disabled' 205 | | 'auth/user-not-found' 206 | | 'auth/wrong-password' 207 | } 208 | 209 | /** 210 | * Error codes which can occur when calling {@link FirebaseAuth.signInWithPopup} 211 | */ 212 | export interface SignInWithPopupError extends AuthError { 213 | code: AuthErrorCodeType 214 | | 'auth/account-exists-with-different-credential' 215 | | 'auth/auth-domain-config-required' 216 | | 'auth/cancelled-popup-request' 217 | | 'auth/operation-not-allowed' 218 | | 'auth/operation-not-supported-in-this-environment' 219 | | 'auth/popup-blocked' 220 | | 'auth/popup-closed-by-user' 221 | | 'auth/unauthorized-domain' 222 | } 223 | 224 | /** 225 | * Error codes which can occur when calling {@link FirebaseAuth.signInWithRedirect} 226 | */ 227 | export interface SignInWithRedirectError extends AuthError { 228 | code: AuthErrorCodeType 229 | | 'auth/auth-domain-config-required' 230 | | 'auth/operation-not-supported-in-this-environment' 231 | | 'auth/unauthorized-domain' 232 | } 233 | 234 | /** 235 | * Error codes which can occur when calling {@link FirebaseAuth.verifyPasswordResetCode} 236 | */ 237 | export interface VerifyPasswordResetCodeError extends AuthError { 238 | code: AuthErrorCodeType 239 | | 'auth/expired-action-code' 240 | | 'auth/invalid-action-code' 241 | | 'auth/user-disabled' 242 | | 'auth/user-not-found' 243 | } 244 | 245 | export interface ActionCodeInfo { 246 | email: string 247 | } 248 | 249 | export type AuthProvider = auth.AuthProvider 250 | export type AuthCredential = auth.AuthCredential 251 | 252 | export class GoogleAuthProvider extends auth.GoogleAuthProvider {} 253 | export class FacebookAuthProvider extends auth.FacebookAuthProvider {} 254 | export class GithubAuthProvider extends auth.GithubAuthProvider {} 255 | export class EmailAuthProvider extends auth.EmailAuthProvider {} 256 | export class TwitterAuthProvider extends auth.TwitterAuthProvider {} 257 | 258 | /* 259 | * User Interfaces 260 | */ 261 | export interface DeleteUserError extends FirebaseError { 262 | code: AuthErrorCodeType 263 | | 'auth/requires-recent-login' 264 | } 265 | 266 | export interface LinkUserError extends FirebaseError { 267 | code: AuthErrorCodeType 268 | | 'auth/provider-already-linked' 269 | | 'auth/invalid-credential' 270 | | 'auth/credential-already-in-use' 271 | | 'auth/email-already-in-use' 272 | | 'auth/operation-not-allowed' 273 | | 'auth/invalid-email' 274 | | 'auth/wrong-password' 275 | } 276 | 277 | export interface LinkUserWithPopupError extends FirebaseError { 278 | code: AuthErrorCodeType 279 | | 'auth/auth-domain-config-required' 280 | | 'auth/cancelled-popup-request' 281 | | 'auth/credential-already-in-use' 282 | | 'auth/email-already-in-use' 283 | | 'auth/operation-not-allowed' 284 | | 'auth/popup-blocked' 285 | | 'auth/operation-not-supported-in-this-environment' 286 | | 'auth/popup-closed-by-user' 287 | | 'auth/provider-already-linked' 288 | | 'auth/unauthorized-domain' 289 | } 290 | 291 | export interface LinkUserWithRedirectError extends FirebaseError { 292 | code: AuthErrorCodeType 293 | | 'auth/auth-domain-config-required' 294 | | 'auth/operation-not-supported-in-this-environment' 295 | | 'auth/provider-already-linked' 296 | | 'auth/unauthorized-domain' 297 | } 298 | 299 | export interface ReauthenticateError extends FirebaseError { 300 | code: AuthErrorCodeType 301 | | 'auth/user-mismatch' 302 | | 'auth/user-not-found' 303 | | 'auth/invalid-credential' 304 | | 'auth/invalid-email' 305 | | 'auth/wrong-password' 306 | } 307 | 308 | export interface UpdateEmailError extends FirebaseError { 309 | code: AuthErrorCodeType 310 | | 'auth/invalid-email' 311 | | 'auth/email-already-in-use' 312 | | 'auth/requires-recent-login' 313 | } 314 | 315 | export interface UpdatePasswordError extends FirebaseError { 316 | code: AuthErrorCodeType 317 | | 'auth/weak-password' 318 | | 'auth/requires-recent-login' 319 | } 320 | 321 | export type UserCredential = auth.UserCredential; 322 | -------------------------------------------------------------------------------- /packages/firebase-rxjs/src/native-firebase.ts: -------------------------------------------------------------------------------- 1 | import { app, auth, database } from 'firebase' 2 | 3 | export abstract class NativeFirebaseApp implements app.App { 4 | name: string; 5 | options: Object; 6 | 7 | abstract auth(): firebase.auth.Auth; 8 | 9 | abstract database(): firebase.database.Database; 10 | 11 | abstract delete(): firebase.Promise; 12 | 13 | abstract storage(): firebase.storage.Storage; 14 | 15 | abstract messaging(): firebase.messaging.Messaging; 16 | } 17 | 18 | export abstract class NativeFirebaseAuth implements auth.Auth { 19 | app: firebase.app.App; 20 | 21 | abstract currentUser: firebase.User | null; 22 | 23 | abstract applyActionCode(code: string): firebase.Promise; 24 | 25 | abstract checkActionCode(code: string): firebase.Promise; 26 | 27 | abstract confirmPasswordReset(code: string, newPassword: string): firebase.Promise; 28 | 29 | abstract createCustomToken(uid: string, developerClaims?: Object | null): string; 30 | 31 | abstract createUserWithEmailAndPassword(email: string, password: string): firebase.Promise; 32 | 33 | abstract fetchProvidersForEmail(email: string): firebase.Promise; 34 | 35 | abstract getRedirectResult(): firebase.Promise; 36 | 37 | abstract onAuthStateChanged(nextOrObserver: Object, opt_error?: (a: firebase.auth.Error) => any, 38 | opt_completed?: () => any): () => any; 39 | 40 | abstract sendPasswordResetEmail(email: string): firebase.Promise; 41 | 42 | abstract signInAnonymously(): firebase.Promise; 43 | 44 | abstract signInWithCredential(credential: firebase.auth.AuthCredential): firebase.Promise; 45 | 46 | abstract signInWithCustomToken(token: string): firebase.Promise; 47 | 48 | abstract signInWithEmailAndPassword(email: string, password: string): firebase.Promise; 49 | 50 | abstract signInWithPopup(provider: firebase.auth.AuthProvider): firebase.Promise; 51 | 52 | abstract signInWithRedirect(provider: firebase.auth.AuthProvider): firebase.Promise; 53 | 54 | abstract signOut(): firebase.Promise; 55 | 56 | abstract verifyIdToken(idToken: string): firebase.Promise; 57 | 58 | abstract verifyPasswordResetCode(code: string): firebase.Promise; 59 | } 60 | 61 | export abstract class NativeFirebaseDatabase implements database.Database { 62 | app: firebase.app.App; 63 | 64 | abstract goOffline(): any; 65 | 66 | abstract goOnline(): any; 67 | 68 | abstract ref(path?: string): firebase.database.Reference; 69 | 70 | abstract refFromURL(url: string): firebase.database.Reference; 71 | } 72 | 73 | export interface FirebaseError extends Error { 74 | code: string 75 | message: string 76 | name: string 77 | stack: string 78 | } 79 | -------------------------------------------------------------------------------- /packages/firebase-rxjs/src/user.spec.ts: -------------------------------------------------------------------------------- 1 | import { async } from '../testing/jasmine' 2 | import { FirebaseApp } from './app' 3 | import { FirebaseAuth } from './auth' 4 | import { FirebaseUser } from './user' 5 | 6 | describe('FirebaseUser', () => { 7 | 8 | describe('Password & Email', () => { 9 | const userCreds = { email: randomEmail(), password: 'password' }; 10 | const profile = { displayName: 'Bob', photoURL: 'photo://url' } 11 | let app: FirebaseApp; 12 | let auth: FirebaseAuth; 13 | let user: FirebaseUser; 14 | 15 | it('should sign up', async(async () => { 16 | app = new FirebaseApp({ options: firebaseConfig }); 17 | auth = app.auth(); 18 | 19 | user = await auth.createUserWithEmailAndPassword(userCreds.email, userCreds.password) 20 | .toPromise() 21 | })); 22 | 23 | it('should update profile', async(async () => { 24 | await user.updateProfile(profile).toPromise(); 25 | })); 26 | 27 | it('should forward User fields', () => { 28 | expect(user.isAnonymous).toBeFalsy(); 29 | expect(user.email).toEqual(userCreds.email); 30 | expect(user.displayName).toEqual(profile.displayName); 31 | expect(user.photoURL).toEqual(profile.photoURL); 32 | expect(user.emailVerified).toBe(false); 33 | expect(user.providerId).toBe('firebase'); 34 | expect(user.uid.length > 10).toBeTruthy(); 35 | expect(user.refreshToken).toBeDefined(); 36 | expect(user.providerData[0]!.uid).toEqual(user.email as string) 37 | }) 38 | 39 | it('should get token', async(async () => { 40 | const token = await user.getToken(true).toPromise(); 41 | expect(typeof token === 'string').toBeTruthy() 42 | })) 43 | 44 | // Only applicable for providers other than password. 45 | it('should reauthenticate', () => pending()) 46 | 47 | it('should link', () => pending()) 48 | it('should linkWithPopup', () => pending()) 49 | it('should linkWithRedirect', () => pending()) 50 | it('should unlink', () => pending()) 51 | 52 | it('should reload user profile', async(async () => { 53 | await user.reload().toPromise() 54 | })) 55 | 56 | it('should send email verification', async(async () => { 57 | await user.sendEmailVerification().toPromise() 58 | })) 59 | 60 | it('should update email', async(async () => { 61 | userCreds.email = randomEmail(); 62 | await user.updateEmail(userCreds.email).toPromise(); 63 | expect(user.email).toBe(userCreds.email); 64 | })) 65 | 66 | it('should update password', async(async () => { 67 | userCreds.password = randomString(); 68 | await user.updatePassword(userCreds.password).toPromise(); 69 | user = await auth.signInWithEmailAndPassword(userCreds.email, userCreds.password).toPromise(); 70 | expect(user).toBeDefined(); 71 | })) 72 | 73 | it('should delete user', async(async () => { 74 | await user.delete().toPromise(); 75 | })); 76 | }); 77 | }); 78 | 79 | 80 | function randomString() { 81 | return Math.random().toString(36).substring(7); 82 | } 83 | 84 | function randomEmail() { 85 | return `${randomString()}@yopmail.com`; 86 | } -------------------------------------------------------------------------------- /packages/firebase-rxjs/src/user.ts: -------------------------------------------------------------------------------- 1 | import { auth, User, UserInfo } from 'firebase' 2 | import { Observable } from 'rxjs/Observable' 3 | import { map } from 'rxjs/operator/map' 4 | import { FirebaseApp } from './app' 5 | import { AuthCredential, UserCredential } from './interfaces' 6 | 7 | 8 | export class FirebaseUserCredential { 9 | credential?: AuthCredential; 10 | user?: FirebaseUser; 11 | 12 | constructor(cred: UserCredential, app: FirebaseApp) { 13 | this.credential = cred.credential || undefined; 14 | this.user = cred.user ? new FirebaseUser(cred.user, app) : undefined; 15 | } 16 | } 17 | 18 | export class FirebaseUser { 19 | 20 | get displayName(): string | null { 21 | return this.user.displayName 22 | } 23 | 24 | get email(): string | null { 25 | return this.user.email 26 | } 27 | 28 | get emailVerified(): boolean { 29 | return this.user.emailVerified; 30 | } 31 | 32 | get isAnonymous(): boolean { 33 | return this.user.isAnonymous; 34 | } 35 | 36 | get photoURL(): string | null { 37 | return this.user.photoURL; 38 | } 39 | 40 | get providerData(): (UserInfo | null)[] { 41 | return this.user.providerData; 42 | } 43 | 44 | get providerId(): string { 45 | return this.user.providerId; 46 | } 47 | 48 | get refreshToken(): string { 49 | return this.user.refreshToken; 50 | } 51 | 52 | get uid(): string { 53 | return this.user.uid 54 | } 55 | 56 | constructor(private user: User, private app: FirebaseApp) {} 57 | 58 | /** 59 | * @returns {Observable} - Returns {@link DeleteUserError} if operation fails. 60 | */ 61 | delete(): Observable { 62 | return this.app.zoneHelper.wrapPromise(() => this.user.delete()); 63 | } 64 | 65 | getToken(forceRefresh?: boolean): Observable { 66 | return this.app.zoneHelper.wrapPromise(() => this.user.getToken(forceRefresh)); 67 | } 68 | 69 | /** 70 | * @returns {Observable} - Returns {@link LinkUserError} if operation fails. 71 | */ 72 | link(credential: AuthCredential): Observable { 73 | return map.call( 74 | this.app.zoneHelper.wrapPromise(() => this.user.link(credential)), 75 | (user: User) => new FirebaseUser(user, this.app) 76 | ); 77 | } 78 | 79 | /** 80 | * @returns {Observable} - Returns {@link LinkUserWithPopupError} if 81 | * operation fails. 82 | */ 83 | linkWithPopup(provider: auth.AuthProvider): Observable { 84 | return map.call( 85 | this.app.zoneHelper.wrapPromise(() => this.user.linkWithPopup(provider)), 86 | (cred: UserCredential) => new FirebaseUserCredential(cred, this.app) 87 | ); 88 | } 89 | 90 | /** 91 | * @returns {Observable} - Returns {@link LinkUserWithRedirectError} if 92 | * operation fails. 93 | */ 94 | linkWithRedirect(provider: auth.AuthProvider): Observable { 95 | return map.call( 96 | this.app.zoneHelper.wrapPromise(() => this.user.linkWithRedirect(provider)), 97 | (cred: UserCredential) => new FirebaseUserCredential(cred, this.app) 98 | ); 99 | } 100 | 101 | /** 102 | * @returns {Observable} - Returns {@link ReauthenticateError} if operation 103 | * fails. 104 | */ 105 | reauthenticate(credential: AuthCredential): Observable { 106 | return this.app.zoneHelper.wrapPromise(() => this.user.reauthenticate(credential)); 107 | } 108 | 109 | reload(): Observable { 110 | return this.app.zoneHelper.wrapPromise(() => this.user.reload()); 111 | } 112 | 113 | sendEmailVerification(): Observable { 114 | return this.app.zoneHelper.wrapPromise(() => this.user.sendEmailVerification()); 115 | } 116 | 117 | unlink(providerId: string): Observable { 118 | return map.call( 119 | this.app.zoneHelper.wrapPromise(() => this.user.unlink(providerId)), 120 | (user: User) => new FirebaseUser(user, this.app) 121 | ); 122 | } 123 | 124 | /** 125 | * @returns {Observable} - Returns {@link UpdateEmailError} if operation 126 | * fails. 127 | */ 128 | updateEmail(newEmail: string): Observable { 129 | return this.app.zoneHelper.wrapPromise(() => this.user.updateEmail(newEmail)); 130 | } 131 | 132 | /** 133 | * @returns {Observable} - Returns {@link UpdatePasswordError} if operation 134 | * fails. 135 | */ 136 | updatePassword(newPassword: string): Observable { 137 | return this.app.zoneHelper.wrapPromise(() => this.user.updatePassword(newPassword)); 138 | } 139 | 140 | updateProfile(profile: { displayName?: string, photoURL?: string }): Observable { 141 | return this.app.zoneHelper.wrapPromise(() => this.user.updateProfile(profile as any)); 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /packages/firebase-rxjs/src/zone-helper.spec.no-zone.ts: -------------------------------------------------------------------------------- 1 | import { ZoneHelper } from './zone-helper' 2 | 3 | describe('ZoneHelper: no zone.js', () => { 4 | let zoneHelper: ZoneHelper 5 | 6 | beforeEach(() => { 7 | zoneHelper = new ZoneHelper() 8 | }) 9 | 10 | it('zone.js should not be loaded', () => { 11 | expect(typeof Zone).toBe('undefined') 12 | }) 13 | 14 | it('should not setup firebaseZone', () => { 15 | expect((zoneHelper as any).firebaseZone).toBeUndefined() 16 | }) 17 | }) -------------------------------------------------------------------------------- /packages/firebase-rxjs/src/zone-helper.ts: -------------------------------------------------------------------------------- 1 | import { Observable } from 'rxjs/Observable' 2 | import { fromPromise } from 'rxjs/observable/fromPromise' 3 | import { Operator } from 'rxjs/Operator' 4 | import { Subscriber } from 'rxjs/Subscriber' 5 | import { TeardownLogic } from 'rxjs/Subscription' 6 | 7 | export class ZoneHelper { 8 | 9 | constructor(private firebaseZone?: Zone) { 10 | if (!firebaseZone) { 11 | if (typeof Zone !== 'undefined') { 12 | this.firebaseZone = Zone.root.fork({ name: 'firebase' }) 13 | } 14 | } 15 | } 16 | 17 | wrap(callback: F, source: string): F { 18 | if (this.firebaseZone) { 19 | return this.firebaseZone.wrap(callback, source) 20 | } 21 | return callback 22 | } 23 | 24 | runInFirebase(fn: () => T): T { 25 | if (this.firebaseZone) { 26 | return this.firebaseZone.run(fn) 27 | } 28 | return fn() 29 | } 30 | 31 | wrapSubscribe(fn: T): T { 32 | if (this.firebaseZone) { 33 | return this.firebaseZone.wrap(fn, 'firebaseRxJS.Observable.subscribe') 34 | } 35 | return fn 36 | } 37 | 38 | wrapPromise(promiseFactory: () => firebase.Promise): Observable { 39 | if (typeof Zone === 'undefined') { 40 | return fromPromise(this.runInFirebase(promiseFactory) as Promise) 41 | } 42 | 43 | return new Observable(subscriber => { 44 | Zone.current.scheduleMacroTask('firebaseRxJS.Promise', 45 | (err: any, res: any) => { 46 | if (err) { 47 | subscriber.error(err) 48 | } else { 49 | subscriber.next(res) 50 | subscriber.complete() 51 | } 52 | }, {}, 53 | (task: Task) => { 54 | const promise = this.runInFirebase(promiseFactory) as Promise 55 | promise.then(task.invoke.bind(task, null), task.invoke.bind(task)) 56 | }, 57 | (task: Task) => {} 58 | ) 59 | }) 60 | } 61 | 62 | createObservable(subscribe: (subscriber: Subscriber) => TeardownLogic): Observable { 63 | const obs = new Observable(this.wrapSubscribe(subscribe)) 64 | 65 | if (typeof Zone === 'undefined') { 66 | return obs 67 | } 68 | 69 | return obs.lift(new EventTaskOperator()) 70 | } 71 | } 72 | 73 | class EventTaskOperator implements Operator { 74 | 75 | call(subscriber: Subscriber, source: any): TeardownLogic { 76 | return source.subscribe(new EventTaskSubscriber(subscriber, Zone.current)) 77 | } 78 | } 79 | 80 | class EventTaskSubscriber extends Subscriber { 81 | nextTask: EventTask 82 | 83 | constructor(destination: Subscriber, private zone: Zone) { 84 | super(destination) 85 | 86 | this.nextTask = this.zone.scheduleEventTask( 87 | 'firebaseRxJS.Observable.next', 88 | (val: T) => this.destination.next!(val), 89 | {}, 90 | () => {}, 91 | () => {}, 92 | ) 93 | 94 | this.add(() => this.zone.cancelTask(this.nextTask)) 95 | } 96 | 97 | protected _next(value: T): void { 98 | const { nextTask } = this 99 | this.zone.run(nextTask.invoke, nextTask, [value]); 100 | } 101 | 102 | protected _error(err: any): void { 103 | const { destination } = this 104 | this.zone.scheduleMicroTask('firebaseRxJS.Observable.error', 105 | destination.error!.bind(destination, err)) 106 | } 107 | 108 | protected _complete(): void { 109 | const { destination } = this 110 | this.zone.scheduleMicroTask('firebaseRxJS.Observable.complete', 111 | destination.complete!.bind(destination)) 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /packages/firebase-rxjs/testing/jasmine.ts: -------------------------------------------------------------------------------- 1 | import { asyncTestWrapper } from './testing' 2 | 3 | export function async(test: () => void, waitForEventTasks = false): (done: () => void) => void { 4 | return function (done) { 5 | asyncTestWrapper('jasmine', 6 | test, 7 | { 8 | failure(err) { 9 | fail(err); 10 | done() 11 | }, 12 | success: function () { 13 | done() 14 | } 15 | }, 16 | waitForEventTasks) 17 | } 18 | } 19 | 20 | export function asyncEvents(test: () => void): (done: () => void) => void { 21 | return async(test, true) 22 | } -------------------------------------------------------------------------------- /packages/firebase-rxjs/testing/log-spec.ts: -------------------------------------------------------------------------------- 1 | 2 | export class LogSpec implements ZoneSpec { 3 | indent = 0 4 | name = 'log-zone' 5 | 6 | log(msg: string) { 7 | console.log(`${' '.repeat(this.indent)}${msg}`) 8 | } 9 | 10 | onIntercept(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, delegate: Function, 11 | source: string) { 12 | this.log(`[onIntercept] ${source}`) 13 | return parentZoneDelegate.intercept(targetZone, delegate, source) 14 | } 15 | 16 | onInvoke(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, delegate: Function, 17 | applyThis: any, applyArgs: any[], source: string) { 18 | this.log(`[onInvoke]:before ${targetZone.name} ${applyArgs}`) 19 | this.indent++ 20 | const res = parentZoneDelegate.invoke(targetZone, delegate, applyThis, applyArgs, source) 21 | this.indent-- 22 | this.log(`[onInvoke]:after ${targetZone.name}`) 23 | return res 24 | } 25 | 26 | onScheduleTask(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, task: Task) { 27 | this.log(`[onScheduleTask] ${task.source}`) 28 | return parentZoneDelegate.scheduleTask(targetZone, task) 29 | } 30 | 31 | onInvokeTask(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, task: Task, 32 | applyThis: any, applyArgs: any) { 33 | this.log(`[onInvokeTask]:before ${task.source} ${applyArgs}`) 34 | this.indent++ 35 | const res = parentZoneDelegate.invokeTask(targetZone, task, applyThis, applyArgs) 36 | this.indent-- 37 | this.log(`[onInvokeTask]:after ${task.source} ${applyArgs}`) 38 | return res 39 | } 40 | 41 | onHasTask(delegate: ZoneDelegate, current: Zone, target: Zone, hasTaskState: HasTaskState) { 42 | const { microTask, macroTask } = hasTaskState 43 | this.log(`[onHasTask] ${microTask ? 'microTask' : ''} ${macroTask ? 'macroTask' : ''}`) 44 | return delegate.hasTask(target, hasTaskState) 45 | } 46 | } 47 | 48 | export const logSpec = new LogSpec() -------------------------------------------------------------------------------- /packages/firebase-rxjs/testing/testing.ts: -------------------------------------------------------------------------------- 1 | export interface TestFrameworkCallbacks { 2 | success(): void 3 | failure(err?: any): void 4 | } 5 | 6 | export function asyncTestWrapper(zoneNamePostFix: string, 7 | test: () => any, 8 | callbacks: TestFrameworkCallbacks, 9 | waitForEventTasks: boolean) { 10 | let startZone = Zone.current 11 | 12 | const longStackTraceSpec = (Zone as any)['longStackTraceZoneSpec'] 13 | if (longStackTraceSpec) { 14 | startZone = startZone.fork(longStackTraceSpec) 15 | } 16 | 17 | startZone.fork(new AsyncTestZoneSpec(callbacks.success, 18 | callbacks.failure, 19 | zoneNamePostFix, 20 | waitForEventTasks)) 21 | .run(() => { 22 | const res = test() 23 | 24 | if (typeof res === 'object' && typeof (res as any).then === 'function') { 25 | const promise = res as Promise 26 | promise.then(callbacks.success, callbacks.failure) 27 | } 28 | }) 29 | } 30 | 31 | // Copied from zone.js/lib/zone-spec/async-test.ts and extended. 32 | class AsyncTestZoneSpec implements ZoneSpec { 33 | _finishCallback: Function; 34 | _failCallback: Function; 35 | _waitForEvents: boolean; 36 | _pendingMicroTasks: boolean = false; 37 | _pendingMacroTasks: boolean = false; 38 | _pendingEventTasks: boolean = false; 39 | _alreadyErrored: boolean = false; 40 | runZone = Zone.current; 41 | 42 | constructor(finishCallback: Function, 43 | failCallback: Function, 44 | namePrefix: string, 45 | waitForEvents: boolean) { 46 | this._finishCallback = finishCallback; 47 | this._failCallback = failCallback; 48 | this._waitForEvents = waitForEvents; 49 | this.name = 'asyncTestZone for ' + namePrefix; 50 | } 51 | 52 | _hasPendingTasks() { 53 | if (this._waitForEvents && this._pendingEventTasks) { 54 | return true 55 | } 56 | return this._pendingMicroTasks || this._pendingMacroTasks 57 | } 58 | 59 | _finishCallbackIfDone() { 60 | if (!this._hasPendingTasks()) { 61 | // We do this because we would like to catch unhandled rejected promises. 62 | this.runZone.run(() => { 63 | setTimeout(() => { 64 | if (!this._alreadyErrored && !this._hasPendingTasks()) { 65 | this._finishCallback(); 66 | } 67 | }, 0); 68 | }); 69 | } 70 | } 71 | 72 | // ZoneSpec implementation below. 73 | 74 | name: string; 75 | 76 | // Note - we need to use onInvoke at the moment to call finish when a test is 77 | // fully synchronous. TODO(juliemr): remove this when the logic for 78 | // onHasTask changes and it calls whenever the task queues are dirty. 79 | onInvoke(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, 80 | delegate: Function, 81 | applyThis: any, applyArgs: any[], source: string): any { 82 | try { 83 | return parentZoneDelegate.invoke(targetZone, delegate, applyThis, applyArgs, source); 84 | } finally { 85 | this._finishCallbackIfDone(); 86 | } 87 | } 88 | 89 | onHandleError(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, 90 | error: any): boolean { 91 | // Let the parent try to handle the error. 92 | const result = parentZoneDelegate.handleError(targetZone, error); 93 | if (result) { 94 | this._failCallback(error); 95 | this._alreadyErrored = true; 96 | } 97 | return false; 98 | } 99 | 100 | onHasTask(delegate: ZoneDelegate, current: Zone, target: Zone, hasTaskState: HasTaskState) { 101 | delegate.hasTask(target, hasTaskState); 102 | if (hasTaskState.change == 'microTask') { 103 | this._pendingMicroTasks = hasTaskState.microTask; 104 | this._finishCallbackIfDone(); 105 | } else if (hasTaskState.change == 'macroTask') { 106 | this._pendingMacroTasks = hasTaskState.macroTask; 107 | this._finishCallbackIfDone(); 108 | } else if (hasTaskState.change == 'eventTask') { 109 | this._pendingEventTasks = hasTaskState.eventTask; 110 | this._finishCallbackIfDone(); 111 | } 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /packages/firebase-rxjs/tsconfig.dist.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "rootDir": ".", 4 | "baseUrl": ".", 5 | "moduleResolution": "node", 6 | "emitDecoratorMetadata": true, 7 | "experimentalDecorators": true, 8 | "outDir": "../../dist/packages/firebase-rxjs", 9 | "paths": { 10 | "rxjs/*": [ 11 | "../../node_modules/rxjs/*" 12 | ], 13 | "firebase": [ 14 | "../../node_modules/firebase" 15 | ] 16 | }, 17 | "noImplicitAny": true, 18 | "strictNullChecks": true, 19 | "declaration": true, 20 | "stripInternal": true, 21 | "sourceMap": true, 22 | "inlineSources": true, 23 | "module": "es2015", 24 | "target": "es5", 25 | "lib": [ 26 | "dom", 27 | "es2015", 28 | "es2015.collection", 29 | "es2015.promise" 30 | ], 31 | "types": [] 32 | }, 33 | "files": [ 34 | "firebase-rxjs.ts", 35 | "../../node_modules/zone.js/dist/zone.js.d.ts" 36 | ], 37 | "angularCompilerOptions": { 38 | "strictMetadataEmit": true 39 | } 40 | } -------------------------------------------------------------------------------- /packages/tests.no-zone.ts: -------------------------------------------------------------------------------- 1 | import 'core-js' 2 | 3 | declare var __karma__: any; 4 | declare var require: any; 5 | 6 | __karma__.loaded = function () {} 7 | 8 | const context = require.context('./', true, /\/.+\/src\/.+\.spec\.no-zone\.ts$/) 9 | 10 | context.keys().map(context) 11 | 12 | __karma__.start() 13 | -------------------------------------------------------------------------------- /packages/tests.ts: -------------------------------------------------------------------------------- 1 | import 'core-js' 2 | 3 | import 'zone.js/dist/zone' 4 | import 'zone.js/dist/long-stack-trace-zone' 5 | import 'zone.js/dist/proxy' 6 | import 'zone.js/dist/fake-async-test' 7 | import 'zone.js/dist/sync-test' 8 | import 'zone.js/dist/async-test' 9 | import 'zone.js/dist/jasmine-patch' 10 | 11 | import { TestBed } from '@angular/core/testing' 12 | import { 13 | BrowserDynamicTestingModule, 14 | platformBrowserDynamicTesting 15 | } from '@angular/platform-browser-dynamic/testing' 16 | 17 | TestBed.initTestEnvironment( 18 | BrowserDynamicTestingModule, 19 | platformBrowserDynamicTesting() 20 | ) 21 | 22 | declare var __karma__: any; 23 | declare var require: any; 24 | 25 | __karma__.loaded = function () {} 26 | 27 | const context = require.context('./', true, /\/.+\/src\/.+\.spec\.ts$/) 28 | 29 | context.keys().map(context) 30 | 31 | __karma__.start() 32 | -------------------------------------------------------------------------------- /packages/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "traceResolution": true, 4 | "baseUrl": ".", 5 | "declaration": true, 6 | "experimentalDecorators": true, 7 | "emitDecoratorMetadata": true, 8 | "module": "commonjs", 9 | "moduleResolution": "node", 10 | "outDir": "../dist/all", 11 | "noImplicitAny": true, 12 | "noFallthroughCasesInSwitch": true, 13 | "paths": { 14 | "rxjs/*": [ 15 | "../node_modules/rxjs/*" 16 | ], 17 | "*": [ 18 | "./*" 19 | ] 20 | }, 21 | "rootDir": ".", 22 | "lib": [ 23 | "es6", 24 | "dom" 25 | ], 26 | "skipDefaultLibCheck": true, 27 | "skipLibCheck": true, 28 | "target": "es5", 29 | "types": [ 30 | "zone.js", 31 | "jasmine" 32 | ] 33 | } 34 | } -------------------------------------------------------------------------------- /packages/typings.d.ts: -------------------------------------------------------------------------------- 1 | declare const firebaseConfig: any 2 | -------------------------------------------------------------------------------- /scripts/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 6 | ROOT="$( cd "${DIR}/.." && pwd )" 7 | BIN=${ROOT}/node_modules/.bin 8 | PKGS=${ROOT}/packages 9 | PKGS_DIST=${ROOT}/dist/packages 10 | 11 | buildJS () { 12 | echo "Building js for $1" 13 | ${BIN}/ngc -p ${PKGS}/$1/tsconfig.dist.json 14 | ${BIN}/cpy README.md CHANGELOG.md ${PKGS}/$1/package.json dist/packages/$1 15 | } 16 | 17 | bundle() { 18 | echo "Bundling $1" 19 | ${BIN}/rollup -c ${PKGS}/$1/rollup.config.js 20 | } 21 | 22 | uglify () { 23 | echo "Uglifying $1" 24 | ${BIN}/uglifyjs -c \ 25 | -o ${PKGS_DIST}/$1/bundles/$1.umd.min.js \ 26 | --source-map ${PKGS_DIST}/$1/bundles/$1.umd.min.map.js \ 27 | ${PKGS_DIST}/$1/bundles/$1.umd.js 28 | } 29 | 30 | cleanDist () { 31 | echo "Cleaning dist folder" 32 | ${BIN}/rimraf ${PKGS_DIST} 33 | } 34 | 35 | cleanSrc () { 36 | echo "Cleaning src folders" 37 | ${BIN}/rimraf -rf "${PKGS}/*/node_modules" 38 | ${BIN}/rimraf -rf "${PKGS}/*/dist" 39 | ${BIN}/rimraf -rf "${PKGS}/**/*.{ngsummary.json,ngfactory.ts}" 40 | } 41 | 42 | buildPkg () { 43 | buildJS $1 44 | bundle $1 45 | uglify $1 46 | } 47 | 48 | build () { 49 | cleanDist 50 | buildPkg firebase-rxjs 51 | buildPkg firebase-rxjs-angular 52 | ${DIR}/version.js 53 | cleanSrc 54 | } 55 | 56 | docsPkg () { 57 | echo "Building docs for $1" 58 | local DOCS_DIR=${ROOT}/docs/$1 59 | rm -rf DOCS_DIR 60 | ${BIN}/typedoc --options typedoc.json -out ${DOCS_DIR} ${PKGS}/$1/$1.ts 61 | } 62 | 63 | docs () { 64 | docsPkg firebase-rxjs 65 | docsPkg firebase-rxjs-angular 66 | } 67 | 68 | "$@" 69 | -------------------------------------------------------------------------------- /scripts/e2e-test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 6 | 7 | cd ${DIR}/../testing/ng-project 8 | yarn 9 | npm run e2e 10 | # Make sure aot and uglification work 11 | npm run ng -- build --prod --env dev -------------------------------------------------------------------------------- /scripts/version.js: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/node 2 | 3 | const fs = require('fs'); 4 | const path = require('path'); 5 | const rootPkg = require('../package.json'); 6 | 7 | const placeholder = /<--VERION_PLACEHOLDER-->/g; 8 | 9 | function replaceVersion(packageName) { 10 | const pkgPath = path.resolve('./dist/packages', packageName, 'package.json'); 11 | const pkgStr = fs.readFileSync(pkgPath).toString(); 12 | const pkgStrReplaced = pkgStr.replace(placeholder, rootPkg.version); 13 | fs.writeFileSync(pkgPath, pkgStrReplaced); 14 | } 15 | 16 | replaceVersion('firebase-rxjs'); 17 | replaceVersion('firebase-rxjs-angular'); -------------------------------------------------------------------------------- /testing/karma.conf.common.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const path = require('path'); 3 | const fs = require('fs'); 4 | const webpack = require('webpack'); 5 | const {TsConfigPathsPlugin} = require('awesome-typescript-loader'); 6 | 7 | let firebaseConfig = process.env.FIREBASE_CONFIG || 8 | fs.readFileSync('./firebase.config.local.json', {encoding: 'utf8'}); 9 | 10 | if (firebaseConfig === '') { 11 | throw new Error('Failed to load Firebase config.') 12 | } 13 | 14 | const coverage = !!process.env['COVERAGE']; 15 | if (coverage) { 16 | console.log('Running tests with coverage!'); 17 | } 18 | 19 | const reporters = ['mocha', 'kjhtml']; 20 | 21 | if (coverage) { 22 | reporters.push('karma-remap-istanbul') 23 | } 24 | 25 | const rules = [{ 26 | test: /\.ts$/, 27 | loader: 'awesome-typescript-loader', 28 | exclude: /node_modules/, 29 | query: { 30 | configFileName: './packages/tsconfig.json' 31 | } 32 | }]; 33 | 34 | if (coverage) { 35 | rules.push({ 36 | enforce: 'post', 37 | test: /\.(ts|js)$/, 38 | loader: 'sourcemap-istanbul-instrumenter-loader', 39 | exclude: [ 40 | /\.(spec|e2e|bundle)\.ts$/, 41 | /node_modules/ 42 | ], 43 | query: {'force-sourcemap': true} 44 | }) 45 | } 46 | 47 | exports.getKarmaConfig = function ({karma, testBundle}) { 48 | return { 49 | basePath: path.resolve(__dirname, '..'), 50 | 51 | mime: { 52 | 'application/javascript': ['ts'] 53 | }, 54 | 55 | frameworks: ['jasmine'], 56 | 57 | files: [{pattern: testBundle, watched: false}], 58 | 59 | preprocessors: { 60 | [testBundle]: ['webpack'] 61 | }, 62 | 63 | reporters, 64 | 65 | remapIstanbulReporter: { 66 | reports: { 67 | html: 'coverage', 68 | lcovonly: 'coverage/lcov.info' 69 | } 70 | }, 71 | 72 | browsers: ['Chrome'], 73 | browserConsoleLogOptions: { 74 | level: "" 75 | }, 76 | colors: true, 77 | autoWatch: true, 78 | singleRun: false, 79 | logLevel: karma.LOG_INFO, 80 | 81 | webpack: { 82 | devtool: 'inline-source-map', 83 | 84 | resolve: { 85 | extensions: ['.ts', '.js'], 86 | modules: [ 87 | path.resolve(__dirname, '../node_modules'), 88 | path.resolve(__dirname, '../packages') 89 | ] 90 | }, 91 | 92 | module: { 93 | rules, 94 | }, 95 | 96 | plugins: [ 97 | new TsConfigPathsPlugin({tsconfig: path.resolve(__dirname, '../packages/tsconfig.json')}), 98 | new webpack.DefinePlugin({ 99 | firebaseConfig 100 | }), 101 | new webpack.SourceMapDevToolPlugin({ 102 | filename: null, // if no value is provided the sourcemap is inlined 103 | test: /\.(ts|js)($|\?)/i // process .js and .ts files only 104 | }) 105 | ] 106 | } 107 | } 108 | }; 109 | -------------------------------------------------------------------------------- /testing/karma.conf.no-zone.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const {getKarmaConfig} = require("./karma.conf.common"); 3 | 4 | module.exports = function (karma) { 5 | karma.set(getKarmaConfig({testBundle: './packages/tests.no-zone.ts', karma})) 6 | }; 7 | -------------------------------------------------------------------------------- /testing/ng-project/.angular-cli.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json", 3 | "project": { 4 | "name": "ng-project" 5 | }, 6 | "apps": [ 7 | { 8 | "root": "src", 9 | "outDir": "dist", 10 | "assets": [ 11 | "assets", 12 | "favicon.ico" 13 | ], 14 | "index": "index.html", 15 | "main": "main.ts", 16 | "polyfills": "polyfills.ts", 17 | "test": "test.ts", 18 | "tsconfig": "tsconfig.app.json", 19 | "testTsconfig": "tsconfig.spec.json", 20 | "prefix": "app", 21 | "styles": [ 22 | "styles.css" 23 | ], 24 | "scripts": [], 25 | "environmentSource": "environments/environment.ts", 26 | "environments": { 27 | "dev": "environments/environment.ts", 28 | "prod": "environments/environment.prod.ts" 29 | } 30 | } 31 | ], 32 | "e2e": { 33 | "protractor": { 34 | "config": "./protractor.conf.js" 35 | } 36 | }, 37 | "lint": [ 38 | { 39 | "project": "src/tsconfig.app.json" 40 | }, 41 | { 42 | "project": "src/tsconfig.spec.json" 43 | }, 44 | { 45 | "project": "e2e/tsconfig.e2e.json" 46 | } 47 | ], 48 | "test": { 49 | "karma": { 50 | "config": "./karma.conf.js" 51 | } 52 | }, 53 | "defaults": { 54 | "styleExt": "css", 55 | "component": {} 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /testing/ng-project/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | max_line_length = off 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /testing/ng-project/.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /tmp 6 | /out-tsc 7 | 8 | # dependencies 9 | /node_modules 10 | 11 | # IDEs and editors 12 | /.idea 13 | .project 14 | .classpath 15 | .c9/ 16 | *.launch 17 | .settings/ 18 | *.sublime-workspace 19 | 20 | # IDE - VSCode 21 | .vscode/* 22 | !.vscode/settings.json 23 | !.vscode/tasks.json 24 | !.vscode/launch.json 25 | !.vscode/extensions.json 26 | 27 | # misc 28 | /.sass-cache 29 | /connect.lock 30 | /coverage 31 | /libpeerconnection.log 32 | npm-debug.log 33 | testem.log 34 | /typings 35 | 36 | # e2e 37 | /e2e/*.js 38 | /e2e/*.map 39 | 40 | # System Files 41 | .DS_Store 42 | Thumbs.db 43 | -------------------------------------------------------------------------------- /testing/ng-project/README.md: -------------------------------------------------------------------------------- 1 | # NgProject 2 | 3 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 1.0.0-rc.4. 4 | 5 | ## Development server 6 | 7 | Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files. 8 | 9 | ## Code scaffolding 10 | 11 | Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive/pipe/service/class/module`. 12 | 13 | ## Build 14 | 15 | Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `-prod` flag for a production build. 16 | 17 | ## Running unit tests 18 | 19 | Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). 20 | 21 | ## Running end-to-end tests 22 | 23 | Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/). 24 | Before running the tests make sure you are serving the app via `ng serve`. 25 | 26 | ## Further help 27 | 28 | To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md). 29 | -------------------------------------------------------------------------------- /testing/ng-project/e2e/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { browser } from 'protractor' 2 | import { NgProjectPage } from './app.po' 3 | 4 | describe('ng-project App', () => { 5 | let page: NgProjectPage; 6 | 7 | beforeEach(() => { 8 | page = new NgProjectPage(); 9 | }); 10 | 11 | it('should display message saying app works', () => { 12 | page.navigateTo(); 13 | expect(page.getParagraphText()).toEqual('app works!'); 14 | browser.sleep(2000) 15 | expect(page.getParagraphText()).toEqual('with Firebase!') 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /testing/ng-project/e2e/app.po.ts: -------------------------------------------------------------------------------- 1 | import { browser, element, by } from 'protractor'; 2 | 3 | export class NgProjectPage { 4 | navigateTo() { 5 | return browser.get('/'); 6 | } 7 | 8 | getParagraphText() { 9 | return element(by.css('app-root h1')).getText(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /testing/ng-project/e2e/tsconfig.e2e.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/e2e", 5 | "module": "commonjs", 6 | "target": "es5", 7 | "types":[ 8 | "jasmine", 9 | "node" 10 | ] 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /testing/ng-project/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/0.13/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', '@angular/cli'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-chrome-launcher'), 11 | require('karma-jasmine-html-reporter'), 12 | require('karma-coverage-istanbul-reporter'), 13 | require('@angular/cli/plugins/karma') 14 | ], 15 | client:{ 16 | clearContext: false // leave Jasmine Spec Runner output visible in browser 17 | }, 18 | files: [ 19 | { pattern: './src/test.ts', watched: false } 20 | ], 21 | preprocessors: { 22 | './src/test.ts': ['@angular/cli'] 23 | }, 24 | mime: { 25 | 'text/x-typescript': ['ts','tsx'] 26 | }, 27 | coverageIstanbulReporter: { 28 | reports: [ 'html', 'lcovonly' ], 29 | fixWebpackSourcePaths: true 30 | }, 31 | angularCli: { 32 | environment: 'dev' 33 | }, 34 | reporters: config.angularCli && config.angularCli.codeCoverage 35 | ? ['progress', 'coverage-istanbul'] 36 | : ['progress', 'kjhtml'], 37 | port: 9876, 38 | colors: true, 39 | logLevel: config.LOG_INFO, 40 | autoWatch: true, 41 | browsers: ['Chrome'], 42 | singleRun: false 43 | }); 44 | }; 45 | -------------------------------------------------------------------------------- /testing/ng-project/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ng-project", 3 | "version": "0.0.0", 4 | "license": "MIT", 5 | "scripts": { 6 | "ng": "ng", 7 | "start": "ng serve", 8 | "build": "ng build", 9 | "test": "ng test", 10 | "lint": "ng lint", 11 | "e2e": "ng e2e" 12 | }, 13 | "private": true, 14 | "dependencies": { 15 | "@angular/common": ">=4.0.0-beta <5.0.0", 16 | "@angular/compiler": ">=4.0.0-beta <5.0.0", 17 | "@angular/core": ">=4.0.0-beta <5.0.0", 18 | "@angular/forms": ">=4.0.0-beta <5.0.0", 19 | "@angular/http": ">=4.0.0-beta <5.0.0", 20 | "@angular/platform-browser": ">=4.0.0-beta <5.0.0", 21 | "@angular/platform-browser-dynamic": ">=4.0.0-beta <5.0.0", 22 | "@angular/router": ">=4.0.0-beta <5.0.0", 23 | "core-js": "^2.4.1", 24 | "firebase-rxjs": "file:../../dist/packages/firebase-rxjs", 25 | "firebase-rxjs-angular": "file:../../dist/packages/firebase-rxjs-angular", 26 | "rxjs": "^5.1.0", 27 | "zone.js": "^0.8.4" 28 | }, 29 | "devDependencies": { 30 | "@angular/cli": "^1.0.0", 31 | "@angular/compiler-cli": ">=4.0.0-beta <5.0.0", 32 | "@types/jasmine": "2.5.45", 33 | "@types/node": "^7.0.12", 34 | "codelyzer": "^3.0.0-beta.4", 35 | "jasmine-core": "~2.5.2", 36 | "jasmine-spec-reporter": "~3.2.0", 37 | "karma": "^1.5.0", 38 | "karma-chrome-launcher": "~2.0.0", 39 | "karma-cli": "~1.0.1", 40 | "karma-coverage-istanbul-reporter": "^1.0.0", 41 | "karma-jasmine": "~1.1.0", 42 | "karma-jasmine-html-reporter": "^0.2.2", 43 | "protractor": "~5.1.0", 44 | "ts-node": "^3.0.2", 45 | "tslint": "~4.5.0", 46 | "typescript": "^2.2.2" 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /testing/ng-project/protractor.conf.js: -------------------------------------------------------------------------------- 1 | // Protractor configuration file, see link for more information 2 | // https://github.com/angular/protractor/blob/master/lib/config.ts 3 | 4 | const { SpecReporter } = require('jasmine-spec-reporter'); 5 | 6 | exports.config = { 7 | allScriptsTimeout: 11000, 8 | specs: [ 9 | './e2e/**/*.e2e-spec.ts' 10 | ], 11 | capabilities: { 12 | 'browserName': 'chrome' 13 | }, 14 | directConnect: true, 15 | baseUrl: 'http://localhost:4200/', 16 | framework: 'jasmine', 17 | jasmineNodeOpts: { 18 | showColors: true, 19 | defaultTimeoutInterval: 30000, 20 | print: function() {} 21 | }, 22 | beforeLaunch: function() { 23 | require('ts-node').register({ 24 | project: 'e2e/tsconfig.e2e.json' 25 | }); 26 | }, 27 | onPrepare() { 28 | jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /testing/ng-project/src/app/app.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blaugold/firebase-rxjs/cc0a0a0e92c43f8deb1030b222f0ee23b0494d54/testing/ng-project/src/app/app.component.css -------------------------------------------------------------------------------- /testing/ng-project/src/app/app.component.html: -------------------------------------------------------------------------------- 1 |

2 | {{title | async}} 3 |

4 | -------------------------------------------------------------------------------- /testing/ng-project/src/app/app.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, async } from '@angular/core/testing'; 2 | 3 | import { AppComponent } from './app.component'; 4 | 5 | describe('AppComponent', () => { 6 | beforeEach(async(() => { 7 | TestBed.configureTestingModule({ 8 | declarations: [ 9 | AppComponent 10 | ], 11 | }).compileComponents(); 12 | })); 13 | 14 | it('should create the app', async(() => { 15 | const fixture = TestBed.createComponent(AppComponent); 16 | const app = fixture.debugElement.componentInstance; 17 | expect(app).toBeTruthy(); 18 | })); 19 | 20 | it(`should have as title 'app works!'`, async(() => { 21 | const fixture = TestBed.createComponent(AppComponent); 22 | const app = fixture.debugElement.componentInstance; 23 | expect(app.title).toEqual('app works!'); 24 | })); 25 | 26 | it('should render title in a h1 tag', async(() => { 27 | const fixture = TestBed.createComponent(AppComponent); 28 | fixture.detectChanges(); 29 | const compiled = fixture.debugElement.nativeElement; 30 | expect(compiled.querySelector('h1').textContent).toContain('app works!'); 31 | })); 32 | }); 33 | -------------------------------------------------------------------------------- /testing/ng-project/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { FirebaseDatabase } from 'firebase-rxjs' 3 | import { Observable } from 'rxjs' 4 | 5 | interface DBSchema { 6 | title: string 7 | } 8 | 9 | @Component({ 10 | selector: 'app-root', 11 | templateUrl: './app.component.html', 12 | styleUrls: ['./app.component.css'] 13 | }) 14 | export class AppComponent implements OnInit { 15 | title: Observable; 16 | 17 | constructor(private db: FirebaseDatabase) {} 18 | 19 | ngOnInit(): void { 20 | const titleRef = this.db.ref().child('title') 21 | 22 | this.title = Observable.of('app works!') 23 | .merge(titleRef.set('with Firebase!') 24 | .switchMapTo(titleRef.onValue().val())) 25 | } 26 | } 27 | 28 | -------------------------------------------------------------------------------- /testing/ng-project/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core' 2 | import { FormsModule } from '@angular/forms' 3 | import { HttpModule } from '@angular/http' 4 | import { BrowserModule } from '@angular/platform-browser' 5 | import { FirebaseRxJSModule } from 'firebase-rxjs-angular' 6 | 7 | import { AppComponent } from './app.component' 8 | import { environment } from '../environments/environment' 9 | 10 | @NgModule({ 11 | declarations: [ 12 | AppComponent 13 | ], 14 | imports: [ 15 | BrowserModule, 16 | FormsModule, 17 | HttpModule, 18 | FirebaseRxJSModule.primaryApp({ 19 | options: environment.firebase 20 | }) 21 | ], 22 | providers: [], 23 | bootstrap: [AppComponent] 24 | }) 25 | export class AppModule { 26 | } 27 | -------------------------------------------------------------------------------- /testing/ng-project/src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blaugold/firebase-rxjs/cc0a0a0e92c43f8deb1030b222f0ee23b0494d54/testing/ng-project/src/assets/.gitkeep -------------------------------------------------------------------------------- /testing/ng-project/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /testing/ng-project/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // The file contents for the current environment will overwrite these during build. 2 | // The build system defaults to the dev environment which uses `environment.ts`, but if you do 3 | // `ng build --env=prod` then `environment.prod.ts` will be used instead. 4 | // The list of which env maps to which file can be found in `.angular-cli.json`. 5 | 6 | export const environment = { 7 | production: false, 8 | firebase: { 9 | "apiKey": "AIzaSyBd0enZJAJQOdbOSBfoYQUh67Lgc3ta550", 10 | "authDomain": "angular-firebase-tests-local.firebaseapp.com", 11 | "databaseURL": "https://angular-firebase-tests-local.firebaseio.com", 12 | "storageBucket": "angular-firebase-tests-local.appspot.com", 13 | "messagingSenderId": "452174369556" 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /testing/ng-project/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blaugold/firebase-rxjs/cc0a0a0e92c43f8deb1030b222f0ee23b0494d54/testing/ng-project/src/favicon.ico -------------------------------------------------------------------------------- /testing/ng-project/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NgProject 6 | 7 | 8 | 9 | 10 | 11 | 12 | Loading... 13 | 14 | 15 | -------------------------------------------------------------------------------- /testing/ng-project/src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic().bootstrapModule(AppModule); 12 | -------------------------------------------------------------------------------- /testing/ng-project/src/polyfills.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file includes polyfills needed by Angular and is loaded before the app. 3 | * You can add your own extra polyfills to this file. 4 | * 5 | * This file is divided into 2 sections: 6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. 7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main 8 | * file. 9 | * 10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that 11 | * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), 12 | * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. 13 | * 14 | * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html 15 | */ 16 | 17 | /*************************************************************************************************** 18 | * BROWSER POLYFILLS 19 | */ 20 | 21 | /** IE9, IE10 and IE11 requires all of the following polyfills. **/ 22 | // import 'core-js/es6/symbol'; 23 | // import 'core-js/es6/object'; 24 | // import 'core-js/es6/function'; 25 | // import 'core-js/es6/parse-int'; 26 | // import 'core-js/es6/parse-float'; 27 | // import 'core-js/es6/number'; 28 | // import 'core-js/es6/math'; 29 | // import 'core-js/es6/string'; 30 | // import 'core-js/es6/date'; 31 | // import 'core-js/es6/array'; 32 | // import 'core-js/es6/regexp'; 33 | // import 'core-js/es6/map'; 34 | // import 'core-js/es6/set'; 35 | 36 | /** IE10 and IE11 requires the following for NgClass support on SVG elements */ 37 | // import 'classlist.js'; // Run `npm install --save classlist.js`. 38 | 39 | /** IE10 and IE11 requires the following to support `@angular/animation`. */ 40 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`. 41 | 42 | 43 | /** Evergreen browsers require these. **/ 44 | import 'core-js/es6/reflect'; 45 | import 'core-js/es7/reflect'; 46 | 47 | 48 | /** ALL Firefox browsers require the following to support `@angular/animation`. **/ 49 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`. 50 | 51 | 52 | 53 | /*************************************************************************************************** 54 | * Zone JS is required by Angular itself. 55 | */ 56 | import 'zone.js/dist/zone'; // Included with Angular CLI. 57 | 58 | 59 | 60 | /*************************************************************************************************** 61 | * APPLICATION IMPORTS 62 | */ 63 | 64 | /** 65 | * Date, currency, decimal and percent pipes. 66 | * Needed for: All but Chrome, Firefox, Edge, IE11 and Safari 10 67 | */ 68 | // import 'intl'; // Run `npm install --save intl`. 69 | -------------------------------------------------------------------------------- /testing/ng-project/src/styles.css: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | -------------------------------------------------------------------------------- /testing/ng-project/src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'zone.js/dist/long-stack-trace-zone'; 4 | import 'zone.js/dist/proxy.js'; 5 | import 'zone.js/dist/sync-test'; 6 | import 'zone.js/dist/jasmine-patch'; 7 | import 'zone.js/dist/async-test'; 8 | import 'zone.js/dist/fake-async-test'; 9 | import { getTestBed } from '@angular/core/testing'; 10 | import { 11 | BrowserDynamicTestingModule, 12 | platformBrowserDynamicTesting 13 | } from '@angular/platform-browser-dynamic/testing'; 14 | 15 | // Unfortunately there's no typing for the `__karma__` variable. Just declare it as any. 16 | declare var __karma__: any; 17 | declare var require: any; 18 | 19 | // Prevent Karma from running prematurely. 20 | __karma__.loaded = function () {}; 21 | 22 | // First, initialize the Angular testing environment. 23 | getTestBed().initTestEnvironment( 24 | BrowserDynamicTestingModule, 25 | platformBrowserDynamicTesting() 26 | ); 27 | // Then we find all the tests. 28 | const context = require.context('./', true, /\.spec\.ts$/); 29 | // And load the modules. 30 | context.keys().map(context); 31 | // Finally, start Karma to run the tests. 32 | __karma__.start(); 33 | -------------------------------------------------------------------------------- /testing/ng-project/src/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/app", 5 | "module": "es2015", 6 | "baseUrl": "", 7 | "types": [] 8 | }, 9 | "exclude": [ 10 | "test.ts", 11 | "**/*.spec.ts" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /testing/ng-project/src/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/spec", 5 | "module": "commonjs", 6 | "target": "es5", 7 | "baseUrl": "", 8 | "types": [ 9 | "jasmine", 10 | "node" 11 | ] 12 | }, 13 | "files": [ 14 | "test.ts" 15 | ], 16 | "include": [ 17 | "**/*.spec.ts", 18 | "**/*.d.ts" 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /testing/ng-project/src/typings.d.ts: -------------------------------------------------------------------------------- 1 | /* SystemJS module definition */ 2 | declare var module: NodeModule; 3 | interface NodeModule { 4 | id: string; 5 | } 6 | -------------------------------------------------------------------------------- /testing/ng-project/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "outDir": "./dist/out-tsc", 5 | "baseUrl": "src", 6 | "sourceMap": true, 7 | "declaration": false, 8 | "moduleResolution": "node", 9 | "emitDecoratorMetadata": true, 10 | "experimentalDecorators": true, 11 | "target": "es5", 12 | "typeRoots": [ 13 | "node_modules/@types" 14 | ], 15 | "lib": [ 16 | "es2016", 17 | "dom" 18 | ] 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /testing/ng-project/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rulesDirectory": [ 3 | "node_modules/codelyzer" 4 | ], 5 | "rules": { 6 | "callable-types": true, 7 | "class-name": true, 8 | "comment-format": [ 9 | true, 10 | "check-space" 11 | ], 12 | "curly": true, 13 | "eofline": true, 14 | "forin": true, 15 | "import-blacklist": [true, "rxjs"], 16 | "import-spacing": true, 17 | "indent": [ 18 | true, 19 | "spaces" 20 | ], 21 | "interface-over-type-literal": true, 22 | "label-position": true, 23 | "max-line-length": [ 24 | true, 25 | 140 26 | ], 27 | "member-access": false, 28 | "member-ordering": [ 29 | true, 30 | "static-before-instance", 31 | "variables-before-functions" 32 | ], 33 | "no-arg": true, 34 | "no-bitwise": true, 35 | "no-console": [ 36 | true, 37 | "debug", 38 | "info", 39 | "time", 40 | "timeEnd", 41 | "trace" 42 | ], 43 | "no-construct": true, 44 | "no-debugger": true, 45 | "no-duplicate-variable": true, 46 | "no-empty": false, 47 | "no-empty-interface": true, 48 | "no-eval": true, 49 | "no-inferrable-types": [true, "ignore-params"], 50 | "no-shadowed-variable": true, 51 | "no-string-literal": false, 52 | "no-string-throw": true, 53 | "no-switch-case-fall-through": true, 54 | "no-trailing-whitespace": true, 55 | "no-unused-expression": true, 56 | "no-use-before-declare": true, 57 | "no-var-keyword": true, 58 | "object-literal-sort-keys": false, 59 | "one-line": [ 60 | true, 61 | "check-open-brace", 62 | "check-catch", 63 | "check-else", 64 | "check-whitespace" 65 | ], 66 | "prefer-const": true, 67 | "quotemark": [ 68 | true, 69 | "single" 70 | ], 71 | "radix": true, 72 | "semicolon": [ 73 | "always" 74 | ], 75 | "triple-equals": [ 76 | true, 77 | "allow-null-check" 78 | ], 79 | "typedef-whitespace": [ 80 | true, 81 | { 82 | "call-signature": "nospace", 83 | "index-signature": "nospace", 84 | "parameter": "nospace", 85 | "property-declaration": "nospace", 86 | "variable-declaration": "nospace" 87 | } 88 | ], 89 | "typeof-compare": true, 90 | "unified-signatures": true, 91 | "variable-name": false, 92 | "whitespace": [ 93 | true, 94 | "check-branch", 95 | "check-decl", 96 | "check-operator", 97 | "check-separator", 98 | "check-type" 99 | ], 100 | 101 | "directive-selector": [true, "attribute", "app", "camelCase"], 102 | "component-selector": [true, "element", "app", "kebab-case"], 103 | "use-input-property-decorator": true, 104 | "use-output-property-decorator": true, 105 | "use-host-property-decorator": true, 106 | "no-input-rename": true, 107 | "no-output-rename": true, 108 | "use-life-cycle-interface": true, 109 | "use-pipe-transform-interface": true, 110 | "component-class-suffix": true, 111 | "directive-class-suffix": true, 112 | "no-access-missing-member": true, 113 | "templates-use-public": true, 114 | "invoke-injectable": true 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /typedoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "mode": "file", 3 | "theme": "minimal", 4 | "ignoreCompilerErrors": true, 5 | "experimentalDecorators": true, 6 | "emitDecoratorMetadata": true, 7 | "target": "ES6", 8 | "moduleResolution": "node", 9 | "preserveConstEnums": true, 10 | "stripInternal": true, 11 | "suppressExcessPropertyErrors": true, 12 | "suppressImplicitAnyIndexErrors": true, 13 | "module": "ES6", 14 | "exclude": "**/*.spec.ts", 15 | "excludePrivate": true, 16 | "excludeExternals": false, 17 | "excludeNotExported": true, 18 | "pretty": true, 19 | "gaID": "UA-87346670-1", 20 | "lib": [ 21 | "es6" 22 | ], 23 | "files": [ 24 | "./node_modules/zone.js/dist/zone.js.d.ts" 25 | ] 26 | } --------------------------------------------------------------------------------