@firebase/data-connect 0.0.2-dataconnect-preview.388b61c7e → 0.0.3-canary.beaa4dffb

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 (36) hide show
  1. package/dist/index.cjs.js +246 -52
  2. package/dist/index.cjs.js.map +1 -1
  3. package/dist/index.esm2017.js +245 -51
  4. package/dist/index.esm2017.js.map +1 -1
  5. package/dist/index.esm5.js +265 -50
  6. package/dist/index.esm5.js.map +1 -1
  7. package/dist/index.node.cjs.js +266 -51
  8. package/dist/index.node.cjs.js.map +1 -1
  9. package/dist/internal.d.ts +59 -33
  10. package/dist/node-esm/index.node.esm.js +245 -51
  11. package/dist/node-esm/index.node.esm.js.map +1 -1
  12. package/dist/node-esm/src/api/DataConnect.d.ts +14 -3
  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/AppCheckTokenProvider.d.ts +30 -0
  16. package/dist/node-esm/src/core/FirebaseAuthProvider.d.ts +1 -1
  17. package/dist/node-esm/src/core/QueryManager.d.ts +1 -1
  18. package/dist/node-esm/src/core/error.d.ts +2 -1
  19. package/dist/node-esm/src/network/fetch.d.ts +1 -1
  20. package/dist/node-esm/src/network/transport/index.d.ts +8 -10
  21. package/dist/node-esm/src/network/transport/rest.d.ts +24 -10
  22. package/dist/node-esm/src/util/validateArgs.d.ts +33 -0
  23. package/dist/private.d.ts +27 -45
  24. package/dist/public.d.ts +8 -38
  25. package/dist/src/api/DataConnect.d.ts +14 -3
  26. package/dist/src/api/index.d.ts +1 -0
  27. package/dist/src/api/query.d.ts +1 -1
  28. package/dist/src/core/AppCheckTokenProvider.d.ts +30 -0
  29. package/dist/src/core/FirebaseAuthProvider.d.ts +1 -1
  30. package/dist/src/core/QueryManager.d.ts +1 -1
  31. package/dist/src/core/error.d.ts +2 -1
  32. package/dist/src/network/fetch.d.ts +1 -1
  33. package/dist/src/network/transport/index.d.ts +8 -10
  34. package/dist/src/network/transport/rest.d.ts +24 -10
  35. package/dist/src/util/validateArgs.d.ts +33 -0
  36. package/package.json +11 -7
@@ -4,7 +4,7 @@ import { FirebaseError } from '@firebase/util';
4
4
  import { Logger } from '@firebase/logger';
5
5
 
6
6
  const name = "@firebase/data-connect";
7
- const version = "0.0.2-dataconnect-preview.388b61c7e";
7
+ const version = "0.0.3-canary.beaa4dffb";
8
8
 
9
9
  /**
10
10
  * @license
@@ -32,6 +32,60 @@ function setSDKVersion(version) {
32
32
  SDK_VERSION = version;
33
33
  }
34
34
 
35
+ /**
36
+ * @license
37
+ * Copyright 2024 Google LLC
38
+ *
39
+ * Licensed under the Apache License, Version 2.0 (the "License");
40
+ * you may not use this file except in compliance with the License.
41
+ * You may obtain a copy of the License at
42
+ *
43
+ * http://www.apache.org/licenses/LICENSE-2.0
44
+ *
45
+ * Unless required by applicable law or agreed to in writing, software
46
+ * distributed under the License is distributed on an "AS IS" BASIS,
47
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
48
+ * See the License for the specific language governing permissions and
49
+ * limitations under the License.
50
+ */
51
+ /**
52
+ * @internal
53
+ * Abstraction around AppCheck's token fetching capabilities.
54
+ */
55
+ class AppCheckTokenProvider {
56
+ constructor(appName_, appCheckProvider) {
57
+ this.appName_ = appName_;
58
+ this.appCheckProvider = appCheckProvider;
59
+ this.appCheck = appCheckProvider === null || appCheckProvider === void 0 ? void 0 : appCheckProvider.getImmediate({ optional: true });
60
+ if (!this.appCheck) {
61
+ void (appCheckProvider === null || appCheckProvider === void 0 ? void 0 : appCheckProvider.get().then(appCheck => (this.appCheck = appCheck)).catch());
62
+ }
63
+ }
64
+ getToken(forceRefresh) {
65
+ if (!this.appCheck) {
66
+ return new Promise((resolve, reject) => {
67
+ // Support delayed initialization of FirebaseAppCheck. This allows our
68
+ // customers to initialize the RTDB SDK before initializing Firebase
69
+ // AppCheck and ensures that all requests are authenticated if a token
70
+ // becomes available before the timoeout below expires.
71
+ setTimeout(() => {
72
+ if (this.appCheck) {
73
+ this.getToken(forceRefresh).then(resolve, reject);
74
+ }
75
+ else {
76
+ resolve(null);
77
+ }
78
+ }, 0);
79
+ });
80
+ }
81
+ return this.appCheck.getToken(forceRefresh);
82
+ }
83
+ addTokenChangeListener(listener) {
84
+ var _a;
85
+ void ((_a = this.appCheckProvider) === null || _a === void 0 ? void 0 : _a.get().then(appCheck => appCheck.addTokenListener(listener)));
86
+ }
87
+ }
88
+
35
89
  /**
36
90
  * @license
37
91
  * Copyright 2024 Google LLC
@@ -54,7 +108,8 @@ const Code = {
54
108
  NOT_INITIALIZED: 'not-initialized',
55
109
  NOT_SUPPORTED: 'not-supported',
56
110
  INVALID_ARGUMENT: 'invalid-argument',
57
- PARTIAL_ERROR: 'partial-error'
111
+ PARTIAL_ERROR: 'partial-error',
112
+ UNAUTHORIZED: 'unauthorized'
58
113
  };
59
114
  /** An error returned by a DataConnect operation. */
60
115
  class DataConnectError extends FirebaseError {
@@ -121,6 +176,7 @@ function logError(msg) {
121
176
  * See the License for the specific language governing permissions and
122
177
  * limitations under the License.
123
178
  */
179
+ // @internal
124
180
  class FirebaseAuthProvider {
125
181
  constructor(_appName, _options, _authProvider) {
126
182
  this._appName = _appName;
@@ -163,7 +219,8 @@ class FirebaseAuthProvider {
163
219
  removeTokenChangeListener(listener) {
164
220
  this._authProvider
165
221
  .get()
166
- .then(auth => auth.removeAuthTokenListener(listener));
222
+ .then(auth => auth.removeAuthTokenListener(listener))
223
+ .catch(err => logError(err));
167
224
  }
168
225
  }
169
226
 
@@ -403,7 +460,7 @@ function urlBuilder(projectConfig, transportOptions) {
403
460
  logError('Port type is of an invalid type');
404
461
  throw new DataConnectError(Code.INVALID_ARGUMENT, 'Incorrect type for port passed in!');
405
462
  }
406
- return `${baseUrl}/v1alpha/projects/${project}/locations/${location}/services/${service}/connectors/${connector}`;
463
+ return `${baseUrl}/v1beta/projects/${project}/locations/${location}/services/${service}/connectors/${connector}`;
407
464
  }
408
465
  function addToken(url, apiKey) {
409
466
  if (!apiKey) {
@@ -431,16 +488,30 @@ function addToken(url, apiKey) {
431
488
  * limitations under the License.
432
489
  */
433
490
  let connectFetch = globalThis.fetch;
434
- function dcFetch(url, body, { signal }, accessToken) {
491
+ function getGoogApiClientValue(_isUsingGen) {
492
+ let str = 'gl-js/ fire/' + SDK_VERSION;
493
+ if (_isUsingGen) {
494
+ str += ' web/gen';
495
+ }
496
+ return str;
497
+ }
498
+ function dcFetch(url, body, { signal }, appId, accessToken, appCheckToken, _isUsingGen) {
435
499
  if (!connectFetch) {
436
500
  throw new DataConnectError(Code.OTHER, 'No Fetch Implementation detected!');
437
501
  }
438
502
  const headers = {
439
- 'Content-Type': 'application/json'
503
+ 'Content-Type': 'application/json',
504
+ 'X-Goog-Api-Client': getGoogApiClientValue(_isUsingGen)
440
505
  };
441
506
  if (accessToken) {
442
507
  headers['X-Firebase-Auth-Token'] = accessToken;
443
508
  }
509
+ if (appId) {
510
+ headers['x-firebase-gmpid'] = appId;
511
+ }
512
+ if (appCheckToken) {
513
+ headers['X-Firebase-AppCheck'] = appCheckToken;
514
+ }
444
515
  const bodyStr = JSON.stringify(body);
445
516
  logDebug(`Making request out to ${url} with body: ${bodyStr}`);
446
517
  return connectFetch(url, {
@@ -448,8 +519,9 @@ function dcFetch(url, body, { signal }, accessToken) {
448
519
  method: 'POST',
449
520
  headers,
450
521
  signal
451
- }).catch(err => {
452
- throw new DataConnectError(Code.OTHER, "Failed to fetch: " + JSON.stringify(err));
522
+ })
523
+ .catch(err => {
524
+ throw new DataConnectError(Code.OTHER, 'Failed to fetch: ' + JSON.stringify(err));
453
525
  })
454
526
  .then(async (response) => {
455
527
  let jsonResponse = null;
@@ -459,9 +531,13 @@ function dcFetch(url, body, { signal }, accessToken) {
459
531
  catch (e) {
460
532
  throw new DataConnectError(Code.OTHER, JSON.stringify(e));
461
533
  }
534
+ const message = getMessage(jsonResponse);
462
535
  if (response.status >= 400) {
463
536
  logError('Error while performing request: ' + JSON.stringify(jsonResponse));
464
- throw new DataConnectError(Code.OTHER, JSON.stringify(jsonResponse));
537
+ if (response.status === 401) {
538
+ throw new DataConnectError(Code.UNAUTHORIZED, message);
539
+ }
540
+ throw new DataConnectError(Code.OTHER, message);
465
541
  }
466
542
  return jsonResponse;
467
543
  })
@@ -473,6 +549,12 @@ function dcFetch(url, body, { signal }, accessToken) {
473
549
  }
474
550
  return res;
475
551
  });
552
+ }
553
+ function getMessage(obj) {
554
+ if ('message' in obj) {
555
+ return obj.message;
556
+ }
557
+ return JSON.stringify(obj);
476
558
  }
477
559
 
478
560
  /**
@@ -492,41 +574,44 @@ function dcFetch(url, body, { signal }, accessToken) {
492
574
  * limitations under the License.
493
575
  */
494
576
  class RESTTransport {
495
- constructor(options, apiKey, authProvider, transportOptions) {
496
- var _a;
577
+ constructor(options, apiKey, appId, authProvider, appCheckProvider, transportOptions, _isUsingGen = false) {
578
+ var _a, _b;
497
579
  this.apiKey = apiKey;
580
+ this.appId = appId;
498
581
  this.authProvider = authProvider;
582
+ this.appCheckProvider = appCheckProvider;
583
+ this._isUsingGen = _isUsingGen;
499
584
  this._host = '';
500
585
  this._location = 'l';
501
586
  this._connectorName = '';
502
587
  this._secure = true;
503
588
  this._project = 'p';
504
589
  this._accessToken = null;
505
- this._authInitialized = false;
590
+ this._appCheckToken = null;
591
+ this._lastToken = null;
506
592
  // TODO(mtewani): Update U to include shape of body defined in line 13.
507
593
  this.invokeQuery = (queryName, body) => {
508
594
  const abortController = new AbortController();
509
595
  // TODO(mtewani): Update to proper value
510
- const withAuth = this.getWithAuth().then(() => {
511
- return dcFetch(addToken(`${this.endpointUrl}:executeQuery`, this.apiKey), {
512
- name: `projects/${this._project}/locations/${this._location}/services/${this._serviceName}/connectors/${this._connectorName}`,
513
- operationName: queryName,
514
- variables: body
515
- }, // TODO(mtewani): This is a patch, fix this.
516
- abortController, this._accessToken);
517
- });
596
+ const withAuth = this.withRetry(() => dcFetch(addToken(`${this.endpointUrl}:executeQuery`, this.apiKey), {
597
+ name: `projects/${this._project}/locations/${this._location}/services/${this._serviceName}/connectors/${this._connectorName}`,
598
+ operationName: queryName,
599
+ variables: body
600
+ }, // TODO(mtewani): This is a patch, fix this.
601
+ abortController, this.appId, this._accessToken, this._appCheckToken, this._isUsingGen));
518
602
  return {
519
- then: withAuth.then.bind(withAuth)
603
+ then: withAuth.then.bind(withAuth),
604
+ catch: withAuth.catch.bind(withAuth)
520
605
  };
521
606
  };
522
607
  this.invokeMutation = (mutationName, body) => {
523
608
  const abortController = new AbortController();
524
- const taskResult = this.getWithAuth().then(() => {
609
+ const taskResult = this.withRetry(() => {
525
610
  return dcFetch(addToken(`${this.endpointUrl}:executeMutation`, this.apiKey), {
526
611
  name: `projects/${this._project}/locations/${this._location}/services/${this._serviceName}/connectors/${this._connectorName}`,
527
612
  operationName: mutationName,
528
613
  variables: body
529
- }, abortController, this._accessToken);
614
+ }, abortController, this.appId, this._accessToken, this._appCheckToken, this._isUsingGen);
530
615
  });
531
616
  return {
532
617
  then: taskResult.then.bind(taskResult),
@@ -560,6 +645,11 @@ class RESTTransport {
560
645
  logDebug(`New Token Available: ${token}`);
561
646
  this._accessToken = token;
562
647
  });
648
+ (_b = this.appCheckProvider) === null || _b === void 0 ? void 0 : _b.addTokenChangeListener(result => {
649
+ const { token } = result;
650
+ logDebug(`New App Check Token Available: ${token}`);
651
+ this._appCheckToken = token;
652
+ });
563
653
  }
564
654
  get endpointUrl() {
565
655
  return urlBuilder({
@@ -581,26 +671,52 @@ class RESTTransport {
581
671
  onTokenChanged(newToken) {
582
672
  this._accessToken = newToken;
583
673
  }
584
- getWithAuth() {
674
+ async getWithAuth(forceToken = false) {
675
+ var _a;
585
676
  let starterPromise = new Promise(resolve => resolve(this._accessToken));
586
- if (!this._authInitialized) {
587
- if (this.authProvider) {
588
- starterPromise = this.authProvider
589
- .getToken(/*forceToken=*/ false)
590
- .then(data => {
591
- if (!data) {
592
- return null;
593
- }
594
- this._accessToken = data.accessToken;
595
- return this._accessToken;
596
- });
597
- }
598
- else {
599
- starterPromise = new Promise(resolve => resolve(''));
600
- }
677
+ if (this.appCheckProvider) {
678
+ this._appCheckToken = (_a = (await this.appCheckProvider.getToken())) === null || _a === void 0 ? void 0 : _a.token;
679
+ }
680
+ if (this.authProvider) {
681
+ starterPromise = this.authProvider
682
+ .getToken(/*forceToken=*/ forceToken)
683
+ .then(data => {
684
+ if (!data) {
685
+ return null;
686
+ }
687
+ this._accessToken = data.accessToken;
688
+ return this._accessToken;
689
+ });
690
+ }
691
+ else {
692
+ starterPromise = new Promise(resolve => resolve(''));
601
693
  }
602
694
  return starterPromise;
603
695
  }
696
+ _setLastToken(lastToken) {
697
+ this._lastToken = lastToken;
698
+ }
699
+ withRetry(promiseFactory, retry = false) {
700
+ let isNewToken = false;
701
+ return this.getWithAuth(retry)
702
+ .then(res => {
703
+ isNewToken = this._lastToken !== res;
704
+ this._lastToken = res;
705
+ return res;
706
+ })
707
+ .then(promiseFactory)
708
+ .catch(err => {
709
+ // Only retry if the result is unauthorized and the last token isn't the same as the new one.
710
+ if ('code' in err &&
711
+ err.code === Code.UNAUTHORIZED &&
712
+ !retry &&
713
+ isNewToken) {
714
+ logDebug('Retrying due to unauthorized');
715
+ return this.withRetry(promiseFactory, true);
716
+ }
717
+ throw err;
718
+ });
719
+ }
604
720
  }
605
721
 
606
722
  /**
@@ -699,14 +815,17 @@ function parseOptions(fullHost) {
699
815
  * Class representing Firebase Data Connect
700
816
  */
701
817
  class DataConnect {
818
+ // @internal
702
819
  constructor(app,
703
820
  // TODO(mtewani): Replace with _dataConnectOptions in the future
704
- dataConnectOptions, _authProvider) {
821
+ dataConnectOptions, _authProvider, _appCheckProvider) {
705
822
  this.app = app;
706
823
  this.dataConnectOptions = dataConnectOptions;
707
824
  this._authProvider = _authProvider;
825
+ this._appCheckProvider = _appCheckProvider;
708
826
  this.isEmulator = false;
709
- this.initialized = false;
827
+ this._initialized = false;
828
+ this._isUsingGeneratedSdk = false;
710
829
  if (typeof process !== 'undefined' && process.env) {
711
830
  const host = process.env[FIREBASE_DATA_CONNECT_EMULATOR_HOST_VAR];
712
831
  if (host) {
@@ -716,17 +835,25 @@ class DataConnect {
716
835
  }
717
836
  }
718
837
  }
838
+ // @internal
839
+ _useGeneratedSdk() {
840
+ if (!this._isUsingGeneratedSdk) {
841
+ this._isUsingGeneratedSdk = true;
842
+ }
843
+ }
719
844
  _delete() {
720
845
  _removeServiceInstance(this.app, 'data-connect', JSON.stringify(this.getSettings()));
721
846
  return Promise.resolve();
722
847
  }
848
+ // @internal
723
849
  getSettings() {
724
850
  const copy = JSON.parse(JSON.stringify(this.dataConnectOptions));
725
851
  delete copy.projectId;
726
852
  return copy;
727
853
  }
854
+ // @internal
728
855
  setInitialized() {
729
- if (this.initialized) {
856
+ if (this._initialized) {
730
857
  return;
731
858
  }
732
859
  if (this._transportClass === undefined) {
@@ -736,16 +863,20 @@ class DataConnect {
736
863
  if (this._authProvider) {
737
864
  this._authTokenProvider = new FirebaseAuthProvider(this.app.name, this.app.options, this._authProvider);
738
865
  }
739
- this.initialized = true;
740
- this._transport = new this._transportClass(this.dataConnectOptions, this.app.options.apiKey, this._authTokenProvider);
866
+ if (this._appCheckProvider) {
867
+ this._appCheckTokenProvider = new AppCheckTokenProvider(this.app.name, this._appCheckProvider);
868
+ }
869
+ this._initialized = true;
870
+ this._transport = new this._transportClass(this.dataConnectOptions, this.app.options.apiKey, this.app.options.appId, this._authTokenProvider, this._appCheckTokenProvider, undefined, this._isUsingGeneratedSdk);
741
871
  if (this._transportOptions) {
742
872
  this._transport.useEmulator(this._transportOptions.host, this._transportOptions.port, this._transportOptions.sslEnabled);
743
873
  }
744
874
  this._queryManager = new QueryManager(this._transport);
745
875
  this._mutationManager = new MutationManager(this._transport);
746
876
  }
877
+ // @internal
747
878
  enableEmulator(transportOptions) {
748
- if (this.initialized) {
879
+ if (this._initialized) {
749
880
  logError('enableEmulator called after initialization');
750
881
  throw new DataConnectError(Code.ALREADY_INITIALIZED, 'DataConnect instance already initialized!');
751
882
  }
@@ -774,7 +905,7 @@ function getDataConnect(appOrOptions, optionalOptions) {
774
905
  dcOptions = optionalOptions;
775
906
  app = appOrOptions;
776
907
  }
777
- if (!app) {
908
+ if (!app || Object.keys(app).length === 0) {
778
909
  app = getApp();
779
910
  }
780
911
  const provider = _getProvider(app, 'data-connect');
@@ -788,9 +919,7 @@ function getDataConnect(appOrOptions, optionalOptions) {
788
919
  return dcInstance;
789
920
  }
790
921
  }
791
- if (!dcOptions) {
792
- throw new DataConnectError(Code.INVALID_ARGUMENT, 'DC Option Required');
793
- }
922
+ validateDCOptions(dcOptions);
794
923
  logDebug('Creating new DataConnect instance');
795
924
  // Initialize with options.
796
925
  return provider.initialize({
@@ -798,6 +927,24 @@ function getDataConnect(appOrOptions, optionalOptions) {
798
927
  options: dcOptions
799
928
  });
800
929
  }
930
+ /**
931
+ *
932
+ * @param dcOptions
933
+ * @returns {void}
934
+ * @internal
935
+ */
936
+ function validateDCOptions(dcOptions) {
937
+ const fields = ['connector', 'location', 'service'];
938
+ if (!dcOptions) {
939
+ throw new DataConnectError(Code.INVALID_ARGUMENT, 'DC Option Required');
940
+ }
941
+ fields.forEach(field => {
942
+ if (dcOptions[field] === null || dcOptions[field] === undefined) {
943
+ throw new DataConnectError(Code.INVALID_ARGUMENT, `${field} Required`);
944
+ }
945
+ });
946
+ return true;
947
+ }
801
948
  /**
802
949
  * Delete DataConnect instance
803
950
  * @param dataConnect DataConnect instance
@@ -829,11 +976,15 @@ function registerDataConnect(variant) {
829
976
  _registerComponent(new Component('data-connect', (container, { instanceIdentifier: settings, options }) => {
830
977
  const app = container.getProvider('app').getImmediate();
831
978
  const authProvider = container.getProvider('auth-internal');
979
+ const appCheckProvider = container.getProvider('app-check-internal');
832
980
  let newOpts = options;
833
981
  if (settings) {
834
982
  newOpts = JSON.parse(settings);
835
983
  }
836
- return new DataConnect(app, Object.assign(Object.assign({}, newOpts), { projectId: app.options.projectId }), authProvider);
984
+ if (!app.options.projectId) {
985
+ throw new DataConnectError(Code.INVALID_ARGUMENT, 'Project ID must be provided. Did you pass in a proper projectId to initializeApp?');
986
+ }
987
+ return new DataConnect(app, Object.assign(Object.assign({}, newOpts), { projectId: app.options.projectId }), authProvider, appCheckProvider);
837
988
  }, "PUBLIC" /* ComponentType.PUBLIC */).setMultipleInstances(true));
838
989
  registerVersion(name, version, variant);
839
990
  // BUILD_TARGET will be replaced by values like esm5, esm2017, cjs5, etc during the compilation
@@ -892,6 +1043,49 @@ function toQueryRef(serializedRef) {
892
1043
  return queryRef(getDataConnect(connectorConfig), name, variables);
893
1044
  }
894
1045
 
1046
+ /**
1047
+ * @license
1048
+ * Copyright 2024 Google LLC
1049
+ *
1050
+ * Licensed under the Apache License, Version 2.0 (the "License");
1051
+ * you may not use this file except in compliance with the License.
1052
+ * You may obtain a copy of the License at
1053
+ *
1054
+ * http://www.apache.org/licenses/LICENSE-2.0
1055
+ *
1056
+ * Unless required by applicable law or agreed to in writing, software
1057
+ * distributed under the License is distributed on an "AS IS" BASIS,
1058
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1059
+ * See the License for the specific language governing permissions and
1060
+ * limitations under the License.
1061
+ */
1062
+ /**
1063
+ * The generated SDK will allow the user to pass in either the variable or the data connect instance with the variable,
1064
+ * and this function validates the variables and returns back the DataConnect instance and variables based on the arguments passed in.
1065
+ * @param connectorConfig
1066
+ * @param dcOrVars
1067
+ * @param vars
1068
+ * @param validateVars
1069
+ * @returns {DataConnect} and {Variables} instance
1070
+ * @internal
1071
+ */
1072
+ function validateArgs(connectorConfig, dcOrVars, vars, validateVars) {
1073
+ let dcInstance;
1074
+ let realVars;
1075
+ if (dcOrVars && 'enableEmulator' in dcOrVars) {
1076
+ dcInstance = dcOrVars;
1077
+ realVars = vars;
1078
+ }
1079
+ else {
1080
+ dcInstance = getDataConnect(connectorConfig);
1081
+ realVars = dcOrVars;
1082
+ }
1083
+ if (!dcInstance || (!realVars && validateVars)) {
1084
+ throw new DataConnectError(Code.INVALID_ARGUMENT, 'Variables required.');
1085
+ }
1086
+ return { dc: dcInstance, vars: realVars };
1087
+ }
1088
+
895
1089
  /**
896
1090
  * @license
897
1091
  * Copyright 2024 Google LLC
@@ -954,5 +1148,5 @@ function subscribe(queryRefOrSerializedResult, observerOrOnNext, onError, onComp
954
1148
  */
955
1149
  registerDataConnect();
956
1150
 
957
- 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 };
1151
+ export { DataConnect, MUTATION_STR, MutationManager, QUERY_STR, SOURCE_CACHE, SOURCE_SERVER, connectDataConnectEmulator, executeMutation, executeQuery, getDataConnect, mutationRef, parseOptions, queryRef, setLogLevel, subscribe, terminate, toQueryRef, validateArgs, validateDCOptions };
958
1152
  //# sourceMappingURL=index.esm2017.js.map