@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.
package/dist/index.cjs.js CHANGED
@@ -8,7 +8,7 @@ var util = require('@firebase/util');
8
8
  var logger$1 = require('@firebase/logger');
9
9
 
10
10
  const name = "@firebase/data-connect";
11
- const version = "0.0.3-dataconnect-preview.d986d4bf2";
11
+ const version = "0.1.0";
12
12
 
13
13
  /**
14
14
  * @license
@@ -36,6 +36,60 @@ function setSDKVersion(version) {
36
36
  SDK_VERSION = version;
37
37
  }
38
38
 
39
+ /**
40
+ * @license
41
+ * Copyright 2024 Google LLC
42
+ *
43
+ * Licensed under the Apache License, Version 2.0 (the "License");
44
+ * you may not use this file except in compliance with the License.
45
+ * You may obtain a copy of the License at
46
+ *
47
+ * http://www.apache.org/licenses/LICENSE-2.0
48
+ *
49
+ * Unless required by applicable law or agreed to in writing, software
50
+ * distributed under the License is distributed on an "AS IS" BASIS,
51
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
52
+ * See the License for the specific language governing permissions and
53
+ * limitations under the License.
54
+ */
55
+ /**
56
+ * @internal
57
+ * Abstraction around AppCheck's token fetching capabilities.
58
+ */
59
+ class AppCheckTokenProvider {
60
+ constructor(appName_, appCheckProvider) {
61
+ this.appName_ = appName_;
62
+ this.appCheckProvider = appCheckProvider;
63
+ this.appCheck = appCheckProvider === null || appCheckProvider === void 0 ? void 0 : appCheckProvider.getImmediate({ optional: true });
64
+ if (!this.appCheck) {
65
+ void (appCheckProvider === null || appCheckProvider === void 0 ? void 0 : appCheckProvider.get().then(appCheck => (this.appCheck = appCheck)).catch());
66
+ }
67
+ }
68
+ getToken(forceRefresh) {
69
+ if (!this.appCheck) {
70
+ return new Promise((resolve, reject) => {
71
+ // Support delayed initialization of FirebaseAppCheck. This allows our
72
+ // customers to initialize the RTDB SDK before initializing Firebase
73
+ // AppCheck and ensures that all requests are authenticated if a token
74
+ // becomes available before the timoeout below expires.
75
+ setTimeout(() => {
76
+ if (this.appCheck) {
77
+ this.getToken(forceRefresh).then(resolve, reject);
78
+ }
79
+ else {
80
+ resolve(null);
81
+ }
82
+ }, 0);
83
+ });
84
+ }
85
+ return this.appCheck.getToken(forceRefresh);
86
+ }
87
+ addTokenChangeListener(listener) {
88
+ var _a;
89
+ void ((_a = this.appCheckProvider) === null || _a === void 0 ? void 0 : _a.get().then(appCheck => appCheck.addTokenListener(listener)));
90
+ }
91
+ }
92
+
39
93
  /**
40
94
  * @license
41
95
  * Copyright 2024 Google LLC
@@ -126,6 +180,7 @@ function logError(msg) {
126
180
  * See the License for the specific language governing permissions and
127
181
  * limitations under the License.
128
182
  */
183
+ // @internal
129
184
  class FirebaseAuthProvider {
130
185
  constructor(_appName, _options, _authProvider) {
131
186
  this._appName = _appName;
@@ -409,7 +464,7 @@ function urlBuilder(projectConfig, transportOptions) {
409
464
  logError('Port type is of an invalid type');
410
465
  throw new DataConnectError(Code.INVALID_ARGUMENT, 'Incorrect type for port passed in!');
411
466
  }
412
- return `${baseUrl}/v1alpha/projects/${project}/locations/${location}/services/${service}/connectors/${connector}`;
467
+ return `${baseUrl}/v1beta/projects/${project}/locations/${location}/services/${service}/connectors/${connector}`;
413
468
  }
414
469
  function addToken(url, apiKey) {
415
470
  if (!apiKey) {
@@ -444,7 +499,7 @@ function getGoogApiClientValue(_isUsingGen) {
444
499
  }
445
500
  return str;
446
501
  }
447
- function dcFetch(url, body, { signal }, accessToken, _isUsingGen) {
502
+ function dcFetch(url, body, { signal }, appId, accessToken, appCheckToken, _isUsingGen) {
448
503
  if (!connectFetch) {
449
504
  throw new DataConnectError(Code.OTHER, 'No Fetch Implementation detected!');
450
505
  }
@@ -455,6 +510,12 @@ function dcFetch(url, body, { signal }, accessToken, _isUsingGen) {
455
510
  if (accessToken) {
456
511
  headers['X-Firebase-Auth-Token'] = accessToken;
457
512
  }
513
+ if (appId) {
514
+ headers['x-firebase-gmpid'] = appId;
515
+ }
516
+ if (appCheckToken) {
517
+ headers['X-Firebase-AppCheck'] = appCheckToken;
518
+ }
458
519
  const bodyStr = JSON.stringify(body);
459
520
  logDebug(`Making request out to ${url} with body: ${bodyStr}`);
460
521
  return connectFetch(url, {
@@ -517,10 +578,12 @@ function getMessage(obj) {
517
578
  * limitations under the License.
518
579
  */
519
580
  class RESTTransport {
520
- constructor(options, apiKey, authProvider, transportOptions, _isUsingGen = false) {
521
- var _a;
581
+ constructor(options, apiKey, appId, authProvider, appCheckProvider, transportOptions, _isUsingGen = false) {
582
+ var _a, _b;
522
583
  this.apiKey = apiKey;
584
+ this.appId = appId;
523
585
  this.authProvider = authProvider;
586
+ this.appCheckProvider = appCheckProvider;
524
587
  this._isUsingGen = _isUsingGen;
525
588
  this._host = '';
526
589
  this._location = 'l';
@@ -528,7 +591,7 @@ class RESTTransport {
528
591
  this._secure = true;
529
592
  this._project = 'p';
530
593
  this._accessToken = null;
531
- this._authInitialized = false;
594
+ this._appCheckToken = null;
532
595
  this._lastToken = null;
533
596
  // TODO(mtewani): Update U to include shape of body defined in line 13.
534
597
  this.invokeQuery = (queryName, body) => {
@@ -539,7 +602,7 @@ class RESTTransport {
539
602
  operationName: queryName,
540
603
  variables: body
541
604
  }, // TODO(mtewani): This is a patch, fix this.
542
- abortController, this._accessToken, this._isUsingGen));
605
+ abortController, this.appId, this._accessToken, this._appCheckToken, this._isUsingGen));
543
606
  return {
544
607
  then: withAuth.then.bind(withAuth),
545
608
  catch: withAuth.catch.bind(withAuth)
@@ -552,7 +615,7 @@ class RESTTransport {
552
615
  name: `projects/${this._project}/locations/${this._location}/services/${this._serviceName}/connectors/${this._connectorName}`,
553
616
  operationName: mutationName,
554
617
  variables: body
555
- }, abortController, this._accessToken, this._isUsingGen);
618
+ }, abortController, this.appId, this._accessToken, this._appCheckToken, this._isUsingGen);
556
619
  });
557
620
  return {
558
621
  then: taskResult.then.bind(taskResult),
@@ -586,6 +649,11 @@ class RESTTransport {
586
649
  logDebug(`New Token Available: ${token}`);
587
650
  this._accessToken = token;
588
651
  });
652
+ (_b = this.appCheckProvider) === null || _b === void 0 ? void 0 : _b.addTokenChangeListener(result => {
653
+ const { token } = result;
654
+ logDebug(`New App Check Token Available: ${token}`);
655
+ this._appCheckToken = token;
656
+ });
589
657
  }
590
658
  get endpointUrl() {
591
659
  return urlBuilder({
@@ -607,23 +675,25 @@ class RESTTransport {
607
675
  onTokenChanged(newToken) {
608
676
  this._accessToken = newToken;
609
677
  }
610
- getWithAuth(forceToken = false) {
678
+ async getWithAuth(forceToken = false) {
679
+ var _a;
611
680
  let starterPromise = new Promise(resolve => resolve(this._accessToken));
612
- if (!this._authInitialized) {
613
- if (this.authProvider) {
614
- starterPromise = this.authProvider
615
- .getToken(/*forceToken=*/ forceToken)
616
- .then(data => {
617
- if (!data) {
618
- return null;
619
- }
620
- this._accessToken = data.accessToken;
621
- return this._accessToken;
622
- });
623
- }
624
- else {
625
- starterPromise = new Promise(resolve => resolve(''));
626
- }
681
+ if (this.appCheckProvider) {
682
+ this._appCheckToken = (_a = (await this.appCheckProvider.getToken())) === null || _a === void 0 ? void 0 : _a.token;
683
+ }
684
+ if (this.authProvider) {
685
+ starterPromise = this.authProvider
686
+ .getToken(/*forceToken=*/ forceToken)
687
+ .then(data => {
688
+ if (!data) {
689
+ return null;
690
+ }
691
+ this._accessToken = data.accessToken;
692
+ return this._accessToken;
693
+ });
694
+ }
695
+ else {
696
+ starterPromise = new Promise(resolve => resolve(''));
627
697
  }
628
698
  return starterPromise;
629
699
  }
@@ -749,14 +819,16 @@ function parseOptions(fullHost) {
749
819
  * Class representing Firebase Data Connect
750
820
  */
751
821
  class DataConnect {
822
+ // @internal
752
823
  constructor(app,
753
824
  // TODO(mtewani): Replace with _dataConnectOptions in the future
754
- dataConnectOptions, _authProvider) {
825
+ dataConnectOptions, _authProvider, _appCheckProvider) {
755
826
  this.app = app;
756
827
  this.dataConnectOptions = dataConnectOptions;
757
828
  this._authProvider = _authProvider;
829
+ this._appCheckProvider = _appCheckProvider;
758
830
  this.isEmulator = false;
759
- this.initialized = false;
831
+ this._initialized = false;
760
832
  this._isUsingGeneratedSdk = false;
761
833
  if (typeof process !== 'undefined' && process.env) {
762
834
  const host = process.env[FIREBASE_DATA_CONNECT_EMULATOR_HOST_VAR];
@@ -767,9 +839,7 @@ class DataConnect {
767
839
  }
768
840
  }
769
841
  }
770
- /*
771
- @internal
772
- */
842
+ // @internal
773
843
  _useGeneratedSdk() {
774
844
  if (!this._isUsingGeneratedSdk) {
775
845
  this._isUsingGeneratedSdk = true;
@@ -779,13 +849,15 @@ class DataConnect {
779
849
  app._removeServiceInstance(this.app, 'data-connect', JSON.stringify(this.getSettings()));
780
850
  return Promise.resolve();
781
851
  }
852
+ // @internal
782
853
  getSettings() {
783
854
  const copy = JSON.parse(JSON.stringify(this.dataConnectOptions));
784
855
  delete copy.projectId;
785
856
  return copy;
786
857
  }
858
+ // @internal
787
859
  setInitialized() {
788
- if (this.initialized) {
860
+ if (this._initialized) {
789
861
  return;
790
862
  }
791
863
  if (this._transportClass === undefined) {
@@ -795,16 +867,20 @@ class DataConnect {
795
867
  if (this._authProvider) {
796
868
  this._authTokenProvider = new FirebaseAuthProvider(this.app.name, this.app.options, this._authProvider);
797
869
  }
798
- this.initialized = true;
799
- this._transport = new this._transportClass(this.dataConnectOptions, this.app.options.apiKey, this._authTokenProvider, undefined, this._isUsingGeneratedSdk);
870
+ if (this._appCheckProvider) {
871
+ this._appCheckTokenProvider = new AppCheckTokenProvider(this.app.name, this._appCheckProvider);
872
+ }
873
+ this._initialized = true;
874
+ this._transport = new this._transportClass(this.dataConnectOptions, this.app.options.apiKey, this.app.options.appId, this._authTokenProvider, this._appCheckTokenProvider, undefined, this._isUsingGeneratedSdk);
800
875
  if (this._transportOptions) {
801
876
  this._transport.useEmulator(this._transportOptions.host, this._transportOptions.port, this._transportOptions.sslEnabled);
802
877
  }
803
878
  this._queryManager = new QueryManager(this._transport);
804
879
  this._mutationManager = new MutationManager(this._transport);
805
880
  }
881
+ // @internal
806
882
  enableEmulator(transportOptions) {
807
- if (this.initialized) {
883
+ if (this._initialized) {
808
884
  logError('enableEmulator called after initialization');
809
885
  throw new DataConnectError(Code.ALREADY_INITIALIZED, 'DataConnect instance already initialized!');
810
886
  }
@@ -904,6 +980,7 @@ function registerDataConnect(variant) {
904
980
  app._registerComponent(new component.Component('data-connect', (container, { instanceIdentifier: settings, options }) => {
905
981
  const app = container.getProvider('app').getImmediate();
906
982
  const authProvider = container.getProvider('auth-internal');
983
+ const appCheckProvider = container.getProvider('app-check-internal');
907
984
  let newOpts = options;
908
985
  if (settings) {
909
986
  newOpts = JSON.parse(settings);
@@ -911,7 +988,7 @@ function registerDataConnect(variant) {
911
988
  if (!app.options.projectId) {
912
989
  throw new DataConnectError(Code.INVALID_ARGUMENT, 'Project ID must be provided. Did you pass in a proper projectId to initializeApp?');
913
990
  }
914
- return new DataConnect(app, Object.assign(Object.assign({}, newOpts), { projectId: app.options.projectId }), authProvider);
991
+ return new DataConnect(app, Object.assign(Object.assign({}, newOpts), { projectId: app.options.projectId }), authProvider, appCheckProvider);
915
992
  }, "PUBLIC" /* ComponentType.PUBLIC */).setMultipleInstances(true));
916
993
  app.registerVersion(name, version, variant);
917
994
  // BUILD_TARGET will be replaced by values like esm5, esm2017, cjs5, etc during the compilation
@@ -1076,8 +1153,6 @@ function subscribe(queryRefOrSerializedResult, observerOrOnNext, onError, onComp
1076
1153
  registerDataConnect();
1077
1154
 
1078
1155
  exports.DataConnect = DataConnect;
1079
- exports.FIREBASE_DATA_CONNECT_EMULATOR_HOST_VAR = FIREBASE_DATA_CONNECT_EMULATOR_HOST_VAR;
1080
- exports.FirebaseAuthProvider = FirebaseAuthProvider;
1081
1156
  exports.MUTATION_STR = MUTATION_STR;
1082
1157
  exports.MutationManager = MutationManager;
1083
1158
  exports.QUERY_STR = QUERY_STR;