@firebase/data-connect 0.0.2-dataconnect-preview.388b61c7e → 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 (34) hide show
  1. package/dist/index.cjs.js +146 -27
  2. package/dist/index.cjs.js.map +1 -1
  3. package/dist/index.esm2017.js +145 -28
  4. package/dist/index.esm2017.js.map +1 -1
  5. package/dist/index.esm5.js +146 -23
  6. package/dist/index.esm5.js.map +1 -1
  7. package/dist/index.node.cjs.js +147 -22
  8. package/dist/index.node.cjs.js.map +1 -1
  9. package/dist/internal.d.ts +32 -5
  10. package/dist/node-esm/index.node.esm.js +145 -28
  11. package/dist/node-esm/index.node.esm.js.map +1 -1
  12. package/dist/node-esm/src/api/DataConnect.d.ts +9 -0
  13. package/dist/node-esm/src/api/index.d.ts +1 -0
  14. package/dist/node-esm/src/api/query.d.ts +1 -1
  15. package/dist/node-esm/src/core/FirebaseAuthProvider.d.ts +1 -1
  16. package/dist/node-esm/src/core/QueryManager.d.ts +1 -1
  17. package/dist/node-esm/src/core/error.d.ts +2 -1
  18. package/dist/node-esm/src/network/fetch.d.ts +1 -1
  19. package/dist/node-esm/src/network/transport/index.d.ts +1 -1
  20. package/dist/node-esm/src/network/transport/rest.d.ts +20 -9
  21. package/dist/node-esm/src/util/validateArgs.d.ts +33 -0
  22. package/dist/private.d.ts +16 -5
  23. package/dist/public.d.ts +5 -3
  24. package/dist/src/api/DataConnect.d.ts +9 -0
  25. package/dist/src/api/index.d.ts +1 -0
  26. package/dist/src/api/query.d.ts +1 -1
  27. package/dist/src/core/FirebaseAuthProvider.d.ts +1 -1
  28. package/dist/src/core/QueryManager.d.ts +1 -1
  29. package/dist/src/core/error.d.ts +2 -1
  30. package/dist/src/network/fetch.d.ts +1 -1
  31. package/dist/src/network/transport/index.d.ts +1 -1
  32. package/dist/src/network/transport/rest.d.ts +20 -9
  33. package/dist/src/util/validateArgs.d.ts +33 -0
  34. package/package.json +10 -6
@@ -30,7 +30,8 @@ var Code = {
30
30
  NOT_INITIALIZED: 'not-initialized',
31
31
  NOT_SUPPORTED: 'not-supported',
32
32
  INVALID_ARGUMENT: 'invalid-argument',
33
- PARTIAL_ERROR: 'partial-error'
33
+ PARTIAL_ERROR: 'partial-error',
34
+ UNAUTHORIZED: 'unauthorized'
34
35
  };
35
36
  /** An error returned by a DataConnect operation. */
36
37
  var DataConnectError = /** @class */ (function (_super) {
@@ -130,14 +131,22 @@ var connectFetch = globalThis.fetch;
130
131
  function initializeFetch(fetchImpl) {
131
132
  connectFetch = fetchImpl;
132
133
  }
133
- function dcFetch(url, body, _a, accessToken) {
134
+ function getGoogApiClientValue(_isUsingGen) {
135
+ var str = 'gl-js/ fire/' + SDK_VERSION;
136
+ if (_isUsingGen) {
137
+ str += ' web/gen';
138
+ }
139
+ return str;
140
+ }
141
+ function dcFetch(url, body, _a, accessToken, _isUsingGen) {
134
142
  var _this = this;
135
143
  var signal = _a.signal;
136
144
  if (!connectFetch) {
137
145
  throw new DataConnectError(Code.OTHER, 'No Fetch Implementation detected!');
138
146
  }
139
147
  var headers = {
140
- 'Content-Type': 'application/json'
148
+ 'Content-Type': 'application/json',
149
+ 'X-Goog-Api-Client': getGoogApiClientValue(_isUsingGen)
141
150
  };
142
151
  if (accessToken) {
143
152
  headers['X-Firebase-Auth-Token'] = accessToken;
@@ -149,11 +158,12 @@ function dcFetch(url, body, _a, accessToken) {
149
158
  method: 'POST',
150
159
  headers: headers,
151
160
  signal: signal
152
- }).catch(function (err) {
153
- throw new DataConnectError(Code.OTHER, "Failed to fetch: " + JSON.stringify(err));
161
+ })
162
+ .catch(function (err) {
163
+ throw new DataConnectError(Code.OTHER, 'Failed to fetch: ' + JSON.stringify(err));
154
164
  })
155
165
  .then(function (response) { return tslib.__awaiter(_this, void 0, void 0, function () {
156
- var jsonResponse, e_1;
166
+ var jsonResponse, e_1, message;
157
167
  return tslib.__generator(this, function (_a) {
158
168
  switch (_a.label) {
159
169
  case 0:
@@ -169,9 +179,13 @@ function dcFetch(url, body, _a, accessToken) {
169
179
  e_1 = _a.sent();
170
180
  throw new DataConnectError(Code.OTHER, JSON.stringify(e_1));
171
181
  case 4:
182
+ message = getMessage(jsonResponse);
172
183
  if (response.status >= 400) {
173
184
  logError('Error while performing request: ' + JSON.stringify(jsonResponse));
174
- throw new DataConnectError(Code.OTHER, JSON.stringify(jsonResponse));
185
+ if (response.status === 401) {
186
+ throw new DataConnectError(Code.UNAUTHORIZED, message);
187
+ }
188
+ throw new DataConnectError(Code.OTHER, message);
175
189
  }
176
190
  return [2 /*return*/, jsonResponse];
177
191
  }
@@ -185,10 +199,16 @@ function dcFetch(url, body, _a, accessToken) {
185
199
  }
186
200
  return res;
187
201
  });
202
+ }
203
+ function getMessage(obj) {
204
+ if ('message' in obj) {
205
+ return obj.message;
206
+ }
207
+ return JSON.stringify(obj);
188
208
  }
189
209
 
190
210
  var name = "@firebase/data-connect";
191
- var version = "0.0.2-dataconnect-preview.388b61c7e";
211
+ var version = "0.0.3-dataconnect-preview.d986d4bf2";
192
212
 
193
213
  /**
194
214
  * @license
@@ -250,7 +270,8 @@ var FirebaseAuthProvider = /** @class */ (function () {
250
270
  FirebaseAuthProvider.prototype.removeTokenChangeListener = function (listener) {
251
271
  this._authProvider
252
272
  .get()
253
- .then(function (auth) { return auth.removeAuthTokenListener(listener); });
273
+ .then(function (auth) { return auth.removeAuthTokenListener(listener); })
274
+ .catch(function (err) { return logError(err); });
254
275
  };
255
276
  return FirebaseAuthProvider;
256
277
  }());
@@ -521,11 +542,13 @@ function addToken(url, apiKey) {
521
542
  * limitations under the License.
522
543
  */
523
544
  var RESTTransport = /** @class */ (function () {
524
- function RESTTransport(options, apiKey, authProvider, transportOptions) {
545
+ function RESTTransport(options, apiKey, authProvider, transportOptions, _isUsingGen) {
546
+ if (_isUsingGen === void 0) { _isUsingGen = false; }
525
547
  var _this = this;
526
548
  var _a;
527
549
  this.apiKey = apiKey;
528
550
  this.authProvider = authProvider;
551
+ this._isUsingGen = _isUsingGen;
529
552
  this._host = '';
530
553
  this._location = 'l';
531
554
  this._connectorName = '';
@@ -533,30 +556,32 @@ var RESTTransport = /** @class */ (function () {
533
556
  this._project = 'p';
534
557
  this._accessToken = null;
535
558
  this._authInitialized = false;
559
+ this._lastToken = null;
536
560
  // TODO(mtewani): Update U to include shape of body defined in line 13.
537
561
  this.invokeQuery = function (queryName, body) {
538
562
  var abortController = new AbortController();
539
563
  // TODO(mtewani): Update to proper value
540
- var withAuth = _this.getWithAuth().then(function () {
564
+ var withAuth = _this.withRetry(function () {
541
565
  return dcFetch(addToken("".concat(_this.endpointUrl, ":executeQuery"), _this.apiKey), {
542
566
  name: "projects/".concat(_this._project, "/locations/").concat(_this._location, "/services/").concat(_this._serviceName, "/connectors/").concat(_this._connectorName),
543
567
  operationName: queryName,
544
568
  variables: body
545
569
  }, // TODO(mtewani): This is a patch, fix this.
546
- abortController, _this._accessToken);
570
+ abortController, _this._accessToken, _this._isUsingGen);
547
571
  });
548
572
  return {
549
- then: withAuth.then.bind(withAuth)
573
+ then: withAuth.then.bind(withAuth),
574
+ catch: withAuth.catch.bind(withAuth)
550
575
  };
551
576
  };
552
577
  this.invokeMutation = function (mutationName, body) {
553
578
  var abortController = new AbortController();
554
- var taskResult = _this.getWithAuth().then(function () {
579
+ var taskResult = _this.withRetry(function () {
555
580
  return dcFetch(addToken("".concat(_this.endpointUrl, ":executeMutation"), _this.apiKey), {
556
581
  name: "projects/".concat(_this._project, "/locations/").concat(_this._location, "/services/").concat(_this._serviceName, "/connectors/").concat(_this._connectorName),
557
582
  operationName: mutationName,
558
583
  variables: body
559
- }, abortController, _this._accessToken);
584
+ }, abortController, _this._accessToken, _this._isUsingGen);
560
585
  });
561
586
  return {
562
587
  then: taskResult.then.bind(taskResult),
@@ -615,15 +640,16 @@ var RESTTransport = /** @class */ (function () {
615
640
  RESTTransport.prototype.onTokenChanged = function (newToken) {
616
641
  this._accessToken = newToken;
617
642
  };
618
- RESTTransport.prototype.getWithAuth = function () {
643
+ RESTTransport.prototype.getWithAuth = function (forceToken) {
619
644
  var _this = this;
645
+ if (forceToken === void 0) { forceToken = false; }
620
646
  var starterPromise = new Promise(function (resolve) {
621
647
  return resolve(_this._accessToken);
622
648
  });
623
649
  if (!this._authInitialized) {
624
650
  if (this.authProvider) {
625
651
  starterPromise = this.authProvider
626
- .getToken(/*forceToken=*/ false)
652
+ .getToken(/*forceToken=*/ forceToken)
627
653
  .then(function (data) {
628
654
  if (!data) {
629
655
  return null;
@@ -638,6 +664,32 @@ var RESTTransport = /** @class */ (function () {
638
664
  }
639
665
  return starterPromise;
640
666
  };
667
+ RESTTransport.prototype._setLastToken = function (lastToken) {
668
+ this._lastToken = lastToken;
669
+ };
670
+ RESTTransport.prototype.withRetry = function (promiseFactory, retry) {
671
+ var _this = this;
672
+ if (retry === void 0) { retry = false; }
673
+ var isNewToken = false;
674
+ return this.getWithAuth(retry)
675
+ .then(function (res) {
676
+ isNewToken = _this._lastToken !== res;
677
+ _this._lastToken = res;
678
+ return res;
679
+ })
680
+ .then(promiseFactory)
681
+ .catch(function (err) {
682
+ // Only retry if the result is unauthorized and the last token isn't the same as the new one.
683
+ if ('code' in err &&
684
+ err.code === Code.UNAUTHORIZED &&
685
+ !retry &&
686
+ isNewToken) {
687
+ logDebug('Retrying due to unauthorized');
688
+ return _this.withRetry(promiseFactory, true);
689
+ }
690
+ throw err;
691
+ });
692
+ };
641
693
  return RESTTransport;
642
694
  }());
643
695
 
@@ -749,6 +801,7 @@ var DataConnect = /** @class */ (function () {
749
801
  this._authProvider = _authProvider;
750
802
  this.isEmulator = false;
751
803
  this.initialized = false;
804
+ this._isUsingGeneratedSdk = false;
752
805
  if (typeof process !== 'undefined' && process.env) {
753
806
  var host = process.env[FIREBASE_DATA_CONNECT_EMULATOR_HOST_VAR];
754
807
  if (host) {
@@ -758,6 +811,14 @@ var DataConnect = /** @class */ (function () {
758
811
  }
759
812
  }
760
813
  }
814
+ /*
815
+ @internal
816
+ */
817
+ DataConnect.prototype._useGeneratedSdk = function () {
818
+ if (!this._isUsingGeneratedSdk) {
819
+ this._isUsingGeneratedSdk = true;
820
+ }
821
+ };
761
822
  DataConnect.prototype._delete = function () {
762
823
  app._removeServiceInstance(this.app, 'data-connect', JSON.stringify(this.getSettings()));
763
824
  return Promise.resolve();
@@ -779,7 +840,7 @@ var DataConnect = /** @class */ (function () {
779
840
  this._authTokenProvider = new FirebaseAuthProvider(this.app.name, this.app.options, this._authProvider);
780
841
  }
781
842
  this.initialized = true;
782
- this._transport = new this._transportClass(this.dataConnectOptions, this.app.options.apiKey, this._authTokenProvider);
843
+ this._transport = new this._transportClass(this.dataConnectOptions, this.app.options.apiKey, this._authTokenProvider, undefined, this._isUsingGeneratedSdk);
783
844
  if (this._transportOptions) {
784
845
  this._transport.useEmulator(this._transportOptions.host, this._transportOptions.port, this._transportOptions.sslEnabled);
785
846
  }
@@ -818,7 +879,7 @@ function getDataConnect(appOrOptions, optionalOptions) {
818
879
  dcOptions = optionalOptions;
819
880
  app$1 = appOrOptions;
820
881
  }
821
- if (!app$1) {
882
+ if (!app$1 || Object.keys(app$1).length === 0) {
822
883
  app$1 = app.getApp();
823
884
  }
824
885
  var provider = app._getProvider(app$1, 'data-connect');
@@ -832,9 +893,7 @@ function getDataConnect(appOrOptions, optionalOptions) {
832
893
  return dcInstance;
833
894
  }
834
895
  }
835
- if (!dcOptions) {
836
- throw new DataConnectError(Code.INVALID_ARGUMENT, 'DC Option Required');
837
- }
896
+ validateDCOptions(dcOptions);
838
897
  logDebug('Creating new DataConnect instance');
839
898
  // Initialize with options.
840
899
  return provider.initialize({
@@ -842,6 +901,24 @@ function getDataConnect(appOrOptions, optionalOptions) {
842
901
  options: dcOptions
843
902
  });
844
903
  }
904
+ /**
905
+ *
906
+ * @param dcOptions
907
+ * @returns {void}
908
+ * @internal
909
+ */
910
+ function validateDCOptions(dcOptions) {
911
+ var fields = ['connector', 'location', 'service'];
912
+ if (!dcOptions) {
913
+ throw new DataConnectError(Code.INVALID_ARGUMENT, 'DC Option Required');
914
+ }
915
+ fields.forEach(function (field) {
916
+ if (dcOptions[field] === null || dcOptions[field] === undefined) {
917
+ throw new DataConnectError(Code.INVALID_ARGUMENT, "".concat(field, " Required"));
918
+ }
919
+ });
920
+ return true;
921
+ }
845
922
  /**
846
923
  * Delete DataConnect instance
847
924
  * @param dataConnect DataConnect instance
@@ -862,6 +939,9 @@ function registerDataConnect(variant) {
862
939
  if (settings) {
863
940
  newOpts = JSON.parse(settings);
864
941
  }
942
+ if (!app.options.projectId) {
943
+ throw new DataConnectError(Code.INVALID_ARGUMENT, 'Project ID must be provided. Did you pass in a proper projectId to initializeApp?');
944
+ }
865
945
  return new DataConnect(app, tslib.__assign(tslib.__assign({}, newOpts), { projectId: app.options.projectId }), authProvider);
866
946
  }, "PUBLIC" /* ComponentType.PUBLIC */).setMultipleInstances(true));
867
947
  app.registerVersion(name, version, variant);
@@ -921,6 +1001,49 @@ function toQueryRef(serializedRef) {
921
1001
  return queryRef(getDataConnect(connectorConfig), name, variables);
922
1002
  }
923
1003
 
1004
+ /**
1005
+ * @license
1006
+ * Copyright 2024 Google LLC
1007
+ *
1008
+ * Licensed under the Apache License, Version 2.0 (the "License");
1009
+ * you may not use this file except in compliance with the License.
1010
+ * You may obtain a copy of the License at
1011
+ *
1012
+ * http://www.apache.org/licenses/LICENSE-2.0
1013
+ *
1014
+ * Unless required by applicable law or agreed to in writing, software
1015
+ * distributed under the License is distributed on an "AS IS" BASIS,
1016
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1017
+ * See the License for the specific language governing permissions and
1018
+ * limitations under the License.
1019
+ */
1020
+ /**
1021
+ * The generated SDK will allow the user to pass in either the variable or the data connect instance with the variable,
1022
+ * and this function validates the variables and returns back the DataConnect instance and variables based on the arguments passed in.
1023
+ * @param connectorConfig
1024
+ * @param dcOrVars
1025
+ * @param vars
1026
+ * @param validateVars
1027
+ * @returns {DataConnect} and {Variables} instance
1028
+ * @internal
1029
+ */
1030
+ function validateArgs(connectorConfig, dcOrVars, vars, validateVars) {
1031
+ var dcInstance;
1032
+ var realVars;
1033
+ if (dcOrVars && 'enableEmulator' in dcOrVars) {
1034
+ dcInstance = dcOrVars;
1035
+ realVars = vars;
1036
+ }
1037
+ else {
1038
+ dcInstance = getDataConnect(connectorConfig);
1039
+ realVars = dcOrVars;
1040
+ }
1041
+ if (!dcInstance || (!realVars && validateVars)) {
1042
+ throw new DataConnectError(Code.INVALID_ARGUMENT, 'Variables required.');
1043
+ }
1044
+ return { dc: dcInstance, vars: realVars };
1045
+ }
1046
+
924
1047
  /**
925
1048
  * @license
926
1049
  * Copyright 2024 Google LLC
@@ -1014,4 +1137,6 @@ exports.setLogLevel = setLogLevel;
1014
1137
  exports.subscribe = subscribe;
1015
1138
  exports.terminate = terminate;
1016
1139
  exports.toQueryRef = toQueryRef;
1140
+ exports.validateArgs = validateArgs;
1141
+ exports.validateDCOptions = validateDCOptions;
1017
1142
  //# sourceMappingURL=index.node.cjs.js.map