@angular/fire 17.0.1 → 17.1.0-canary.1302e3a

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/README.md +21 -24
  2. package/analytics/analytics.module.d.ts +2 -2
  3. package/app/app.module.d.ts +2 -2
  4. package/app/firebase.d.ts +2 -1
  5. package/app-check/app-check.module.d.ts +2 -2
  6. package/auth/auth.module.d.ts +2 -2
  7. package/database/database.module.d.ts +2 -2
  8. package/docs/compat/auth/getting-started.md +4 -4
  9. package/docs/compat/emulators/emulators.md +28 -2
  10. package/docs/compat/firestore/collections.md +1 -1
  11. package/docs/compat/firestore/querying-collections.md +2 -2
  12. package/docs/compat.md +1 -1
  13. package/docs/install-and-setup.md +1 -1
  14. package/docs/messaging.md +187 -9
  15. package/esm2022/analytics/analytics.module.mjs +24 -17
  16. package/esm2022/app/app.module.mjs +22 -16
  17. package/esm2022/app/firebase.mjs +3 -2
  18. package/esm2022/app-check/app-check.module.mjs +20 -18
  19. package/esm2022/auth/auth.module.mjs +20 -18
  20. package/esm2022/database/database.module.mjs +22 -20
  21. package/esm2022/firestore/firestore.module.mjs +22 -20
  22. package/esm2022/firestore/lite/lite.module.mjs +22 -20
  23. package/esm2022/functions/functions.module.mjs +22 -20
  24. package/esm2022/messaging/messaging.module.mjs +24 -17
  25. package/esm2022/performance/performance.module.mjs +20 -18
  26. package/esm2022/remote-config/remote-config.module.mjs +24 -17
  27. package/esm2022/storage/storage.module.mjs +22 -20
  28. package/esm2022/vertexai-preview/angular-fire-vertexai-preview.mjs +5 -0
  29. package/esm2022/vertexai-preview/firebase.mjs +7 -0
  30. package/esm2022/vertexai-preview/public_api.mjs +4 -0
  31. package/esm2022/vertexai-preview/vertexai.mjs +16 -0
  32. package/esm2022/vertexai-preview/vertexai.module.mjs +73 -0
  33. package/fesm2022/angular-fire-analytics.mjs +23 -16
  34. package/fesm2022/angular-fire-analytics.mjs.map +1 -1
  35. package/fesm2022/angular-fire-app-check.mjs +19 -17
  36. package/fesm2022/angular-fire-app-check.mjs.map +1 -1
  37. package/fesm2022/angular-fire-app.mjs +24 -17
  38. package/fesm2022/angular-fire-app.mjs.map +1 -1
  39. package/fesm2022/angular-fire-auth.mjs +19 -17
  40. package/fesm2022/angular-fire-auth.mjs.map +1 -1
  41. package/fesm2022/angular-fire-database.mjs +21 -19
  42. package/fesm2022/angular-fire-database.mjs.map +1 -1
  43. package/fesm2022/angular-fire-firestore-lite.mjs +21 -19
  44. package/fesm2022/angular-fire-firestore-lite.mjs.map +1 -1
  45. package/fesm2022/angular-fire-firestore.mjs +21 -19
  46. package/fesm2022/angular-fire-firestore.mjs.map +1 -1
  47. package/fesm2022/angular-fire-functions.mjs +21 -19
  48. package/fesm2022/angular-fire-functions.mjs.map +1 -1
  49. package/fesm2022/angular-fire-messaging.mjs +23 -16
  50. package/fesm2022/angular-fire-messaging.mjs.map +1 -1
  51. package/fesm2022/angular-fire-performance.mjs +19 -17
  52. package/fesm2022/angular-fire-performance.mjs.map +1 -1
  53. package/fesm2022/angular-fire-remote-config.mjs +23 -16
  54. package/fesm2022/angular-fire-remote-config.mjs.map +1 -1
  55. package/fesm2022/angular-fire-storage.mjs +21 -19
  56. package/fesm2022/angular-fire-storage.mjs.map +1 -1
  57. package/fesm2022/angular-fire-vertexai-preview.mjs +99 -0
  58. package/fesm2022/angular-fire-vertexai-preview.mjs.map +1 -0
  59. package/firestore/firestore.module.d.ts +2 -2
  60. package/firestore/lite/lite.module.d.ts +2 -2
  61. package/functions/functions.module.d.ts +2 -2
  62. package/messaging/messaging.module.d.ts +2 -2
  63. package/package.json +8 -2
  64. package/performance/performance.module.d.ts +2 -2
  65. package/remote-config/remote-config.module.d.ts +2 -2
  66. package/schematics/common.js +1 -26
  67. package/schematics/deploy/actions.js +7 -1
  68. package/schematics/interfaces.js +11 -11
  69. package/schematics/setup/index.js +7 -97
  70. package/schematics/setup/prompts.js +2 -91
  71. package/schematics/utils.js +27 -75
  72. package/storage/storage.module.d.ts +2 -2
  73. package/vertexai-preview/firebase.d.ts +4 -0
  74. package/vertexai-preview/index.d.ts +5 -0
  75. package/vertexai-preview/package.json +3 -0
  76. package/vertexai-preview/public_api.d.ts +3 -0
  77. package/vertexai-preview/vertexai.d.ts +13 -0
  78. package/vertexai-preview/vertexai.module.d.ts +15 -0
package/README.md CHANGED
@@ -7,29 +7,29 @@ by conforming to Angular conventions.
7
7
 
8
8
  <strong><pre>ng add @angular/fire</pre></strong>
9
9
 
10
- - **Dependency injection** - Provide and Inject Firebase services in your components
11
- - **Zone.js wrappers** - Stable zones allow proper functionality of service workers, forms, SSR, and pre-rendering
12
- - **Observable based** - Utilize RxJS rather than callbacks for realtime streams
10
+ - **Dependency injection** - Provide and Inject Firebase services in your components.
11
+ - **Zone.js wrappers** - Stable zones allow proper functionality of service workers, forms, SSR, and pre-rendering.
12
+ - **Observable based** - Utilize RxJS rather than callbacks for real-time streams.
13
13
  - **NgRx friendly API** - Integrate with NgRx using AngularFire's action based APIs.
14
- - **Lazy-loading** - AngularFire dynamically imports much of Firebase, reducing time to load your app
15
- - **Deploy schematics** - Get your Angular application deployed on Firebase Hosting with a single command
16
- - **Google Analytics** - Zero-effort Angular Router awareness in Google Analytics
17
- - **Router Guards** - Guard your Angular routes with built-in Firebase Authentication checks
14
+ - **Lazy-loading** - AngularFire dynamically imports much of Firebase, reducing the time to load your app.
15
+ - **Deploy schematics** - Get your Angular application deployed on Firebase Hosting with a single command.
16
+ - **Google Analytics** - Zero-effort Angular Router awareness in Google Analytics.
17
+ - **Router Guards** - Guard your Angular routes with built-in Firebase Authentication checks.
18
18
 
19
19
  ## Example use
20
20
 
21
21
  ```ts
22
- import { provideFirebaseApp, getApp, initializeApp } from '@angular/fire/app';
22
+ import { provideFirebaseApp, initializeApp } from '@angular/fire/app';
23
23
  import { getFirestore, provideFirestore } from '@angular/fire/firestore';
24
24
 
25
- @NgModule({
26
- imports: [
25
+ export const appConfig: ApplicationConfig = {
26
+ providers: [
27
27
  provideFirebaseApp(() => initializeApp({ ... })),
28
28
  provideFirestore(() => getFirestore()),
29
+ ...
29
30
  ],
30
31
  ...
31
32
  })
32
- export class AppModule { }
33
33
  ```
34
34
 
35
35
  ```ts
@@ -44,11 +44,14 @@ interface Item {
44
44
 
45
45
  @Component({
46
46
  selector: 'app-root',
47
+ standalone: true,
47
48
  template: `
48
49
  <ul>
49
- <li *ngFor="let item of item$ | async">
50
- {{ item.name }}
51
- </li>
50
+ @for (item of (item$ | async); track item) {
51
+ <li>
52
+ {{ item.name }}
53
+ </li>
54
+ }
52
55
  </ul>
53
56
  `
54
57
  })
@@ -58,14 +61,14 @@ export class AppComponent {
58
61
 
59
62
  constructor() {
60
63
  const itemCollection = collection(this.firestore, 'items');
61
- this.item$ = collectionData(itemCollection);
64
+ this.item$ = collectionData<Item>(itemCollection);
62
65
  }
63
66
  }
64
67
  ```
65
68
 
66
69
  ### Polyfills
67
70
 
68
- Neither AngularFire or Firebase ship with polyfills. To have compatibility across as wide-range of environments we suggest the following polyfills be added to your application:
71
+ Neither AngularFire nor Firebase ship with polyfills. To have compatibility across a wide-range of environments, we suggest the following polyfills be added to your application:
69
72
 
70
73
  | API | Environments | Suggested Polyfill | License |
71
74
  |-----|--------------|--------------------|---------|
@@ -96,11 +99,11 @@ We have three sample apps in this repository:
96
99
 
97
100
  Get help on our [Q&A board](https://github.com/angular/angularfire/discussions?discussions_q=category%3AQ%26A), the official [Firebase Mailing List](https://groups.google.com/forum/#!forum/firebase-talk), the [Firebase Community Slack](https://firebase.community/) (`#angularfire2`), the [Angular Community Discord](http://discord.gg/angular) (`#firebase`), [Gitter](https://gitter.im/angular/angularfire2), the [Firebase subreddit](https://www.reddit.com/r/firebase), or [Stack Overflow](https://stackoverflow.com/questions/tagged/angularfire2).
98
101
 
99
- > **NOTE:** AngularFire is maintained by Googlers but is not a supported Firebase product. Questions on the mailing list and issues filed here are answered on a <strong>best-effort basis</strong> by maintainers and other community members. If you are able to reproduce a problem with Firebase <em>outside of AngularFire's implementation</em>, please [file an issue on the Firebase JS SDK](https://github.com/firebase/firebase-js-sdk/issues) or reach out to the personalized [Firebase support channel](https://firebase.google.com/support/).
102
+ > **NOTE:** While relatively stable, AngularFire is a [developer preview](https://angular.io/guide/releases#developer-preview) and is subject to change before general availability. Questions on the mailing list and issues filed here are answered on a <strong>best-effort basis</strong> by maintainers and other community members. If you are able to reproduce a problem with Firebase <em>outside of AngularFire's implementation</em>, please [file an issue on the Firebase JS SDK](https://github.com/firebase/firebase-js-sdk/issues) or reach out to the personalized [Firebase support channel](https://firebase.google.com/support/).
100
103
 
101
104
  ## Developer Guide
102
105
 
103
- This developer guide assimes you're using the new tree-shakable AngularFire API, [if you're looking for the compatability API you can find the documentation here](docs/compat.md).
106
+ This developer guide assumes you're using the new tree-shakable AngularFire API, [if you're looking for the compatibility API you can find the documentation here](docs/compat.md).
104
107
 
105
108
  [See the v7 upgrade guide for more information on this change.](docs/version-7-upgrade.md).
106
109
 
@@ -188,9 +191,3 @@ import { } from '@angular/fire/app-check';
188
191
  </td>
189
192
  </tr>
190
193
  </table>
191
-
192
- ### Deploying your site
193
-
194
- * Deploy to Firebase Hosting
195
- * Angular Universal: Deploy to Cloud Functions
196
- * Angular Universal: Deploy to Cloud Run
@@ -1,4 +1,4 @@
1
- import { InjectionToken, Injector, ModuleWithProviders, NgZone } from '@angular/core';
1
+ import { EnvironmentProviders, InjectionToken, Injector, NgZone } from '@angular/core';
2
2
  import { FirebaseApp } from '@angular/fire/app';
3
3
  import { Analytics as FirebaseAnalytics } from 'firebase/analytics';
4
4
  import { Analytics } from './analytics';
@@ -14,4 +14,4 @@ export declare class AnalyticsModule {
14
14
  static ɵmod: i0.ɵɵNgModuleDeclaration<AnalyticsModule, never, never, never>;
15
15
  static ɵinj: i0.ɵɵInjectorDeclaration<AnalyticsModule>;
16
16
  }
17
- export declare function provideAnalytics(fn: (injector: Injector) => FirebaseAnalytics, ...deps: any[]): ModuleWithProviders<AnalyticsModule>;
17
+ export declare function provideAnalytics(fn: (injector: Injector) => FirebaseAnalytics, ...deps: any[]): EnvironmentProviders;
@@ -1,4 +1,4 @@
1
- import { InjectionToken, Injector, ModuleWithProviders, NgZone } from '@angular/core';
1
+ import { EnvironmentProviders, InjectionToken, Injector, NgZone } from '@angular/core';
2
2
  import { FirebaseApp as IFirebaseApp } from 'firebase/app';
3
3
  import { FirebaseApp } from './app';
4
4
  import * as i0 from "@angular/core";
@@ -11,4 +11,4 @@ export declare class FirebaseAppModule {
11
11
  static ɵmod: i0.ɵɵNgModuleDeclaration<FirebaseAppModule, never, never, never>;
12
12
  static ɵinj: i0.ɵɵInjectorDeclaration<FirebaseAppModule>;
13
13
  }
14
- export declare function provideFirebaseApp(fn: (injector: Injector) => IFirebaseApp, ...deps: any[]): ModuleWithProviders<FirebaseAppModule>;
14
+ export declare function provideFirebaseApp(fn: (injector: Injector) => IFirebaseApp, ...deps: any[]): EnvironmentProviders;
package/app/firebase.d.ts CHANGED
@@ -1,9 +1,10 @@
1
1
  export * from 'firebase/app';
2
- import { deleteApp as _deleteApp, getApp as _getApp, getApps as _getApps, initializeApp as _initializeApp, onLog as _onLog, registerVersion as _registerVersion, setLogLevel as _setLogLevel } from 'firebase/app';
2
+ import { deleteApp as _deleteApp, getApp as _getApp, getApps as _getApps, initializeApp as _initializeApp, initializeServerApp as _initializeServerApp, onLog as _onLog, registerVersion as _registerVersion, setLogLevel as _setLogLevel } from 'firebase/app';
3
3
  export declare const deleteApp: typeof _deleteApp;
4
4
  export declare const getApp: typeof _getApp;
5
5
  export declare const getApps: typeof _getApps;
6
6
  export declare const initializeApp: typeof _initializeApp;
7
+ export declare const initializeServerApp: typeof _initializeServerApp;
7
8
  export declare const onLog: typeof _onLog;
8
9
  export declare const registerVersion: typeof _registerVersion;
9
10
  export declare const setLogLevel: typeof _setLogLevel;
@@ -1,4 +1,4 @@
1
- import { InjectionToken, Injector, ModuleWithProviders, NgZone } from '@angular/core';
1
+ import { EnvironmentProviders, InjectionToken, Injector, NgZone } from '@angular/core';
2
2
  import { FirebaseApp } from '@angular/fire/app';
3
3
  import { AppCheck as FirebaseAppCheck } from 'firebase/app-check';
4
4
  import { AppCheck } from './app-check';
@@ -12,4 +12,4 @@ export declare class AppCheckModule {
12
12
  static ɵmod: i0.ɵɵNgModuleDeclaration<AppCheckModule, never, never, never>;
13
13
  static ɵinj: i0.ɵɵInjectorDeclaration<AppCheckModule>;
14
14
  }
15
- export declare function provideAppCheck(fn: (injector: Injector) => FirebaseAppCheck, ...deps: any[]): ModuleWithProviders<AppCheckModule>;
15
+ export declare function provideAppCheck(fn: (injector: Injector) => FirebaseAppCheck, ...deps: any[]): EnvironmentProviders;
@@ -1,4 +1,4 @@
1
- import { InjectionToken, Injector, ModuleWithProviders, NgZone } from '@angular/core';
1
+ import { EnvironmentProviders, InjectionToken, Injector, NgZone } from '@angular/core';
2
2
  import { FirebaseApp } from '@angular/fire/app';
3
3
  import { Auth as FirebaseAuth } from 'firebase/auth';
4
4
  import { Auth } from './auth';
@@ -12,4 +12,4 @@ export declare class AuthModule {
12
12
  static ɵmod: i0.ɵɵNgModuleDeclaration<AuthModule, never, never, never>;
13
13
  static ɵinj: i0.ɵɵInjectorDeclaration<AuthModule>;
14
14
  }
15
- export declare function provideAuth(fn: (injector: Injector) => FirebaseAuth, ...deps: any[]): ModuleWithProviders<AuthModule>;
15
+ export declare function provideAuth(fn: (injector: Injector) => FirebaseAuth, ...deps: any[]): EnvironmentProviders;
@@ -1,4 +1,4 @@
1
- import { InjectionToken, Injector, ModuleWithProviders, NgZone } from '@angular/core';
1
+ import { EnvironmentProviders, InjectionToken, Injector, NgZone } from '@angular/core';
2
2
  import { FirebaseApp } from '@angular/fire/app';
3
3
  import { Database as FirebaseDatabase } from 'firebase/database';
4
4
  import { Database } from './database';
@@ -12,4 +12,4 @@ export declare class DatabaseModule {
12
12
  static ɵmod: i0.ɵɵNgModuleDeclaration<DatabaseModule, never, never, never>;
13
13
  static ɵinj: i0.ɵɵInjectorDeclaration<DatabaseModule>;
14
14
  }
15
- export declare function provideDatabase(fn: (injector: Injector) => FirebaseDatabase, ...deps: any[]): ModuleWithProviders<DatabaseModule>;
15
+ export declare function provideDatabase(fn: (injector: Injector) => FirebaseDatabase, ...deps: any[]): EnvironmentProviders;
@@ -4,7 +4,7 @@
4
4
 
5
5
  `AngularFireAuth` promise proxies an initialized
6
6
  `firebase.auth.Auth` instance, allowing you to log users in, out, etc. [See
7
- the Firebase docs for more information on what methods are available.](https://firebase.google.com/docs/reference/js/firebase.auth.Auth)
7
+ the Firebase docs for more information on what methods are available.](https://firebase.google.com/docs/reference/js/auth.auth)
8
8
 
9
9
  > **NOTE**: [AngularFire has a new tree-shakable API](../../../README.md#developer-guide), you're looking at the documentation for the compatability version of the library. [See the v7 upgrade guide for more information on this change.](../../version-7-upgrade.md).
10
10
 
@@ -65,7 +65,7 @@ import { SETTINGS as AUTH_SETTINGS } from '@angular/fire/compat/auth';
65
65
  export class AppModule { }
66
66
  ```
67
67
 
68
- Read more at [Firebase Auth Settings](https://firebase.google.com/docs/reference/js/firebase.auth.AuthSettings).
68
+ Read more at [Firebase Auth Settings](https://firebase.google.com/docs/reference/js/auth.authsettings).
69
69
 
70
70
  ### Use Current Browser Language
71
71
 
@@ -90,7 +90,7 @@ export class AppModule { }
90
90
  If you want to set a different language, you can use `LANGUAGE_CODE` DI Token
91
91
  (*default: null*).
92
92
 
93
- More info at the [firebase auth docs](https://firebase.google.com/docs/reference/js/firebase.auth.Auth#languagecode).
93
+ More info at the [firebase auth docs](https://firebase.google.com/docs/reference/js/auth.auth#authlanguagecode).
94
94
 
95
95
  ```ts
96
96
  import { LANGUAGE_CODE } from '@angular/fire/compat/auth';
@@ -150,7 +150,7 @@ export class AppModule { }
150
150
  ```
151
151
 
152
152
  - [Multi-Tenancy Authentication](https://cloud.google.com/identity-platform/docs/multi-tenancy-authentication)
153
- - [Firebase Auth Tenant](https://firebase.google.com/docs/reference/js/firebase.auth.Auth#tenantid)
153
+ - [Firebase Auth Tenant](https://firebase.google.com/docs/reference/js/auth.auth#tenantid)
154
154
 
155
155
  ## UI Libraries
156
156
 
@@ -60,6 +60,21 @@ Follow the instructions to download whatever emulator you want to use then check
60
60
  }
61
61
  ```
62
62
 
63
+ Then launch the emulators by running
64
+
65
+ ```shell
66
+ firebase emulators:start
67
+ ```
68
+
69
+ Then you can visit
70
+
71
+ ```shell
72
+ ┌─────────────────────────────────────────────────────────────┐
73
+ │ ✔ All emulators ready! It is now safe to connect your app. │
74
+ │ i View Emulator UI at http://127.0.0.1:4000/ │
75
+ └─────────────────────────────────────────────────────────────┘
76
+ ```
77
+
63
78
  ## Import the DI Tokens at your AppModule
64
79
 
65
80
  Configuring your app to connect to local emulators is easily done by using dependency injection tokens provided by the library. However, there are slighty changes between 6.0.0 and 6.1.0 in the way it was done.
@@ -68,6 +83,17 @@ Configuring your app to connect to local emulators is easily done by using depen
68
83
 
69
84
  Each module (database, firestore, auth, function) provides `USE_EMULATOR` token to configure the emulator `host` and `port` by passing a tuple of `[string, number]` values, which are set by default to `localhost` and the asigned port from your `firebase.json` file.
70
85
 
86
+ Update your `environment.ts` file:
87
+
88
+ ```ts
89
+ export const environment = {
90
+ production: false,
91
+ useEmulators: true,
92
+ ...
93
+ }
94
+
95
+ ```
96
+
71
97
  Import these tokens at your `app.module.ts` as follow:
72
98
 
73
99
  ```ts
@@ -80,7 +106,7 @@ import { USE_EMULATOR as USE_FUNCTIONS_EMULATOR } from '@angular/fire/compat/fun
80
106
  // ... Existing configuration
81
107
  providers: [
82
108
  // ... Existing Providers
83
- { provide: USE_AUTH_EMULATOR, useValue: environment.useEmulators ? ['localhost', 9099] : undefined },
109
+ { provide: USE_AUTH_EMULATOR, useValue: environment.useEmulators ? ['http://localhost', 9099] : undefined },
84
110
  { provide: USE_DATABASE_EMULATOR, useValue: environment.useEmulators ? ['localhost', 9000] : undefined },
85
111
  { provide: USE_FIRESTORE_EMULATOR, useValue: environment.useEmulators ? ['localhost', 8080] : undefined },
86
112
  { provide: USE_FUNCTIONS_EMULATOR, useValue: environment.useEmulators ? ['localhost', 5001] : undefined },
@@ -131,4 +157,4 @@ import { SETTINGS as FIRESTORE_SETTINGS } from '@angular/fire/compat/firestore';
131
157
  export class AppModule { }
132
158
  ```
133
159
 
134
- For older versions, please upgrade your app to latest version to get the advantages of these new features :rocket:
160
+ For older versions, please upgrade your app to latest version to get the advantages of these new features :rocket:
@@ -7,7 +7,7 @@ Each *document* contains a set of key-value pairs. Cloud Firestore is optimized
7
7
 
8
8
  ## Using `AngularFirestoreCollection`
9
9
 
10
- The `AngularFirestoreCollection` service is a wrapper around the native Firestore SDK's [`CollectionReference`](https://firebase.google.com/docs/reference/js/firebase.firestore.CollectionReference) and [`Query`](https://firebase.google.com/docs/reference/js/firebase.firestore.Query) types. It is a generic service that provides you with a strongly typed set of methods for manipulating and streaming data. This service is designed for use as an `@Injectable()`.
10
+ The `AngularFirestoreCollection` service is a wrapper around the native Firestore SDK's [`CollectionReference`](https://firebase.google.com/docs/reference/js/v8/firebase.firestore.CollectionReference) and [`Query`](https://firebase.google.com/docs/reference/js/v8/firebase.firestore.Query) types. It is a generic service that provides you with a strongly typed set of methods for manipulating and streaming data. This service is designed for use as an `@Injectable()`.
11
11
 
12
12
  ```ts
13
13
  import { Component } from '@angular/core';
@@ -1,13 +1,13 @@
1
1
  # 4. Querying Collections in AngularFirestore
2
2
 
3
3
  > Firestore has [powerful querying syntax](https://firebase.google.com/docs/firestore/query-data/queries) and the `AngularFirestoreCollection` provides a thin wrapper around it. This keeps you from having to learn two query syntax systems.
4
- If you know the [Firestore query API](https://firebase.google.com/docs/reference/js/firebase.firestore.Query) then you know how to query in AngularFirestore.
4
+ If you know the [Firestore query API](https://firebase.google.com/docs/reference/js/v8/firebase.firestore.Query) then you know how to query in AngularFirestore.
5
5
 
6
6
  > **NOTE**: [AngularFire has a new tree-shakable API](../../../README.md#developer-guide), you're looking at the documentation for the compatability version of the library. [See the v7 upgrade guide for more information on this change.](../../version-7-upgrade.md).
7
7
 
8
8
  ## Creating a query with primitive/scalar values
9
9
 
10
- Queries are created by building on the [`firebase.firestore.CollectionReference`](https://firebase.google.com/docs/reference/js/firebase.firestore.CollectionReference).
10
+ Queries are created by building on the [`firebase.firestore.CollectionReference`](https://firebase.google.com/docs/reference/js/v8/firebase.firestore.CollectionReference).
11
11
 
12
12
  ```ts
13
13
  afs.collection('items', ref => ref.where('size', '==', 'large'))
package/docs/compat.md CHANGED
@@ -38,7 +38,7 @@ Firebase offers two cloud-based, client-accessible database solutions that suppo
38
38
 
39
39
  ### Authenticate users
40
40
 
41
- - [Getting started with Firebase Authentication](acompat/uth/getting-started.md)
41
+ - [Getting started with Firebase Authentication](compat/auth/getting-started.md)
42
42
  - [Route users with AngularFire guards](compat/auth/router-guards.md)
43
43
 
44
44
  ### Local Emulator Suite
@@ -73,7 +73,7 @@ import { Observable } from 'rxjs';
73
73
  styleUrls: ['app.component.css']
74
74
  })
75
75
  export class AppComponent {
76
- firestore: Firestore = inject(Firestore)
76
+ firestore: Firestore = inject(Firestore);
77
77
  items$: Observable<any[]>;
78
78
 
79
79
  constructor() {
package/docs/messaging.md CHANGED
@@ -6,20 +6,198 @@
6
6
 
7
7
  # Cloud Messaging
8
8
 
9
- The FCM JavaScript API lets you receive notification messages in web apps running in browsers that support the Push API.
9
+ Firebase FCM allows you to register devices with unique FCM tokens, that you can later programtically send notifications to using Firebase Cloud Functions. It is up to the application to update these tokens in Firebase if you want to use them in other layers of your application, i.e send a notification to all administrators, etc. In that case, you would likely want to store your fcm tokens on your user collection, or a sub collection or another collection with different permissions.
10
10
 
11
- [Learn More](https://firebase.google.com/docs/cloud-messaging/)
11
+ # Provide Messaging to your existing application
12
12
 
13
- ## Dependency Injection
13
+ ```
14
+ import { getMessaging, provideMessaging } from "@angular/fire/messaging";
14
15
 
15
- YADA YADA YADA
16
+ bootstrapApplication(AppComponent, {
17
+ providers: [
18
+ ...,
19
+ provideMessaging(() => getMessaging())
20
+ ),
21
+ ],
22
+ });
23
+ ```
16
24
 
17
- ## Firebase API
25
+ # Create a Firebase Messaging Service Worker
18
26
 
19
- Something something look at the offical docs
27
+ There are two parts to Firebase Messaging, a Service Worker and the DOM API. Angular Fire Messaging allows you to request permission, get tokens, delete tokens, and subscribe to messages on the DOM side. To register to receive notifications you need to set up the Service Worker. [The official Firebase documentation for setting up the details exactly how to do that](https://firebase.google.com/docs/cloud-messaging/js/client).
20
28
 
21
- ## Convenience observables
29
+ #### Create your firebase-messaging-sw.js file in your src/assets folder
22
30
 
23
- ### Foo
31
+ *Note: When copying the below file, make sure your firebase version in your installation matches the version your are importing from below*
24
32
 
25
- bar baz
33
+ It may be wise to use file replacements or environments here for different environments
34
+
35
+ ```
36
+ // This sample application is using 9.22, make sure you are importing the same version
37
+
38
+ import { initializeApp } from "https://www.gstatic.com/firebasejs/9.22.0/firebase-app.js";
39
+ import { getMessaging } from "https://www.gstatic.com/firebasejs/9.22.0/firebase-messaging-sw.js";
40
+
41
+ const firebaseApp = initializeApp({
42
+ apiKey: "",
43
+ authDomain: "",
44
+ projectId: "",
45
+ storageBucket: "",
46
+ messagingSenderId: "",
47
+ appId: "",
48
+ });
49
+
50
+ const messaging = getMessaging(firebaseApp);
51
+ ```
52
+
53
+ # Example messaging service
54
+
55
+ ```
56
+ import { Injectable } from "@angular/core";
57
+ import { Messaging, getToken, onMessage, deleteToken } from "@angular/fire/messaging";
58
+ import { Observable, tap } from "rxjs";
59
+
60
+ @Injectable({
61
+ providedIn: "root",
62
+ })
63
+ export class FcmService {
64
+ constructor(private msg: Messaging){
65
+ Notification.requestPermission().then(
66
+ (notificationPermissions: NotificationPermission) => {
67
+ if (notificationPermissions === "granted") {
68
+ console.log("Granted");
69
+ }
70
+ if (notificationPermissions === "denied") {
71
+ console.log("Denied");
72
+ }
73
+ });
74
+ navigator.serviceWorker
75
+ .register("/assets/firebase-messaging-sw.js", {
76
+ type: "module",
77
+ })
78
+ .then((serviceWorkerRegistration) => {
79
+ getToken(this.msg, {
80
+ vapidKey: `an optional key generated on Firebase for your fcm tokens`,
81
+ serviceWorkerRegistration: serviceWorkerRegistration,
82
+ }).then((x) => {
83
+ console.log('my fcm token', x);
84
+ // This is a good place to then store it on your database for each user
85
+ });
86
+ });
87
+ }
88
+ this.message$ = new Observable((sub) => onMessage(this.msg, (msg) =>
89
+ sub.next(msg))).pipe(
90
+ tap((msg) => {
91
+ console.log("My Firebase Cloud Message", msg);
92
+ })
93
+ );
94
+ }
95
+ deleteToken(){
96
+ // We can also delete fcm tokens, make sure to also update this on your firestore db if you are storing them as well
97
+ await deleteToken(this.msg);
98
+ }
99
+ ```
100
+
101
+ # Testing and Sending Notifications
102
+
103
+ Firebase will allow you to send a test notification under Engage > Messaging > New Campaign > Notifications. Here you can click send a test message. Additionally, you can send them programmatically through Firebase cloud functions.
104
+
105
+ Here is a barebones Node example:
106
+
107
+ ```
108
+ export const sendTestMessage = onRequest(async (_, res) => {
109
+ try {
110
+ const message = {
111
+ notification: {
112
+ title: "Test Title",
113
+ body: "Test Body",
114
+ },
115
+ token: "your token here, you can store these and retreive as you please",
116
+ };
117
+ await admin.messaging().send(message);
118
+ res.sendStatus(200);
119
+ } catch (error) {
120
+ console.error(error);
121
+ res.sendStatus(500);
122
+ }
123
+ });
124
+ ```
125
+
126
+ Here is a Node example that listens for a new comment on a collection, then sends a notification, and also adds it to a cache on Firebase so users can click through them.
127
+
128
+ ```
129
+ exports.onPostReply =
130
+ onDocumentCreated("comments/{commentId}", async (event) => {
131
+ if (!event) throw new Error("No event found for document creation");
132
+ const snapshot = event.data;
133
+ if (!snapshot) {
134
+ throw new Error("No data associated with the event");
135
+ }
136
+ const data = snapshot.data();
137
+ if (!data.postId) {
138
+ throw new Error("No post ID found");
139
+ }
140
+ const postRef = await firestore.collection("posts").doc(data.postId).get();
141
+ const postData = postRef.data();
142
+ if (!postData) {
143
+ throw new Error("No postData found");
144
+ }
145
+ // userUid will be the post author's id.
146
+ const {userUid} = postData;
147
+ if (!userUid) {
148
+ throw new Error(
149
+ "Could not find the userUid for the post author for post reply"
150
+ );
151
+ }
152
+ const messageForNotification = {
153
+ title: "You have a new reply on your post",
154
+ body: "",
155
+ };
156
+ await createNotificationAndCache(messageForNotification, userUid);
157
+ });
158
+
159
+ // If you want to cache notifications a number of times, abstracting this
160
+ // to a function can bring a lot of value.
161
+
162
+ interface NotificationProps {
163
+ title: string;
164
+ body: string;
165
+ }
166
+
167
+ async function createNotificationAndCache(
168
+ notificationProps: NotificationProps, userAuthUid: string) {
169
+ const userRef = await firestore.collection("users").where("authUid", "==",
170
+ userAuthUid).get();
171
+ const userData = userRef.docs[0].data();
172
+
173
+ const promises: Promise<any>[] = [];
174
+ // This sample application has seperate fcm tokens for web and mobile
175
+ if (userData.mobileToken) {
176
+ const message = {
177
+ notification: notificationProps,
178
+ token: userData.mobileToken,
179
+ };
180
+ const promise = admin.messaging().send(message);
181
+ promises.push(promise);
182
+ }
183
+ if (userData.webToken) {
184
+ const message = {
185
+ notification: notificationProps,
186
+ token: userData.webToken,
187
+ };
188
+ const promise = admin.messaging().send(message);
189
+ promises.push(promise);
190
+ }
191
+
192
+ const notificationCacheValue = {
193
+ userAuthUid: userAuthUid,
194
+ tokenTitle: notificationProps.title,
195
+ tokenBody: notificationProps.body,
196
+ isActive: true, // This determines whether a notification has been seen
197
+ };
198
+
199
+ promises.push(
200
+ firestore.collection("notificationCache").add(notificationCacheValue));
201
+
202
+ await Promise.all(promises);
203
+ } ```
@@ -1,4 +1,4 @@
1
- import { APP_INITIALIZER, InjectionToken, Injector, NgModule, NgZone, Optional } from '@angular/core';
1
+ import { APP_INITIALIZER, InjectionToken, Injector, NgModule, NgZone, Optional, makeEnvironmentProviders, } from '@angular/core';
2
2
  import { VERSION, ɵAngularFireSchedulers, ɵgetDefaultInstanceOf } from '@angular/fire';
3
3
  import { FirebaseApp, FirebaseApps } from '@angular/fire/app';
4
4
  import { registerVersion } from 'firebase/app';
@@ -75,20 +75,27 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.6", ngImpor
75
75
  type: Optional
76
76
  }] }] });
77
77
  export function provideAnalytics(fn, ...deps) {
78
- return {
79
- ngModule: AnalyticsModule,
80
- providers: [{
81
- provide: PROVIDED_ANALYTICS_INSTANCES,
82
- useFactory: analyticsInstanceFactory(fn),
83
- multi: true,
84
- deps: [
85
- NgZone,
86
- Injector,
87
- ɵAngularFireSchedulers,
88
- FirebaseApps,
89
- ...deps,
90
- ]
91
- }]
92
- };
78
+ registerVersion('angularfire', VERSION.full, 'analytics');
79
+ return makeEnvironmentProviders([
80
+ DEFAULT_ANALYTICS_INSTANCE_PROVIDER,
81
+ ANALYTICS_INSTANCES_PROVIDER,
82
+ {
83
+ provide: APP_INITIALIZER,
84
+ useValue: isAnalyticsSupportedFactory.async,
85
+ multi: true,
86
+ },
87
+ {
88
+ provide: PROVIDED_ANALYTICS_INSTANCES,
89
+ useFactory: analyticsInstanceFactory(fn),
90
+ multi: true,
91
+ deps: [
92
+ NgZone,
93
+ Injector,
94
+ ɵAngularFireSchedulers,
95
+ FirebaseApps,
96
+ ...deps,
97
+ ],
98
+ },
99
+ ]);
93
100
  }
94
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW5hbHl0aWNzLm1vZHVsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9hbmFseXRpY3MvYW5hbHl0aWNzLm1vZHVsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsZUFBZSxFQUFFLGNBQWMsRUFBRSxRQUFRLEVBQXVCLFFBQVEsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNILE9BQU8sRUFBRSxPQUFPLEVBQUUsc0JBQXNCLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDdkYsT0FBTyxFQUFFLFdBQVcsRUFBRSxZQUFZLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUU5RCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQy9DLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxTQUFTLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDckYsT0FBTyxFQUFFLDJCQUEyQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDL0UsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDbEUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0seUJBQXlCLENBQUM7Ozs7QUFFOUQsTUFBTSxDQUFDLE1BQU0sNEJBQTRCLEdBQUcsSUFBSSxjQUFjLENBQWMsa0NBQWtDLENBQUMsQ0FBQztBQUVoSCxNQUFNLFVBQVUsK0JBQStCLENBQUMsUUFBdUMsRUFBRSxVQUF1QjtJQUM5RyxJQUFJLENBQUMsMkJBQTJCLENBQUMsSUFBSSxFQUFFLEVBQUU7UUFBRSxPQUFPLElBQUksQ0FBQztLQUFFO0lBQ3pELE1BQU0sZ0JBQWdCLEdBQUcscUJBQXFCLENBQW9CLHVCQUF1QixFQUFFLFFBQVEsRUFBRSxVQUFVLENBQUMsQ0FBQztJQUNqSCxPQUFPLGdCQUFnQixJQUFJLElBQUksU0FBUyxDQUFDLGdCQUFnQixDQUFDLENBQUM7QUFDN0QsQ0FBQztBQUVELE1BQU0sVUFBVSx3QkFBd0IsQ0FBQyxFQUE2QztJQUNwRixPQUFPLENBQUMsSUFBWSxFQUFFLFFBQWtCLEVBQUUsRUFBRTtRQUMxQyxJQUFJLENBQUMsMkJBQTJCLENBQUMsSUFBSSxFQUFFLEVBQUU7WUFBRSxPQUFPLElBQUksQ0FBQztTQUFFO1FBQ3pELE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztRQUM3RCxPQUFPLElBQUksU0FBUyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ2xDLENBQUMsQ0FBQztBQUNKLENBQUM7QUFFRCxNQUFNLDRCQUE0QixHQUFHO0lBQ25DLE9BQU8sRUFBRSxrQkFBa0I7SUFDM0IsSUFBSSxFQUFFO1FBQ0osQ0FBQyxJQUFJLFFBQVEsRUFBRSxFQUFFLDRCQUE0QixDQUFFO0tBQ2hEO0NBQ0YsQ0FBQztBQUVGLE1BQU0sbUNBQW1DLEdBQUc7SUFDMUMsT0FBTyxFQUFFLFNBQVM7SUFDbEIsVUFBVSxFQUFFLCtCQUErQjtJQUMzQyxJQUFJLEVBQUU7UUFDSixDQUFDLElBQUksUUFBUSxFQUFFLEVBQUUsNEJBQTRCLENBQUU7UUFDL0MsV0FBVztLQUNaO0NBQ0YsQ0FBQztBQWFGLE1BQU0sT0FBTyxlQUFlO0lBQzFCLFlBQ2Msc0JBQTZDLEVBQzdDLG9CQUF5QztRQUVyRCxlQUFlLENBQUMsYUFBYSxFQUFFLE9BQU8sQ0FBQyxJQUFJLEVBQUUsV0FBVyxDQUFDLENBQUM7SUFDNUQsQ0FBQzt1R0FOVSxlQUFlO3dHQUFmLGVBQWU7d0dBQWYsZUFBZSxhQVZmO1lBQ1QsbUNBQW1DO1lBQ25DLDRCQUE0QjtZQUM1QjtnQkFDRSxPQUFPLEVBQUUsZUFBZTtnQkFDeEIsUUFBUSxFQUFFLDJCQUEyQixDQUFDLEtBQUs7Z0JBQzNDLEtBQUssRUFBRSxJQUFJO2FBQ1o7U0FDRjs7MkZBRVUsZUFBZTtrQkFYM0IsUUFBUTttQkFBQztvQkFDUixTQUFTLEVBQUU7d0JBQ1QsbUNBQW1DO3dCQUNuQyw0QkFBNEI7d0JBQzVCOzRCQUNFLE9BQU8sRUFBRSxlQUFlOzRCQUN4QixRQUFRLEVBQUUsMkJBQTJCLENBQUMsS0FBSzs0QkFDM0MsS0FBSyxFQUFFLElBQUk7eUJBQ1o7cUJBQ0Y7aUJBQ0Y7OzBCQUdJLFFBQVE7OzBCQUNSLFFBQVE7O0FBTWIsTUFBTSxVQUFVLGdCQUFnQixDQUFDLEVBQTZDLEVBQUUsR0FBRyxJQUFXO0lBQzVGLE9BQU87UUFDTCxRQUFRLEVBQUUsZUFBZTtRQUN6QixTQUFTLEVBQUUsQ0FBQztnQkFDVixPQUFPLEVBQUUsNEJBQTRCO2dCQUNyQyxVQUFVLEVBQUUsd0JBQXdCLENBQUMsRUFBRSxDQUFDO2dCQUN4QyxLQUFLLEVBQUUsSUFBSTtnQkFDWCxJQUFJLEVBQUU7b0JBQ0osTUFBTTtvQkFDTixRQUFRO29CQUNSLHNCQUFzQjtvQkFDdEIsWUFBWTtvQkFDWixHQUFHLElBQUk7aUJBQ1I7YUFDRixDQUFDO0tBQ0gsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBUFBfSU5JVElBTElaRVIsIEluamVjdGlvblRva2VuLCBJbmplY3RvciwgTW9kdWxlV2l0aFByb3ZpZGVycywgTmdNb2R1bGUsIE5nWm9uZSwgT3B0aW9uYWwgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFZFUlNJT04sIMm1QW5ndWxhckZpcmVTY2hlZHVsZXJzLCDJtWdldERlZmF1bHRJbnN0YW5jZU9mIH0gZnJvbSAnQGFuZ3VsYXIvZmlyZSc7XG5pbXBvcnQgeyBGaXJlYmFzZUFwcCwgRmlyZWJhc2VBcHBzIH0gZnJvbSAnQGFuZ3VsYXIvZmlyZS9hcHAnO1xuaW1wb3J0IHsgQW5hbHl0aWNzIGFzIEZpcmViYXNlQW5hbHl0aWNzIH0gZnJvbSAnZmlyZWJhc2UvYW5hbHl0aWNzJztcbmltcG9ydCB7IHJlZ2lzdGVyVmVyc2lvbiB9IGZyb20gJ2ZpcmViYXNlL2FwcCc7XG5pbXBvcnQgeyBBTkFMWVRJQ1NfUFJPVklERVJfTkFNRSwgQW5hbHl0aWNzLCBBbmFseXRpY3NJbnN0YW5jZXMgfSBmcm9tICcuL2FuYWx5dGljcyc7XG5pbXBvcnQgeyBpc0FuYWx5dGljc1N1cHBvcnRlZEZhY3RvcnkgfSBmcm9tICcuL2lzLWFuYWx5dGljcy1zdXBwb3J0ZWQtZmFjdG9yeSc7XG5pbXBvcnQgeyBTY3JlZW5UcmFja2luZ1NlcnZpY2UgfSBmcm9tICcuL3NjcmVlbi10cmFja2luZy5zZXJ2aWNlJztcbmltcG9ydCB7IFVzZXJUcmFja2luZ1NlcnZpY2UgfSBmcm9tICcuL3VzZXItdHJhY2tpbmcuc2VydmljZSc7XG5cbmV4cG9ydCBjb25zdCBQUk9WSURFRF9BTkFMWVRJQ1NfSU5TVEFOQ0VTID0gbmV3IEluamVjdGlvblRva2VuPEFuYWx5dGljc1tdPignYW5ndWxhcmZpcmUyLmFuYWx5dGljcy1pbnN0YW5jZXMnKTtcblxuZXhwb3J0IGZ1bmN0aW9uIGRlZmF1bHRBbmFseXRpY3NJbnN0YW5jZUZhY3RvcnkocHJvdmlkZWQ6IEZpcmViYXNlQW5hbHl0aWNzW118dW5kZWZpbmVkLCBkZWZhdWx0QXBwOiBGaXJlYmFzZUFwcCkge1xuICBpZiAoIWlzQW5hbHl0aWNzU3VwcG9ydGVkRmFjdG9yeS5zeW5jKCkpIHsgcmV0dXJuIG51bGw7IH1cbiAgY29uc3QgZGVmYXVsdEFuYWx5dGljcyA9IMm1Z2V0RGVmYXVsdEluc3RhbmNlT2Y8RmlyZWJhc2VBbmFseXRpY3M+KEFOQUxZVElDU19QUk9WSURFUl9OQU1FLCBwcm92aWRlZCwgZGVmYXVsdEFwcCk7XG4gIHJldHVybiBkZWZhdWx0QW5hbHl0aWNzICYmIG5ldyBBbmFseXRpY3MoZGVmYXVsdEFuYWx5dGljcyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhbmFseXRpY3NJbnN0YW5jZUZhY3RvcnkoZm46IChpbmplY3RvcjogSW5qZWN0b3IpID0+IEZpcmViYXNlQW5hbHl0aWNzKSB7XG4gIHJldHVybiAoem9uZTogTmdab25lLCBpbmplY3RvcjogSW5qZWN0b3IpID0+IHtcbiAgICBpZiAoIWlzQW5hbHl0aWNzU3VwcG9ydGVkRmFjdG9yeS5zeW5jKCkpIHsgcmV0dXJuIG51bGw7IH1cbiAgICBjb25zdCBhbmFseXRpY3MgPSB6b25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IGZuKGluamVjdG9yKSk7XG4gICAgcmV0dXJuIG5ldyBBbmFseXRpY3MoYW5hbHl0aWNzKTtcbiAgfTtcbn1cblxuY29uc3QgQU5BTFlUSUNTX0lOU1RBTkNFU19QUk9WSURFUiA9IHtcbiAgcHJvdmlkZTogQW5hbHl0aWNzSW5zdGFuY2VzLFxuICBkZXBzOiBbXG4gICAgW25ldyBPcHRpb25hbCgpLCBQUk9WSURFRF9BTkFMWVRJQ1NfSU5TVEFOQ0VTIF0sXG4gIF1cbn07XG5cbmNvbnN0IERFRkFVTFRfQU5BTFlUSUNTX0lOU1RBTkNFX1BST1ZJREVSID0ge1xuICBwcm92aWRlOiBBbmFseXRpY3MsXG4gIHVzZUZhY3Rvcnk6IGRlZmF1bHRBbmFseXRpY3NJbnN0YW5jZUZhY3RvcnksXG4gIGRlcHM6IFtcbiAgICBbbmV3IE9wdGlvbmFsKCksIFBST1ZJREVEX0FOQUxZVElDU19JTlNUQU5DRVMgXSxcbiAgICBGaXJlYmFzZUFwcCxcbiAgXVxufTtcblxuQE5nTW9kdWxlKHtcbiAgcHJvdmlkZXJzOiBbXG4gICAgREVGQVVMVF9BTkFMWVRJQ1NfSU5TVEFOQ0VfUFJPVklERVIsXG4gICAgQU5BTFlUSUNTX0lOU1RBTkNFU19QUk9WSURFUixcbiAgICB7XG4gICAgICBwcm92aWRlOiBBUFBfSU5JVElBTElaRVIsXG4gICAgICB1c2VWYWx1ZTogaXNBbmFseXRpY3NTdXBwb3J0ZWRGYWN0b3J5LmFzeW5jLFxuICAgICAgbXVsdGk6IHRydWUsXG4gICAgfVxuICBdXG59KVxuZXhwb3J0IGNsYXNzIEFuYWx5dGljc01vZHVsZSB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIEBPcHRpb25hbCgpIF9zY3JlZW5UcmFja2luZ1NlcnZpY2U6IFNjcmVlblRyYWNraW5nU2VydmljZSxcbiAgICBAT3B0aW9uYWwoKSBfdXNlclRyYWNraW5nU2VydmljZTogVXNlclRyYWNraW5nU2VydmljZSxcbiAgKSB7XG4gICAgcmVnaXN0ZXJWZXJzaW9uKCdhbmd1bGFyZmlyZScsIFZFUlNJT04uZnVsbCwgJ2FuYWx5dGljcycpO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwcm92aWRlQW5hbHl0aWNzKGZuOiAoaW5qZWN0b3I6IEluamVjdG9yKSA9PiBGaXJlYmFzZUFuYWx5dGljcywgLi4uZGVwczogYW55W10pOiBNb2R1bGVXaXRoUHJvdmlkZXJzPEFuYWx5dGljc01vZHVsZT4ge1xuICByZXR1cm4ge1xuICAgIG5nTW9kdWxlOiBBbmFseXRpY3NNb2R1bGUsXG4gICAgcHJvdmlkZXJzOiBbe1xuICAgICAgcHJvdmlkZTogUFJPVklERURfQU5BTFlUSUNTX0lOU1RBTkNFUyxcbiAgICAgIHVzZUZhY3Rvcnk6IGFuYWx5dGljc0luc3RhbmNlRmFjdG9yeShmbiksXG4gICAgICBtdWx0aTogdHJ1ZSxcbiAgICAgIGRlcHM6IFtcbiAgICAgICAgTmdab25lLFxuICAgICAgICBJbmplY3RvcixcbiAgICAgICAgybVBbmd1bGFyRmlyZVNjaGVkdWxlcnMsXG4gICAgICAgIEZpcmViYXNlQXBwcyxcbiAgICAgICAgLi4uZGVwcyxcbiAgICAgIF1cbiAgICB9XVxuICB9O1xufVxuIl19
101
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW5hbHl0aWNzLm1vZHVsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9hbmFseXRpY3MvYW5hbHl0aWNzLm1vZHVsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsZUFBZSxFQUVmLGNBQWMsRUFDZCxRQUFRLEVBQ1IsUUFBUSxFQUNSLE1BQU0sRUFDTixRQUFRLEVBQ1Isd0JBQXdCLEdBQ3pCLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxPQUFPLEVBQUUsc0JBQXNCLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDdkYsT0FBTyxFQUFFLFdBQVcsRUFBRSxZQUFZLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUU5RCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQy9DLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxTQUFTLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDckYsT0FBTyxFQUFFLDJCQUEyQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDL0UsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDbEUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0seUJBQXlCLENBQUM7Ozs7QUFFOUQsTUFBTSxDQUFDLE1BQU0sNEJBQTRCLEdBQUcsSUFBSSxjQUFjLENBQWMsa0NBQWtDLENBQUMsQ0FBQztBQUVoSCxNQUFNLFVBQVUsK0JBQStCLENBQUMsUUFBdUMsRUFBRSxVQUF1QjtJQUM5RyxJQUFJLENBQUMsMkJBQTJCLENBQUMsSUFBSSxFQUFFLEVBQUU7UUFBRSxPQUFPLElBQUksQ0FBQztLQUFFO0lBQ3pELE1BQU0sZ0JBQWdCLEdBQUcscUJBQXFCLENBQW9CLHVCQUF1QixFQUFFLFFBQVEsRUFBRSxVQUFVLENBQUMsQ0FBQztJQUNqSCxPQUFPLGdCQUFnQixJQUFJLElBQUksU0FBUyxDQUFDLGdCQUFnQixDQUFDLENBQUM7QUFDN0QsQ0FBQztBQUVELE1BQU0sVUFBVSx3QkFBd0IsQ0FBQyxFQUE2QztJQUNwRixPQUFPLENBQUMsSUFBWSxFQUFFLFFBQWtCLEVBQUUsRUFBRTtRQUMxQyxJQUFJLENBQUMsMkJBQTJCLENBQUMsSUFBSSxFQUFFLEVBQUU7WUFBRSxPQUFPLElBQUksQ0FBQztTQUFFO1FBQ3pELE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztRQUM3RCxPQUFPLElBQUksU0FBUyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ2xDLENBQUMsQ0FBQztBQUNKLENBQUM7QUFFRCxNQUFNLDRCQUE0QixHQUFHO0lBQ25DLE9BQU8sRUFBRSxrQkFBa0I7SUFDM0IsSUFBSSxFQUFFO1FBQ0osQ0FBQyxJQUFJLFFBQVEsRUFBRSxFQUFFLDRCQUE0QixDQUFFO0tBQ2hEO0NBQ0YsQ0FBQztBQUVGLE1BQU0sbUNBQW1DLEdBQUc7SUFDMUMsT0FBTyxFQUFFLFNBQVM7SUFDbEIsVUFBVSxFQUFFLCtCQUErQjtJQUMzQyxJQUFJLEVBQUU7UUFDSixDQUFDLElBQUksUUFBUSxFQUFFLEVBQUUsNEJBQTRCLENBQUU7UUFDL0MsV0FBVztLQUNaO0NBQ0YsQ0FBQztBQWFGLE1BQU0sT0FBTyxlQUFlO0lBQzFCLFlBQ2Msc0JBQTZDLEVBQzdDLG9CQUF5QztRQUVyRCxlQUFlLENBQUMsYUFBYSxFQUFFLE9BQU8sQ0FBQyxJQUFJLEVBQUUsV0FBVyxDQUFDLENBQUM7SUFDNUQsQ0FBQzt1R0FOVSxlQUFlO3dHQUFmLGVBQWU7d0dBQWYsZUFBZSxhQVZmO1lBQ1QsbUNBQW1DO1lBQ25DLDRCQUE0QjtZQUM1QjtnQkFDRSxPQUFPLEVBQUUsZUFBZTtnQkFDeEIsUUFBUSxFQUFFLDJCQUEyQixDQUFDLEtBQUs7Z0JBQzNDLEtBQUssRUFBRSxJQUFJO2FBQ1o7U0FDRjs7MkZBRVUsZUFBZTtrQkFYM0IsUUFBUTttQkFBQztvQkFDUixTQUFTLEVBQUU7d0JBQ1QsbUNBQW1DO3dCQUNuQyw0QkFBNEI7d0JBQzVCOzRCQUNFLE9BQU8sRUFBRSxlQUFlOzRCQUN4QixRQUFRLEVBQUUsMkJBQTJCLENBQUMsS0FBSzs0QkFDM0MsS0FBSyxFQUFFLElBQUk7eUJBQ1o7cUJBQ0Y7aUJBQ0Y7OzBCQUdJLFFBQVE7OzBCQUNSLFFBQVE7O0FBTWIsTUFBTSxVQUFVLGdCQUFnQixDQUFDLEVBQTZDLEVBQUUsR0FBRyxJQUFXO0lBQzVGLGVBQWUsQ0FBQyxhQUFhLEVBQUUsT0FBTyxDQUFDLElBQUksRUFBRSxXQUFXLENBQUMsQ0FBQztJQUUxRCxPQUFPLHdCQUF3QixDQUFDO1FBQzlCLG1DQUFtQztRQUNuQyw0QkFBNEI7UUFDNUI7WUFDRSxPQUFPLEVBQUUsZUFBZTtZQUN4QixRQUFRLEVBQUUsMkJBQTJCLENBQUMsS0FBSztZQUMzQyxLQUFLLEVBQUUsSUFBSTtTQUNaO1FBQ0Q7WUFDRSxPQUFPLEVBQUUsNEJBQTRCO1lBQ3JDLFVBQVUsRUFBRSx3QkFBd0IsQ0FBQyxFQUFFLENBQUM7WUFDeEMsS0FBSyxFQUFFLElBQUk7WUFDWCxJQUFJLEVBQUU7Z0JBQ0osTUFBTTtnQkFDTixRQUFRO2dCQUNSLHNCQUFzQjtnQkFDdEIsWUFBWTtnQkFDWixHQUFHLElBQUk7YUFDUjtTQUNGO0tBQ0YsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEFQUF9JTklUSUFMSVpFUixcbiAgRW52aXJvbm1lbnRQcm92aWRlcnMsXG4gIEluamVjdGlvblRva2VuLFxuICBJbmplY3RvcixcbiAgTmdNb2R1bGUsXG4gIE5nWm9uZSxcbiAgT3B0aW9uYWwsXG4gIG1ha2VFbnZpcm9ubWVudFByb3ZpZGVycyxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBWRVJTSU9OLCDJtUFuZ3VsYXJGaXJlU2NoZWR1bGVycywgybVnZXREZWZhdWx0SW5zdGFuY2VPZiB9IGZyb20gJ0Bhbmd1bGFyL2ZpcmUnO1xuaW1wb3J0IHsgRmlyZWJhc2VBcHAsIEZpcmViYXNlQXBwcyB9IGZyb20gJ0Bhbmd1bGFyL2ZpcmUvYXBwJztcbmltcG9ydCB7IEFuYWx5dGljcyBhcyBGaXJlYmFzZUFuYWx5dGljcyB9IGZyb20gJ2ZpcmViYXNlL2FuYWx5dGljcyc7XG5pbXBvcnQgeyByZWdpc3RlclZlcnNpb24gfSBmcm9tICdmaXJlYmFzZS9hcHAnO1xuaW1wb3J0IHsgQU5BTFlUSUNTX1BST1ZJREVSX05BTUUsIEFuYWx5dGljcywgQW5hbHl0aWNzSW5zdGFuY2VzIH0gZnJvbSAnLi9hbmFseXRpY3MnO1xuaW1wb3J0IHsgaXNBbmFseXRpY3NTdXBwb3J0ZWRGYWN0b3J5IH0gZnJvbSAnLi9pcy1hbmFseXRpY3Mtc3VwcG9ydGVkLWZhY3RvcnknO1xuaW1wb3J0IHsgU2NyZWVuVHJhY2tpbmdTZXJ2aWNlIH0gZnJvbSAnLi9zY3JlZW4tdHJhY2tpbmcuc2VydmljZSc7XG5pbXBvcnQgeyBVc2VyVHJhY2tpbmdTZXJ2aWNlIH0gZnJvbSAnLi91c2VyLXRyYWNraW5nLnNlcnZpY2UnO1xuXG5leHBvcnQgY29uc3QgUFJPVklERURfQU5BTFlUSUNTX0lOU1RBTkNFUyA9IG5ldyBJbmplY3Rpb25Ub2tlbjxBbmFseXRpY3NbXT4oJ2FuZ3VsYXJmaXJlMi5hbmFseXRpY3MtaW5zdGFuY2VzJyk7XG5cbmV4cG9ydCBmdW5jdGlvbiBkZWZhdWx0QW5hbHl0aWNzSW5zdGFuY2VGYWN0b3J5KHByb3ZpZGVkOiBGaXJlYmFzZUFuYWx5dGljc1tdfHVuZGVmaW5lZCwgZGVmYXVsdEFwcDogRmlyZWJhc2VBcHApIHtcbiAgaWYgKCFpc0FuYWx5dGljc1N1cHBvcnRlZEZhY3Rvcnkuc3luYygpKSB7IHJldHVybiBudWxsOyB9XG4gIGNvbnN0IGRlZmF1bHRBbmFseXRpY3MgPSDJtWdldERlZmF1bHRJbnN0YW5jZU9mPEZpcmViYXNlQW5hbHl0aWNzPihBTkFMWVRJQ1NfUFJPVklERVJfTkFNRSwgcHJvdmlkZWQsIGRlZmF1bHRBcHApO1xuICByZXR1cm4gZGVmYXVsdEFuYWx5dGljcyAmJiBuZXcgQW5hbHl0aWNzKGRlZmF1bHRBbmFseXRpY3MpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYW5hbHl0aWNzSW5zdGFuY2VGYWN0b3J5KGZuOiAoaW5qZWN0b3I6IEluamVjdG9yKSA9PiBGaXJlYmFzZUFuYWx5dGljcykge1xuICByZXR1cm4gKHpvbmU6IE5nWm9uZSwgaW5qZWN0b3I6IEluamVjdG9yKSA9PiB7XG4gICAgaWYgKCFpc0FuYWx5dGljc1N1cHBvcnRlZEZhY3Rvcnkuc3luYygpKSB7IHJldHVybiBudWxsOyB9XG4gICAgY29uc3QgYW5hbHl0aWNzID0gem9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiBmbihpbmplY3RvcikpO1xuICAgIHJldHVybiBuZXcgQW5hbHl0aWNzKGFuYWx5dGljcyk7XG4gIH07XG59XG5cbmNvbnN0IEFOQUxZVElDU19JTlNUQU5DRVNfUFJPVklERVIgPSB7XG4gIHByb3ZpZGU6IEFuYWx5dGljc0luc3RhbmNlcyxcbiAgZGVwczogW1xuICAgIFtuZXcgT3B0aW9uYWwoKSwgUFJPVklERURfQU5BTFlUSUNTX0lOU1RBTkNFUyBdLFxuICBdXG59O1xuXG5jb25zdCBERUZBVUxUX0FOQUxZVElDU19JTlNUQU5DRV9QUk9WSURFUiA9IHtcbiAgcHJvdmlkZTogQW5hbHl0aWNzLFxuICB1c2VGYWN0b3J5OiBkZWZhdWx0QW5hbHl0aWNzSW5zdGFuY2VGYWN0b3J5LFxuICBkZXBzOiBbXG4gICAgW25ldyBPcHRpb25hbCgpLCBQUk9WSURFRF9BTkFMWVRJQ1NfSU5TVEFOQ0VTIF0sXG4gICAgRmlyZWJhc2VBcHAsXG4gIF1cbn07XG5cbkBOZ01vZHVsZSh7XG4gIHByb3ZpZGVyczogW1xuICAgIERFRkFVTFRfQU5BTFlUSUNTX0lOU1RBTkNFX1BST1ZJREVSLFxuICAgIEFOQUxZVElDU19JTlNUQU5DRVNfUFJPVklERVIsXG4gICAge1xuICAgICAgcHJvdmlkZTogQVBQX0lOSVRJQUxJWkVSLFxuICAgICAgdXNlVmFsdWU6IGlzQW5hbHl0aWNzU3VwcG9ydGVkRmFjdG9yeS5hc3luYyxcbiAgICAgIG11bHRpOiB0cnVlLFxuICAgIH1cbiAgXVxufSlcbmV4cG9ydCBjbGFzcyBBbmFseXRpY3NNb2R1bGUge1xuICBjb25zdHJ1Y3RvcihcbiAgICBAT3B0aW9uYWwoKSBfc2NyZWVuVHJhY2tpbmdTZXJ2aWNlOiBTY3JlZW5UcmFja2luZ1NlcnZpY2UsXG4gICAgQE9wdGlvbmFsKCkgX3VzZXJUcmFja2luZ1NlcnZpY2U6IFVzZXJUcmFja2luZ1NlcnZpY2UsXG4gICkge1xuICAgIHJlZ2lzdGVyVmVyc2lvbignYW5ndWxhcmZpcmUnLCBWRVJTSU9OLmZ1bGwsICdhbmFseXRpY3MnKTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gcHJvdmlkZUFuYWx5dGljcyhmbjogKGluamVjdG9yOiBJbmplY3RvcikgPT4gRmlyZWJhc2VBbmFseXRpY3MsIC4uLmRlcHM6IGFueVtdKTogRW52aXJvbm1lbnRQcm92aWRlcnMge1xuICByZWdpc3RlclZlcnNpb24oJ2FuZ3VsYXJmaXJlJywgVkVSU0lPTi5mdWxsLCAnYW5hbHl0aWNzJyk7XG5cbiAgcmV0dXJuIG1ha2VFbnZpcm9ubWVudFByb3ZpZGVycyhbXG4gICAgREVGQVVMVF9BTkFMWVRJQ1NfSU5TVEFOQ0VfUFJPVklERVIsXG4gICAgQU5BTFlUSUNTX0lOU1RBTkNFU19QUk9WSURFUixcbiAgICB7XG4gICAgICBwcm92aWRlOiBBUFBfSU5JVElBTElaRVIsXG4gICAgICB1c2VWYWx1ZTogaXNBbmFseXRpY3NTdXBwb3J0ZWRGYWN0b3J5LmFzeW5jLFxuICAgICAgbXVsdGk6IHRydWUsXG4gICAgfSxcbiAgICB7XG4gICAgICBwcm92aWRlOiBQUk9WSURFRF9BTkFMWVRJQ1NfSU5TVEFOQ0VTLFxuICAgICAgdXNlRmFjdG9yeTogYW5hbHl0aWNzSW5zdGFuY2VGYWN0b3J5KGZuKSxcbiAgICAgIG11bHRpOiB0cnVlLFxuICAgICAgZGVwczogW1xuICAgICAgICBOZ1pvbmUsXG4gICAgICAgIEluamVjdG9yLFxuICAgICAgICDJtUFuZ3VsYXJGaXJlU2NoZWR1bGVycyxcbiAgICAgICAgRmlyZWJhc2VBcHBzLFxuICAgICAgICAuLi5kZXBzLFxuICAgICAgXSxcbiAgICB9LFxuICBdKTtcbn1cbiJdfQ==