@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.
- package/dist/index.cjs.js +304 -54
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm2017.js +303 -53
- package/dist/index.esm2017.js.map +1 -1
- package/dist/index.esm5.js +323 -52
- package/dist/index.esm5.js.map +1 -1
- package/dist/index.node.cjs.js +324 -53
- package/dist/index.node.cjs.js.map +1 -1
- package/dist/internal.d.ts +186 -41
- package/dist/node-esm/index.node.esm.js +303 -53
- package/dist/node-esm/index.node.esm.js.map +1 -1
- package/dist/node-esm/src/api/DataConnect.d.ts +47 -3
- package/dist/node-esm/src/api/Mutation.d.ts +26 -1
- package/dist/node-esm/src/api/Reference.d.ts +6 -0
- package/dist/node-esm/src/api/index.d.ts +1 -0
- package/dist/node-esm/src/api/query.d.ts +51 -1
- package/dist/node-esm/src/api.browser.d.ts +12 -7
- package/dist/node-esm/src/core/AppCheckTokenProvider.d.ts +30 -0
- package/dist/node-esm/src/core/FirebaseAuthProvider.d.ts +1 -1
- package/dist/node-esm/src/core/QueryManager.d.ts +1 -1
- package/dist/node-esm/src/core/error.d.ts +2 -1
- package/dist/node-esm/src/network/fetch.d.ts +1 -1
- package/dist/node-esm/src/network/transport/index.d.ts +8 -10
- package/dist/node-esm/src/network/transport/rest.d.ts +24 -10
- package/dist/node-esm/src/util/validateArgs.d.ts +33 -0
- package/dist/private.d.ts +152 -59
- package/dist/public.d.ts +133 -50
- package/dist/src/api/DataConnect.d.ts +47 -3
- package/dist/src/api/Mutation.d.ts +26 -1
- package/dist/src/api/Reference.d.ts +6 -0
- package/dist/src/api/index.d.ts +1 -0
- package/dist/src/api/query.d.ts +51 -1
- package/dist/src/api.browser.d.ts +12 -7
- package/dist/src/core/AppCheckTokenProvider.d.ts +30 -0
- package/dist/src/core/FirebaseAuthProvider.d.ts +1 -1
- package/dist/src/core/QueryManager.d.ts +1 -1
- package/dist/src/core/error.d.ts +2 -1
- package/dist/src/network/fetch.d.ts +1 -1
- package/dist/src/network/transport/index.d.ts +8 -10
- package/dist/src/network/transport/rest.d.ts +24 -10
- package/dist/src/util/validateArgs.d.ts +33 -0
- package/package.json +11 -7
package/dist/index.esm2017.js
CHANGED
|
@@ -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.
|
|
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}/
|
|
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
|
|
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
|
-
})
|
|
452
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
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.
|
|
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 (
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
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
|
-
|
|
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:
|
|
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.
|
|
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.
|
|
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.
|
|
722
|
-
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
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
|