@firebase/data-connect 0.0.2-dataconnect-preview.877f8b7d0 → 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 (42) hide show
  1. package/dist/index.cjs.js +304 -54
  2. package/dist/index.cjs.js.map +1 -1
  3. package/dist/index.esm2017.js +303 -53
  4. package/dist/index.esm2017.js.map +1 -1
  5. package/dist/index.esm5.js +323 -52
  6. package/dist/index.esm5.js.map +1 -1
  7. package/dist/index.node.cjs.js +324 -53
  8. package/dist/index.node.cjs.js.map +1 -1
  9. package/dist/internal.d.ts +186 -41
  10. package/dist/node-esm/index.node.esm.js +303 -53
  11. package/dist/node-esm/index.node.esm.js.map +1 -1
  12. package/dist/node-esm/src/api/DataConnect.d.ts +47 -3
  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/AppCheckTokenProvider.d.ts +30 -0
  19. package/dist/node-esm/src/core/FirebaseAuthProvider.d.ts +1 -1
  20. package/dist/node-esm/src/core/QueryManager.d.ts +1 -1
  21. package/dist/node-esm/src/core/error.d.ts +2 -1
  22. package/dist/node-esm/src/network/fetch.d.ts +1 -1
  23. package/dist/node-esm/src/network/transport/index.d.ts +8 -10
  24. package/dist/node-esm/src/network/transport/rest.d.ts +24 -10
  25. package/dist/node-esm/src/util/validateArgs.d.ts +33 -0
  26. package/dist/private.d.ts +152 -59
  27. package/dist/public.d.ts +133 -50
  28. package/dist/src/api/DataConnect.d.ts +47 -3
  29. package/dist/src/api/Mutation.d.ts +26 -1
  30. package/dist/src/api/Reference.d.ts +6 -0
  31. package/dist/src/api/index.d.ts +1 -0
  32. package/dist/src/api/query.d.ts +51 -1
  33. package/dist/src/api.browser.d.ts +12 -7
  34. package/dist/src/core/AppCheckTokenProvider.d.ts +30 -0
  35. package/dist/src/core/FirebaseAuthProvider.d.ts +1 -1
  36. package/dist/src/core/QueryManager.d.ts +1 -1
  37. package/dist/src/core/error.d.ts +2 -1
  38. package/dist/src/network/fetch.d.ts +1 -1
  39. package/dist/src/network/transport/index.d.ts +8 -10
  40. package/dist/src/network/transport/rest.d.ts +24 -10
  41. package/dist/src/util/validateArgs.d.ts +33 -0
  42. 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.877f8b7d0";
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
  /**
@@ -619,16 +735,26 @@ class RESTTransport {
619
735
  * See the License for the specific language governing permissions and
620
736
  * limitations under the License.
621
737
  */
622
- function mutationRef(dcInstance, queryName, variables) {
738
+ /**
739
+ *
740
+ * @param dcInstance Data Connect instance
741
+ * @param mutationName name of mutation
742
+ * @param variables variables to send with mutation
743
+ * @returns `MutationRef`
744
+ */
745
+ function mutationRef(dcInstance, mutationName, variables) {
623
746
  dcInstance.setInitialized();
624
747
  const ref = {
625
748
  dataConnect: dcInstance,
626
- name: queryName,
749
+ name: mutationName,
627
750
  refType: MUTATION_STR,
628
751
  variables: variables
629
752
  };
630
753
  return ref;
631
754
  }
755
+ /**
756
+ * @internal
757
+ */
632
758
  class MutationManager {
633
759
  constructor(_transport) {
634
760
  this._transport = _transport;
@@ -646,6 +772,11 @@ class MutationManager {
646
772
  return withRefPromise;
647
773
  }
648
774
  }
775
+ /**
776
+ * Execute Mutation
777
+ * @param mutationRef mutation to execute
778
+ * @returns `MutationRef`
779
+ */
649
780
  function executeMutation(mutationRef) {
650
781
  return mutationRef.dataConnect._mutationManager.executeMutation(mutationRef);
651
782
  }
@@ -680,15 +811,21 @@ function parseOptions(fullHost) {
680
811
  const port = Number(portAsString);
681
812
  return { host, port, sslEnabled: isSecure };
682
813
  }
814
+ /**
815
+ * Class representing Firebase Data Connect
816
+ */
683
817
  class DataConnect {
818
+ // @internal
684
819
  constructor(app,
685
820
  // TODO(mtewani): Replace with _dataConnectOptions in the future
686
- dataConnectOptions, _authProvider) {
821
+ dataConnectOptions, _authProvider, _appCheckProvider) {
687
822
  this.app = app;
688
823
  this.dataConnectOptions = dataConnectOptions;
689
824
  this._authProvider = _authProvider;
825
+ this._appCheckProvider = _appCheckProvider;
690
826
  this.isEmulator = false;
691
- this.initialized = false;
827
+ this._initialized = false;
828
+ this._isUsingGeneratedSdk = false;
692
829
  if (typeof process !== 'undefined' && process.env) {
693
830
  const host = process.env[FIREBASE_DATA_CONNECT_EMULATOR_HOST_VAR];
694
831
  if (host) {
@@ -698,17 +835,25 @@ class DataConnect {
698
835
  }
699
836
  }
700
837
  }
838
+ // @internal
839
+ _useGeneratedSdk() {
840
+ if (!this._isUsingGeneratedSdk) {
841
+ this._isUsingGeneratedSdk = true;
842
+ }
843
+ }
701
844
  _delete() {
702
845
  _removeServiceInstance(this.app, 'data-connect', JSON.stringify(this.getSettings()));
703
846
  return Promise.resolve();
704
847
  }
848
+ // @internal
705
849
  getSettings() {
706
850
  const copy = JSON.parse(JSON.stringify(this.dataConnectOptions));
707
851
  delete copy.projectId;
708
852
  return copy;
709
853
  }
854
+ // @internal
710
855
  setInitialized() {
711
- if (this.initialized) {
856
+ if (this._initialized) {
712
857
  return;
713
858
  }
714
859
  if (this._transportClass === undefined) {
@@ -718,16 +863,20 @@ class DataConnect {
718
863
  if (this._authProvider) {
719
864
  this._authTokenProvider = new FirebaseAuthProvider(this.app.name, this.app.options, this._authProvider);
720
865
  }
721
- this.initialized = true;
722
- 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);
723
871
  if (this._transportOptions) {
724
872
  this._transport.useEmulator(this._transportOptions.host, this._transportOptions.port, this._transportOptions.sslEnabled);
725
873
  }
726
874
  this._queryManager = new QueryManager(this._transport);
727
875
  this._mutationManager = new MutationManager(this._transport);
728
876
  }
877
+ // @internal
729
878
  enableEmulator(transportOptions) {
730
- if (this.initialized) {
879
+ if (this._initialized) {
731
880
  logError('enableEmulator called after initialization');
732
881
  throw new DataConnectError(Code.ALREADY_INITIALIZED, 'DataConnect instance already initialized!');
733
882
  }
@@ -735,6 +884,13 @@ class DataConnect {
735
884
  this.isEmulator = true;
736
885
  }
737
886
  }
887
+ /**
888
+ * Connect to the DataConnect Emulator
889
+ * @param dc Data Connect instance
890
+ * @param host host of emulator server
891
+ * @param port port of emulator server
892
+ * @param sslEnabled use https
893
+ */
738
894
  function connectDataConnectEmulator(dc, host, port, sslEnabled = false) {
739
895
  dc.enableEmulator({ host, port, sslEnabled });
740
896
  }
@@ -749,7 +905,7 @@ function getDataConnect(appOrOptions, optionalOptions) {
749
905
  dcOptions = optionalOptions;
750
906
  app = appOrOptions;
751
907
  }
752
- if (!app) {
908
+ if (!app || Object.keys(app).length === 0) {
753
909
  app = getApp();
754
910
  }
755
911
  const provider = _getProvider(app, 'data-connect');
@@ -763,9 +919,7 @@ function getDataConnect(appOrOptions, optionalOptions) {
763
919
  return dcInstance;
764
920
  }
765
921
  }
766
- if (!dcOptions) {
767
- throw new DataConnectError(Code.INVALID_ARGUMENT, 'DC Option Required');
768
- }
922
+ validateDCOptions(dcOptions);
769
923
  logDebug('Creating new DataConnect instance');
770
924
  // Initialize with options.
771
925
  return provider.initialize({
@@ -773,6 +927,29 @@ function getDataConnect(appOrOptions, optionalOptions) {
773
927
  options: dcOptions
774
928
  });
775
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
+ }
948
+ /**
949
+ * Delete DataConnect instance
950
+ * @param dataConnect DataConnect instance
951
+ * @returns
952
+ */
776
953
  function terminate(dataConnect) {
777
954
  return dataConnect._delete();
778
955
  // TODO(mtewani): Stop pending tasks
@@ -799,11 +976,15 @@ function registerDataConnect(variant) {
799
976
  _registerComponent(new Component('data-connect', (container, { instanceIdentifier: settings, options }) => {
800
977
  const app = container.getProvider('app').getImmediate();
801
978
  const authProvider = container.getProvider('auth-internal');
979
+ const appCheckProvider = container.getProvider('app-check-internal');
802
980
  let newOpts = options;
803
981
  if (settings) {
804
982
  newOpts = JSON.parse(settings);
805
983
  }
806
- 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);
807
988
  }, "PUBLIC" /* ComponentType.PUBLIC */).setMultipleInstances(true));
808
989
  registerVersion(name, version, variant);
809
990
  // BUILD_TARGET will be replaced by values like esm5, esm2017, cjs5, etc during the compilation
@@ -826,9 +1007,22 @@ function registerDataConnect(variant) {
826
1007
  * See the License for the specific language governing permissions and
827
1008
  * limitations under the License.
828
1009
  */
1010
+ /**
1011
+ * Execute Query
1012
+ * @param queryRef query to execute.
1013
+ * @returns `QueryPromise`
1014
+ */
829
1015
  function executeQuery(queryRef) {
830
1016
  return queryRef.dataConnect._queryManager.executeQuery(queryRef);
831
1017
  }
1018
+ /**
1019
+ * Execute Query
1020
+ * @param dcInstance Data Connect instance to use.
1021
+ * @param queryName Query to execute
1022
+ * @param variables Variables to execute with
1023
+ * @param initialCache initial cache to use for client hydration
1024
+ * @returns `QueryRef`
1025
+ */
832
1026
  function queryRef(dcInstance, queryName, variables, initialCache) {
833
1027
  dcInstance.setInitialized();
834
1028
  dcInstance._queryManager.track(queryName, variables, initialCache);
@@ -839,6 +1033,11 @@ function queryRef(dcInstance, queryName, variables, initialCache) {
839
1033
  variables: variables
840
1034
  };
841
1035
  }
1036
+ /**
1037
+ * Converts serialized ref to query ref
1038
+ * @param serializedRef ref to convert to `QueryRef`
1039
+ * @returns `QueryRef`
1040
+ */
842
1041
  function toQueryRef(serializedRef) {
843
1042
  const { refInfo: { name, variables, connectorConfig } } = serializedRef;
844
1043
  return queryRef(getDataConnect(connectorConfig), name, variables);
@@ -860,6 +1059,57 @@ function toQueryRef(serializedRef) {
860
1059
  * See the License for the specific language governing permissions and
861
1060
  * limitations under the License.
862
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
+
1089
+ /**
1090
+ * @license
1091
+ * Copyright 2024 Google LLC
1092
+ *
1093
+ * Licensed under the Apache License, Version 2.0 (the "License");
1094
+ * you may not use this file except in compliance with the License.
1095
+ * You may obtain a copy of the License at
1096
+ *
1097
+ * http://www.apache.org/licenses/LICENSE-2.0
1098
+ *
1099
+ * Unless required by applicable law or agreed to in writing, software
1100
+ * distributed under the License is distributed on an "AS IS" BASIS,
1101
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1102
+ * See the License for the specific language governing permissions and
1103
+ * limitations under the License.
1104
+ */
1105
+ /**
1106
+ * Subscribe to a `QueryRef`
1107
+ * @param queryRefOrSerializedResult query ref or serialized result.
1108
+ * @param observerOrOnNext observer object or next function.
1109
+ * @param onError Callback to call when error gets thrown.
1110
+ * @param onComplete Called when subscription completes.
1111
+ * @returns `SubscriptionOptions`
1112
+ */
863
1113
  function subscribe(queryRefOrSerializedResult, observerOrOnNext, onError, onComplete) {
864
1114
  let ref;
865
1115
  let initialCache;
@@ -898,5 +1148,5 @@ function subscribe(queryRefOrSerializedResult, observerOrOnNext, onError, onComp
898
1148
  */
899
1149
  registerDataConnect();
900
1150
 
901
- 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 };
902
1152
  //# sourceMappingURL=index.esm2017.js.map