@firebase/data-connect 0.0.2-dataconnect-preview.877f8b7d0 → 0.0.3-dataconnect-preview.d986d4bf2

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 (40) hide show
  1. package/dist/index.cjs.js +204 -29
  2. package/dist/index.cjs.js.map +1 -1
  3. package/dist/index.esm2017.js +203 -30
  4. package/dist/index.esm2017.js.map +1 -1
  5. package/dist/index.esm5.js +204 -25
  6. package/dist/index.esm5.js.map +1 -1
  7. package/dist/index.node.cjs.js +205 -24
  8. package/dist/index.node.cjs.js.map +1 -1
  9. package/dist/internal.d.ts +159 -13
  10. package/dist/node-esm/index.node.esm.js +203 -30
  11. package/dist/node-esm/index.node.esm.js.map +1 -1
  12. package/dist/node-esm/src/api/DataConnect.d.ts +42 -0
  13. package/dist/node-esm/src/api/Mutation.d.ts +26 -1
  14. package/dist/node-esm/src/api/Reference.d.ts +6 -0
  15. package/dist/node-esm/src/api/index.d.ts +1 -0
  16. package/dist/node-esm/src/api/query.d.ts +51 -1
  17. package/dist/node-esm/src/api.browser.d.ts +12 -7
  18. package/dist/node-esm/src/core/FirebaseAuthProvider.d.ts +1 -1
  19. package/dist/node-esm/src/core/QueryManager.d.ts +1 -1
  20. package/dist/node-esm/src/core/error.d.ts +2 -1
  21. package/dist/node-esm/src/network/fetch.d.ts +1 -1
  22. package/dist/node-esm/src/network/transport/index.d.ts +1 -1
  23. package/dist/node-esm/src/network/transport/rest.d.ts +20 -9
  24. package/dist/node-esm/src/util/validateArgs.d.ts +33 -0
  25. package/dist/private.d.ts +141 -19
  26. package/dist/public.d.ts +130 -15
  27. package/dist/src/api/DataConnect.d.ts +42 -0
  28. package/dist/src/api/Mutation.d.ts +26 -1
  29. package/dist/src/api/Reference.d.ts +6 -0
  30. package/dist/src/api/index.d.ts +1 -0
  31. package/dist/src/api/query.d.ts +51 -1
  32. package/dist/src/api.browser.d.ts +12 -7
  33. package/dist/src/core/FirebaseAuthProvider.d.ts +1 -1
  34. package/dist/src/core/QueryManager.d.ts +1 -1
  35. package/dist/src/core/error.d.ts +2 -1
  36. package/dist/src/network/fetch.d.ts +1 -1
  37. package/dist/src/network/transport/index.d.ts +1 -1
  38. package/dist/src/network/transport/rest.d.ts +20 -9
  39. package/dist/src/util/validateArgs.d.ts +33 -0
  40. package/package.json +10 -6
@@ -5,7 +5,7 @@ import { FirebaseError } from '@firebase/util';
5
5
  import { Logger } from '@firebase/logger';
6
6
 
7
7
  var name = "@firebase/data-connect";
8
- var version = "0.0.2-dataconnect-preview.877f8b7d0";
8
+ var version = "0.0.3-dataconnect-preview.d986d4bf2";
9
9
 
10
10
  /**
11
11
  * @license
@@ -55,7 +55,8 @@ var Code = {
55
55
  NOT_INITIALIZED: 'not-initialized',
56
56
  NOT_SUPPORTED: 'not-supported',
57
57
  INVALID_ARGUMENT: 'invalid-argument',
58
- PARTIAL_ERROR: 'partial-error'
58
+ PARTIAL_ERROR: 'partial-error',
59
+ UNAUTHORIZED: 'unauthorized'
59
60
  };
60
61
  /** An error returned by a DataConnect operation. */
61
62
  var DataConnectError = /** @class */ (function (_super) {
@@ -169,7 +170,8 @@ var FirebaseAuthProvider = /** @class */ (function () {
169
170
  FirebaseAuthProvider.prototype.removeTokenChangeListener = function (listener) {
170
171
  this._authProvider
171
172
  .get()
172
- .then(function (auth) { return auth.removeAuthTokenListener(listener); });
173
+ .then(function (auth) { return auth.removeAuthTokenListener(listener); })
174
+ .catch(function (err) { return logError(err); });
173
175
  };
174
176
  return FirebaseAuthProvider;
175
177
  }());
@@ -440,14 +442,22 @@ function addToken(url, apiKey) {
440
442
  * limitations under the License.
441
443
  */
442
444
  var connectFetch = globalThis.fetch;
443
- function dcFetch(url, body, _a, accessToken) {
445
+ function getGoogApiClientValue(_isUsingGen) {
446
+ var str = 'gl-js/ fire/' + SDK_VERSION;
447
+ if (_isUsingGen) {
448
+ str += ' web/gen';
449
+ }
450
+ return str;
451
+ }
452
+ function dcFetch(url, body, _a, accessToken, _isUsingGen) {
444
453
  var _this = this;
445
454
  var signal = _a.signal;
446
455
  if (!connectFetch) {
447
456
  throw new DataConnectError(Code.OTHER, 'No Fetch Implementation detected!');
448
457
  }
449
458
  var headers = {
450
- 'Content-Type': 'application/json'
459
+ 'Content-Type': 'application/json',
460
+ 'X-Goog-Api-Client': getGoogApiClientValue(_isUsingGen)
451
461
  };
452
462
  if (accessToken) {
453
463
  headers['X-Firebase-Auth-Token'] = accessToken;
@@ -459,11 +469,12 @@ function dcFetch(url, body, _a, accessToken) {
459
469
  method: 'POST',
460
470
  headers: headers,
461
471
  signal: signal
462
- }).catch(function (err) {
463
- throw new DataConnectError(Code.OTHER, "Failed to fetch: " + JSON.stringify(err));
472
+ })
473
+ .catch(function (err) {
474
+ throw new DataConnectError(Code.OTHER, 'Failed to fetch: ' + JSON.stringify(err));
464
475
  })
465
476
  .then(function (response) { return __awaiter(_this, void 0, void 0, function () {
466
- var jsonResponse, e_1;
477
+ var jsonResponse, e_1, message;
467
478
  return __generator(this, function (_a) {
468
479
  switch (_a.label) {
469
480
  case 0:
@@ -479,9 +490,13 @@ function dcFetch(url, body, _a, accessToken) {
479
490
  e_1 = _a.sent();
480
491
  throw new DataConnectError(Code.OTHER, JSON.stringify(e_1));
481
492
  case 4:
493
+ message = getMessage(jsonResponse);
482
494
  if (response.status >= 400) {
483
495
  logError('Error while performing request: ' + JSON.stringify(jsonResponse));
484
- throw new DataConnectError(Code.OTHER, JSON.stringify(jsonResponse));
496
+ if (response.status === 401) {
497
+ throw new DataConnectError(Code.UNAUTHORIZED, message);
498
+ }
499
+ throw new DataConnectError(Code.OTHER, message);
485
500
  }
486
501
  return [2 /*return*/, jsonResponse];
487
502
  }
@@ -495,6 +510,12 @@ function dcFetch(url, body, _a, accessToken) {
495
510
  }
496
511
  return res;
497
512
  });
513
+ }
514
+ function getMessage(obj) {
515
+ if ('message' in obj) {
516
+ return obj.message;
517
+ }
518
+ return JSON.stringify(obj);
498
519
  }
499
520
 
500
521
  /**
@@ -514,11 +535,13 @@ function dcFetch(url, body, _a, accessToken) {
514
535
  * limitations under the License.
515
536
  */
516
537
  var RESTTransport = /** @class */ (function () {
517
- function RESTTransport(options, apiKey, authProvider, transportOptions) {
538
+ function RESTTransport(options, apiKey, authProvider, transportOptions, _isUsingGen) {
539
+ if (_isUsingGen === void 0) { _isUsingGen = false; }
518
540
  var _this = this;
519
541
  var _a;
520
542
  this.apiKey = apiKey;
521
543
  this.authProvider = authProvider;
544
+ this._isUsingGen = _isUsingGen;
522
545
  this._host = '';
523
546
  this._location = 'l';
524
547
  this._connectorName = '';
@@ -526,30 +549,32 @@ var RESTTransport = /** @class */ (function () {
526
549
  this._project = 'p';
527
550
  this._accessToken = null;
528
551
  this._authInitialized = false;
552
+ this._lastToken = null;
529
553
  // TODO(mtewani): Update U to include shape of body defined in line 13.
530
554
  this.invokeQuery = function (queryName, body) {
531
555
  var abortController = new AbortController();
532
556
  // TODO(mtewani): Update to proper value
533
- var withAuth = _this.getWithAuth().then(function () {
557
+ var withAuth = _this.withRetry(function () {
534
558
  return dcFetch(addToken("".concat(_this.endpointUrl, ":executeQuery"), _this.apiKey), {
535
559
  name: "projects/".concat(_this._project, "/locations/").concat(_this._location, "/services/").concat(_this._serviceName, "/connectors/").concat(_this._connectorName),
536
560
  operationName: queryName,
537
561
  variables: body
538
562
  }, // TODO(mtewani): This is a patch, fix this.
539
- abortController, _this._accessToken);
563
+ abortController, _this._accessToken, _this._isUsingGen);
540
564
  });
541
565
  return {
542
- then: withAuth.then.bind(withAuth)
566
+ then: withAuth.then.bind(withAuth),
567
+ catch: withAuth.catch.bind(withAuth)
543
568
  };
544
569
  };
545
570
  this.invokeMutation = function (mutationName, body) {
546
571
  var abortController = new AbortController();
547
- var taskResult = _this.getWithAuth().then(function () {
572
+ var taskResult = _this.withRetry(function () {
548
573
  return dcFetch(addToken("".concat(_this.endpointUrl, ":executeMutation"), _this.apiKey), {
549
574
  name: "projects/".concat(_this._project, "/locations/").concat(_this._location, "/services/").concat(_this._serviceName, "/connectors/").concat(_this._connectorName),
550
575
  operationName: mutationName,
551
576
  variables: body
552
- }, abortController, _this._accessToken);
577
+ }, abortController, _this._accessToken, _this._isUsingGen);
553
578
  });
554
579
  return {
555
580
  then: taskResult.then.bind(taskResult),
@@ -608,15 +633,16 @@ var RESTTransport = /** @class */ (function () {
608
633
  RESTTransport.prototype.onTokenChanged = function (newToken) {
609
634
  this._accessToken = newToken;
610
635
  };
611
- RESTTransport.prototype.getWithAuth = function () {
636
+ RESTTransport.prototype.getWithAuth = function (forceToken) {
612
637
  var _this = this;
638
+ if (forceToken === void 0) { forceToken = false; }
613
639
  var starterPromise = new Promise(function (resolve) {
614
640
  return resolve(_this._accessToken);
615
641
  });
616
642
  if (!this._authInitialized) {
617
643
  if (this.authProvider) {
618
644
  starterPromise = this.authProvider
619
- .getToken(/*forceToken=*/ false)
645
+ .getToken(/*forceToken=*/ forceToken)
620
646
  .then(function (data) {
621
647
  if (!data) {
622
648
  return null;
@@ -631,6 +657,32 @@ var RESTTransport = /** @class */ (function () {
631
657
  }
632
658
  return starterPromise;
633
659
  };
660
+ RESTTransport.prototype._setLastToken = function (lastToken) {
661
+ this._lastToken = lastToken;
662
+ };
663
+ RESTTransport.prototype.withRetry = function (promiseFactory, retry) {
664
+ var _this = this;
665
+ if (retry === void 0) { retry = false; }
666
+ var isNewToken = false;
667
+ return this.getWithAuth(retry)
668
+ .then(function (res) {
669
+ isNewToken = _this._lastToken !== res;
670
+ _this._lastToken = res;
671
+ return res;
672
+ })
673
+ .then(promiseFactory)
674
+ .catch(function (err) {
675
+ // Only retry if the result is unauthorized and the last token isn't the same as the new one.
676
+ if ('code' in err &&
677
+ err.code === Code.UNAUTHORIZED &&
678
+ !retry &&
679
+ isNewToken) {
680
+ logDebug('Retrying due to unauthorized');
681
+ return _this.withRetry(promiseFactory, true);
682
+ }
683
+ throw err;
684
+ });
685
+ };
634
686
  return RESTTransport;
635
687
  }());
636
688
 
@@ -650,16 +702,26 @@ var RESTTransport = /** @class */ (function () {
650
702
  * See the License for the specific language governing permissions and
651
703
  * limitations under the License.
652
704
  */
653
- function mutationRef(dcInstance, queryName, variables) {
705
+ /**
706
+ *
707
+ * @param dcInstance Data Connect instance
708
+ * @param mutationName name of mutation
709
+ * @param variables variables to send with mutation
710
+ * @returns `MutationRef`
711
+ */
712
+ function mutationRef(dcInstance, mutationName, variables) {
654
713
  dcInstance.setInitialized();
655
714
  var ref = {
656
715
  dataConnect: dcInstance,
657
- name: queryName,
716
+ name: mutationName,
658
717
  refType: MUTATION_STR,
659
718
  variables: variables
660
719
  };
661
720
  return ref;
662
721
  }
722
+ /**
723
+ * @internal
724
+ */
663
725
  var MutationManager = /** @class */ (function () {
664
726
  function MutationManager(_transport) {
665
727
  this._transport = _transport;
@@ -681,6 +743,11 @@ var MutationManager = /** @class */ (function () {
681
743
  };
682
744
  return MutationManager;
683
745
  }());
746
+ /**
747
+ * Execute Mutation
748
+ * @param mutationRef mutation to execute
749
+ * @returns `MutationRef`
750
+ */
684
751
  function executeMutation(mutationRef) {
685
752
  return mutationRef.dataConnect._mutationManager.executeMutation(mutationRef);
686
753
  }
@@ -715,6 +782,9 @@ function parseOptions(fullHost) {
715
782
  var port = Number(portAsString);
716
783
  return { host: host, port: port, sslEnabled: isSecure };
717
784
  }
785
+ /**
786
+ * Class representing Firebase Data Connect
787
+ */
718
788
  var DataConnect = /** @class */ (function () {
719
789
  function DataConnect(app,
720
790
  // TODO(mtewani): Replace with _dataConnectOptions in the future
@@ -724,6 +794,7 @@ var DataConnect = /** @class */ (function () {
724
794
  this._authProvider = _authProvider;
725
795
  this.isEmulator = false;
726
796
  this.initialized = false;
797
+ this._isUsingGeneratedSdk = false;
727
798
  if (typeof process !== 'undefined' && process.env) {
728
799
  var host = process.env[FIREBASE_DATA_CONNECT_EMULATOR_HOST_VAR];
729
800
  if (host) {
@@ -733,6 +804,14 @@ var DataConnect = /** @class */ (function () {
733
804
  }
734
805
  }
735
806
  }
807
+ /*
808
+ @internal
809
+ */
810
+ DataConnect.prototype._useGeneratedSdk = function () {
811
+ if (!this._isUsingGeneratedSdk) {
812
+ this._isUsingGeneratedSdk = true;
813
+ }
814
+ };
736
815
  DataConnect.prototype._delete = function () {
737
816
  _removeServiceInstance(this.app, 'data-connect', JSON.stringify(this.getSettings()));
738
817
  return Promise.resolve();
@@ -754,7 +833,7 @@ var DataConnect = /** @class */ (function () {
754
833
  this._authTokenProvider = new FirebaseAuthProvider(this.app.name, this.app.options, this._authProvider);
755
834
  }
756
835
  this.initialized = true;
757
- this._transport = new this._transportClass(this.dataConnectOptions, this.app.options.apiKey, this._authTokenProvider);
836
+ this._transport = new this._transportClass(this.dataConnectOptions, this.app.options.apiKey, this._authTokenProvider, undefined, this._isUsingGeneratedSdk);
758
837
  if (this._transportOptions) {
759
838
  this._transport.useEmulator(this._transportOptions.host, this._transportOptions.port, this._transportOptions.sslEnabled);
760
839
  }
@@ -771,6 +850,13 @@ var DataConnect = /** @class */ (function () {
771
850
  };
772
851
  return DataConnect;
773
852
  }());
853
+ /**
854
+ * Connect to the DataConnect Emulator
855
+ * @param dc Data Connect instance
856
+ * @param host host of emulator server
857
+ * @param port port of emulator server
858
+ * @param sslEnabled use https
859
+ */
774
860
  function connectDataConnectEmulator(dc, host, port, sslEnabled) {
775
861
  if (sslEnabled === void 0) { sslEnabled = false; }
776
862
  dc.enableEmulator({ host: host, port: port, sslEnabled: sslEnabled });
@@ -786,7 +872,7 @@ function getDataConnect(appOrOptions, optionalOptions) {
786
872
  dcOptions = optionalOptions;
787
873
  app = appOrOptions;
788
874
  }
789
- if (!app) {
875
+ if (!app || Object.keys(app).length === 0) {
790
876
  app = getApp();
791
877
  }
792
878
  var provider = _getProvider(app, 'data-connect');
@@ -800,9 +886,7 @@ function getDataConnect(appOrOptions, optionalOptions) {
800
886
  return dcInstance;
801
887
  }
802
888
  }
803
- if (!dcOptions) {
804
- throw new DataConnectError(Code.INVALID_ARGUMENT, 'DC Option Required');
805
- }
889
+ validateDCOptions(dcOptions);
806
890
  logDebug('Creating new DataConnect instance');
807
891
  // Initialize with options.
808
892
  return provider.initialize({
@@ -810,6 +894,29 @@ function getDataConnect(appOrOptions, optionalOptions) {
810
894
  options: dcOptions
811
895
  });
812
896
  }
897
+ /**
898
+ *
899
+ * @param dcOptions
900
+ * @returns {void}
901
+ * @internal
902
+ */
903
+ function validateDCOptions(dcOptions) {
904
+ var fields = ['connector', 'location', 'service'];
905
+ if (!dcOptions) {
906
+ throw new DataConnectError(Code.INVALID_ARGUMENT, 'DC Option Required');
907
+ }
908
+ fields.forEach(function (field) {
909
+ if (dcOptions[field] === null || dcOptions[field] === undefined) {
910
+ throw new DataConnectError(Code.INVALID_ARGUMENT, "".concat(field, " Required"));
911
+ }
912
+ });
913
+ return true;
914
+ }
915
+ /**
916
+ * Delete DataConnect instance
917
+ * @param dataConnect DataConnect instance
918
+ * @returns
919
+ */
813
920
  function terminate(dataConnect) {
814
921
  return dataConnect._delete();
815
922
  // TODO(mtewani): Stop pending tasks
@@ -825,6 +932,9 @@ function registerDataConnect(variant) {
825
932
  if (settings) {
826
933
  newOpts = JSON.parse(settings);
827
934
  }
935
+ if (!app.options.projectId) {
936
+ throw new DataConnectError(Code.INVALID_ARGUMENT, 'Project ID must be provided. Did you pass in a proper projectId to initializeApp?');
937
+ }
828
938
  return new DataConnect(app, __assign(__assign({}, newOpts), { projectId: app.options.projectId }), authProvider);
829
939
  }, "PUBLIC" /* ComponentType.PUBLIC */).setMultipleInstances(true));
830
940
  registerVersion(name, version, variant);
@@ -848,9 +958,22 @@ function registerDataConnect(variant) {
848
958
  * See the License for the specific language governing permissions and
849
959
  * limitations under the License.
850
960
  */
961
+ /**
962
+ * Execute Query
963
+ * @param queryRef query to execute.
964
+ * @returns `QueryPromise`
965
+ */
851
966
  function executeQuery(queryRef) {
852
967
  return queryRef.dataConnect._queryManager.executeQuery(queryRef);
853
968
  }
969
+ /**
970
+ * Execute Query
971
+ * @param dcInstance Data Connect instance to use.
972
+ * @param queryName Query to execute
973
+ * @param variables Variables to execute with
974
+ * @param initialCache initial cache to use for client hydration
975
+ * @returns `QueryRef`
976
+ */
854
977
  function queryRef(dcInstance, queryName, variables, initialCache) {
855
978
  dcInstance.setInitialized();
856
979
  dcInstance._queryManager.track(queryName, variables, initialCache);
@@ -861,6 +984,11 @@ function queryRef(dcInstance, queryName, variables, initialCache) {
861
984
  variables: variables
862
985
  };
863
986
  }
987
+ /**
988
+ * Converts serialized ref to query ref
989
+ * @param serializedRef ref to convert to `QueryRef`
990
+ * @returns `QueryRef`
991
+ */
864
992
  function toQueryRef(serializedRef) {
865
993
  var _a = serializedRef.refInfo, name = _a.name, variables = _a.variables, connectorConfig = _a.connectorConfig;
866
994
  return queryRef(getDataConnect(connectorConfig), name, variables);
@@ -882,6 +1010,57 @@ function toQueryRef(serializedRef) {
882
1010
  * See the License for the specific language governing permissions and
883
1011
  * limitations under the License.
884
1012
  */
1013
+ /**
1014
+ * The generated SDK will allow the user to pass in either the variable or the data connect instance with the variable,
1015
+ * and this function validates the variables and returns back the DataConnect instance and variables based on the arguments passed in.
1016
+ * @param connectorConfig
1017
+ * @param dcOrVars
1018
+ * @param vars
1019
+ * @param validateVars
1020
+ * @returns {DataConnect} and {Variables} instance
1021
+ * @internal
1022
+ */
1023
+ function validateArgs(connectorConfig, dcOrVars, vars, validateVars) {
1024
+ var dcInstance;
1025
+ var realVars;
1026
+ if (dcOrVars && 'enableEmulator' in dcOrVars) {
1027
+ dcInstance = dcOrVars;
1028
+ realVars = vars;
1029
+ }
1030
+ else {
1031
+ dcInstance = getDataConnect(connectorConfig);
1032
+ realVars = dcOrVars;
1033
+ }
1034
+ if (!dcInstance || (!realVars && validateVars)) {
1035
+ throw new DataConnectError(Code.INVALID_ARGUMENT, 'Variables required.');
1036
+ }
1037
+ return { dc: dcInstance, vars: realVars };
1038
+ }
1039
+
1040
+ /**
1041
+ * @license
1042
+ * Copyright 2024 Google LLC
1043
+ *
1044
+ * Licensed under the Apache License, Version 2.0 (the "License");
1045
+ * you may not use this file except in compliance with the License.
1046
+ * You may obtain a copy of the License at
1047
+ *
1048
+ * http://www.apache.org/licenses/LICENSE-2.0
1049
+ *
1050
+ * Unless required by applicable law or agreed to in writing, software
1051
+ * distributed under the License is distributed on an "AS IS" BASIS,
1052
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1053
+ * See the License for the specific language governing permissions and
1054
+ * limitations under the License.
1055
+ */
1056
+ /**
1057
+ * Subscribe to a `QueryRef`
1058
+ * @param queryRefOrSerializedResult query ref or serialized result.
1059
+ * @param observerOrOnNext observer object or next function.
1060
+ * @param onError Callback to call when error gets thrown.
1061
+ * @param onComplete Called when subscription completes.
1062
+ * @returns `SubscriptionOptions`
1063
+ */
885
1064
  function subscribe(queryRefOrSerializedResult, observerOrOnNext, onError, onComplete) {
886
1065
  var ref;
887
1066
  var initialCache;
@@ -920,5 +1099,5 @@ function subscribe(queryRefOrSerializedResult, observerOrOnNext, onError, onComp
920
1099
  */
921
1100
  registerDataConnect();
922
1101
 
923
- 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 };
1102
+ 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 };
924
1103
  //# sourceMappingURL=index.esm5.js.map