@firebase/data-connect 0.0.3-dataconnect-preview.d986d4bf2 → 0.1.0

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.
@@ -130,7 +130,7 @@ function getGoogApiClientValue(_isUsingGen) {
130
130
  }
131
131
  return str;
132
132
  }
133
- function dcFetch(url, body, { signal }, accessToken, _isUsingGen) {
133
+ function dcFetch(url, body, { signal }, appId, accessToken, appCheckToken, _isUsingGen) {
134
134
  if (!connectFetch) {
135
135
  throw new DataConnectError(Code.OTHER, 'No Fetch Implementation detected!');
136
136
  }
@@ -141,6 +141,12 @@ function dcFetch(url, body, { signal }, accessToken, _isUsingGen) {
141
141
  if (accessToken) {
142
142
  headers['X-Firebase-Auth-Token'] = accessToken;
143
143
  }
144
+ if (appId) {
145
+ headers['x-firebase-gmpid'] = appId;
146
+ }
147
+ if (appCheckToken) {
148
+ headers['X-Firebase-AppCheck'] = appCheckToken;
149
+ }
144
150
  const bodyStr = JSON.stringify(body);
145
151
  logDebug(`Making request out to ${url} with body: ${bodyStr}`);
146
152
  return connectFetch(url, {
@@ -187,7 +193,61 @@ function getMessage(obj) {
187
193
  }
188
194
 
189
195
  const name = "@firebase/data-connect";
190
- const version = "0.0.3-dataconnect-preview.d986d4bf2";
196
+ const version = "0.1.0";
197
+
198
+ /**
199
+ * @license
200
+ * Copyright 2024 Google LLC
201
+ *
202
+ * Licensed under the Apache License, Version 2.0 (the "License");
203
+ * you may not use this file except in compliance with the License.
204
+ * You may obtain a copy of the License at
205
+ *
206
+ * http://www.apache.org/licenses/LICENSE-2.0
207
+ *
208
+ * Unless required by applicable law or agreed to in writing, software
209
+ * distributed under the License is distributed on an "AS IS" BASIS,
210
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
211
+ * See the License for the specific language governing permissions and
212
+ * limitations under the License.
213
+ */
214
+ /**
215
+ * @internal
216
+ * Abstraction around AppCheck's token fetching capabilities.
217
+ */
218
+ class AppCheckTokenProvider {
219
+ constructor(appName_, appCheckProvider) {
220
+ this.appName_ = appName_;
221
+ this.appCheckProvider = appCheckProvider;
222
+ this.appCheck = appCheckProvider === null || appCheckProvider === void 0 ? void 0 : appCheckProvider.getImmediate({ optional: true });
223
+ if (!this.appCheck) {
224
+ void (appCheckProvider === null || appCheckProvider === void 0 ? void 0 : appCheckProvider.get().then(appCheck => (this.appCheck = appCheck)).catch());
225
+ }
226
+ }
227
+ getToken(forceRefresh) {
228
+ if (!this.appCheck) {
229
+ return new Promise((resolve, reject) => {
230
+ // Support delayed initialization of FirebaseAppCheck. This allows our
231
+ // customers to initialize the RTDB SDK before initializing Firebase
232
+ // AppCheck and ensures that all requests are authenticated if a token
233
+ // becomes available before the timoeout below expires.
234
+ setTimeout(() => {
235
+ if (this.appCheck) {
236
+ this.getToken(forceRefresh).then(resolve, reject);
237
+ }
238
+ else {
239
+ resolve(null);
240
+ }
241
+ }, 0);
242
+ });
243
+ }
244
+ return this.appCheck.getToken(forceRefresh);
245
+ }
246
+ addTokenChangeListener(listener) {
247
+ var _a;
248
+ void ((_a = this.appCheckProvider) === null || _a === void 0 ? void 0 : _a.get().then(appCheck => appCheck.addTokenListener(listener)));
249
+ }
250
+ }
191
251
 
192
252
  /**
193
253
  * @license
@@ -205,6 +265,7 @@ const version = "0.0.3-dataconnect-preview.d986d4bf2";
205
265
  * See the License for the specific language governing permissions and
206
266
  * limitations under the License.
207
267
  */
268
+ // @internal
208
269
  class FirebaseAuthProvider {
209
270
  constructor(_appName, _options, _authProvider) {
210
271
  this._appName = _appName;
@@ -488,7 +549,7 @@ function urlBuilder(projectConfig, transportOptions) {
488
549
  logError('Port type is of an invalid type');
489
550
  throw new DataConnectError(Code.INVALID_ARGUMENT, 'Incorrect type for port passed in!');
490
551
  }
491
- return `${baseUrl}/v1alpha/projects/${project}/locations/${location}/services/${service}/connectors/${connector}`;
552
+ return `${baseUrl}/v1beta/projects/${project}/locations/${location}/services/${service}/connectors/${connector}`;
492
553
  }
493
554
  function addToken(url, apiKey) {
494
555
  if (!apiKey) {
@@ -516,10 +577,12 @@ function addToken(url, apiKey) {
516
577
  * limitations under the License.
517
578
  */
518
579
  class RESTTransport {
519
- constructor(options, apiKey, authProvider, transportOptions, _isUsingGen = false) {
520
- var _a;
580
+ constructor(options, apiKey, appId, authProvider, appCheckProvider, transportOptions, _isUsingGen = false) {
581
+ var _a, _b;
521
582
  this.apiKey = apiKey;
583
+ this.appId = appId;
522
584
  this.authProvider = authProvider;
585
+ this.appCheckProvider = appCheckProvider;
523
586
  this._isUsingGen = _isUsingGen;
524
587
  this._host = '';
525
588
  this._location = 'l';
@@ -527,7 +590,7 @@ class RESTTransport {
527
590
  this._secure = true;
528
591
  this._project = 'p';
529
592
  this._accessToken = null;
530
- this._authInitialized = false;
593
+ this._appCheckToken = null;
531
594
  this._lastToken = null;
532
595
  // TODO(mtewani): Update U to include shape of body defined in line 13.
533
596
  this.invokeQuery = (queryName, body) => {
@@ -538,7 +601,7 @@ class RESTTransport {
538
601
  operationName: queryName,
539
602
  variables: body
540
603
  }, // TODO(mtewani): This is a patch, fix this.
541
- abortController, this._accessToken, this._isUsingGen));
604
+ abortController, this.appId, this._accessToken, this._appCheckToken, this._isUsingGen));
542
605
  return {
543
606
  then: withAuth.then.bind(withAuth),
544
607
  catch: withAuth.catch.bind(withAuth)
@@ -551,7 +614,7 @@ class RESTTransport {
551
614
  name: `projects/${this._project}/locations/${this._location}/services/${this._serviceName}/connectors/${this._connectorName}`,
552
615
  operationName: mutationName,
553
616
  variables: body
554
- }, abortController, this._accessToken, this._isUsingGen);
617
+ }, abortController, this.appId, this._accessToken, this._appCheckToken, this._isUsingGen);
555
618
  });
556
619
  return {
557
620
  then: taskResult.then.bind(taskResult),
@@ -585,6 +648,11 @@ class RESTTransport {
585
648
  logDebug(`New Token Available: ${token}`);
586
649
  this._accessToken = token;
587
650
  });
651
+ (_b = this.appCheckProvider) === null || _b === void 0 ? void 0 : _b.addTokenChangeListener(result => {
652
+ const { token } = result;
653
+ logDebug(`New App Check Token Available: ${token}`);
654
+ this._appCheckToken = token;
655
+ });
588
656
  }
589
657
  get endpointUrl() {
590
658
  return urlBuilder({
@@ -606,23 +674,25 @@ class RESTTransport {
606
674
  onTokenChanged(newToken) {
607
675
  this._accessToken = newToken;
608
676
  }
609
- getWithAuth(forceToken = false) {
677
+ async getWithAuth(forceToken = false) {
678
+ var _a;
610
679
  let starterPromise = new Promise(resolve => resolve(this._accessToken));
611
- if (!this._authInitialized) {
612
- if (this.authProvider) {
613
- starterPromise = this.authProvider
614
- .getToken(/*forceToken=*/ forceToken)
615
- .then(data => {
616
- if (!data) {
617
- return null;
618
- }
619
- this._accessToken = data.accessToken;
620
- return this._accessToken;
621
- });
622
- }
623
- else {
624
- starterPromise = new Promise(resolve => resolve(''));
625
- }
680
+ if (this.appCheckProvider) {
681
+ this._appCheckToken = (_a = (await this.appCheckProvider.getToken())) === null || _a === void 0 ? void 0 : _a.token;
682
+ }
683
+ if (this.authProvider) {
684
+ starterPromise = this.authProvider
685
+ .getToken(/*forceToken=*/ forceToken)
686
+ .then(data => {
687
+ if (!data) {
688
+ return null;
689
+ }
690
+ this._accessToken = data.accessToken;
691
+ return this._accessToken;
692
+ });
693
+ }
694
+ else {
695
+ starterPromise = new Promise(resolve => resolve(''));
626
696
  }
627
697
  return starterPromise;
628
698
  }
@@ -748,14 +818,16 @@ function parseOptions(fullHost) {
748
818
  * Class representing Firebase Data Connect
749
819
  */
750
820
  class DataConnect {
821
+ // @internal
751
822
  constructor(app,
752
823
  // TODO(mtewani): Replace with _dataConnectOptions in the future
753
- dataConnectOptions, _authProvider) {
824
+ dataConnectOptions, _authProvider, _appCheckProvider) {
754
825
  this.app = app;
755
826
  this.dataConnectOptions = dataConnectOptions;
756
827
  this._authProvider = _authProvider;
828
+ this._appCheckProvider = _appCheckProvider;
757
829
  this.isEmulator = false;
758
- this.initialized = false;
830
+ this._initialized = false;
759
831
  this._isUsingGeneratedSdk = false;
760
832
  if (typeof process !== 'undefined' && process.env) {
761
833
  const host = process.env[FIREBASE_DATA_CONNECT_EMULATOR_HOST_VAR];
@@ -766,9 +838,7 @@ class DataConnect {
766
838
  }
767
839
  }
768
840
  }
769
- /*
770
- @internal
771
- */
841
+ // @internal
772
842
  _useGeneratedSdk() {
773
843
  if (!this._isUsingGeneratedSdk) {
774
844
  this._isUsingGeneratedSdk = true;
@@ -778,13 +848,15 @@ class DataConnect {
778
848
  _removeServiceInstance(this.app, 'data-connect', JSON.stringify(this.getSettings()));
779
849
  return Promise.resolve();
780
850
  }
851
+ // @internal
781
852
  getSettings() {
782
853
  const copy = JSON.parse(JSON.stringify(this.dataConnectOptions));
783
854
  delete copy.projectId;
784
855
  return copy;
785
856
  }
857
+ // @internal
786
858
  setInitialized() {
787
- if (this.initialized) {
859
+ if (this._initialized) {
788
860
  return;
789
861
  }
790
862
  if (this._transportClass === undefined) {
@@ -794,16 +866,20 @@ class DataConnect {
794
866
  if (this._authProvider) {
795
867
  this._authTokenProvider = new FirebaseAuthProvider(this.app.name, this.app.options, this._authProvider);
796
868
  }
797
- this.initialized = true;
798
- this._transport = new this._transportClass(this.dataConnectOptions, this.app.options.apiKey, this._authTokenProvider, undefined, this._isUsingGeneratedSdk);
869
+ if (this._appCheckProvider) {
870
+ this._appCheckTokenProvider = new AppCheckTokenProvider(this.app.name, this._appCheckProvider);
871
+ }
872
+ this._initialized = true;
873
+ this._transport = new this._transportClass(this.dataConnectOptions, this.app.options.apiKey, this.app.options.appId, this._authTokenProvider, this._appCheckTokenProvider, undefined, this._isUsingGeneratedSdk);
799
874
  if (this._transportOptions) {
800
875
  this._transport.useEmulator(this._transportOptions.host, this._transportOptions.port, this._transportOptions.sslEnabled);
801
876
  }
802
877
  this._queryManager = new QueryManager(this._transport);
803
878
  this._mutationManager = new MutationManager(this._transport);
804
879
  }
880
+ // @internal
805
881
  enableEmulator(transportOptions) {
806
- if (this.initialized) {
882
+ if (this._initialized) {
807
883
  logError('enableEmulator called after initialization');
808
884
  throw new DataConnectError(Code.ALREADY_INITIALIZED, 'DataConnect instance already initialized!');
809
885
  }
@@ -903,6 +979,7 @@ function registerDataConnect(variant) {
903
979
  _registerComponent(new Component('data-connect', (container, { instanceIdentifier: settings, options }) => {
904
980
  const app = container.getProvider('app').getImmediate();
905
981
  const authProvider = container.getProvider('auth-internal');
982
+ const appCheckProvider = container.getProvider('app-check-internal');
906
983
  let newOpts = options;
907
984
  if (settings) {
908
985
  newOpts = JSON.parse(settings);
@@ -910,7 +987,7 @@ function registerDataConnect(variant) {
910
987
  if (!app.options.projectId) {
911
988
  throw new DataConnectError(Code.INVALID_ARGUMENT, 'Project ID must be provided. Did you pass in a proper projectId to initializeApp?');
912
989
  }
913
- return new DataConnect(app, Object.assign(Object.assign({}, newOpts), { projectId: app.options.projectId }), authProvider);
990
+ return new DataConnect(app, Object.assign(Object.assign({}, newOpts), { projectId: app.options.projectId }), authProvider, appCheckProvider);
914
991
  }, "PUBLIC" /* ComponentType.PUBLIC */).setMultipleInstances(true));
915
992
  registerVersion(name, version, variant);
916
993
  // BUILD_TARGET will be replaced by values like esm5, esm2017, cjs5, etc during the compilation
@@ -1086,5 +1163,5 @@ function subscribe(queryRefOrSerializedResult, observerOrOnNext, onError, onComp
1086
1163
  initializeFetch(fetch);
1087
1164
  registerDataConnect('node');
1088
1165
 
1089
- export { DataConnect, FIREBASE_DATA_CONNECT_EMULATOR_HOST_VAR, FirebaseAuthProvider, MUTATION_STR, MutationManager, QUERY_STR, SOURCE_CACHE, SOURCE_SERVER, connectDataConnectEmulator, executeMutation, executeQuery, getDataConnect, mutationRef, parseOptions, queryRef, setLogLevel, subscribe, terminate, toQueryRef, validateArgs, validateDCOptions };
1166
+ export { DataConnect, MUTATION_STR, MutationManager, QUERY_STR, SOURCE_CACHE, SOURCE_SERVER, connectDataConnectEmulator, executeMutation, executeQuery, getDataConnect, mutationRef, parseOptions, queryRef, setLogLevel, subscribe, terminate, toQueryRef, validateArgs, validateDCOptions };
1090
1167
  //# sourceMappingURL=index.node.esm.js.map