@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.cjs.js
CHANGED
|
@@ -8,7 +8,7 @@ var util = require('@firebase/util');
|
|
|
8
8
|
var logger$1 = require('@firebase/logger');
|
|
9
9
|
|
|
10
10
|
const name = "@firebase/data-connect";
|
|
11
|
-
const version = "0.0.
|
|
11
|
+
const version = "0.0.3-canary.beaa4dffb";
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* @license
|
|
@@ -36,6 +36,60 @@ function setSDKVersion(version) {
|
|
|
36
36
|
SDK_VERSION = version;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
/**
|
|
40
|
+
* @license
|
|
41
|
+
* Copyright 2024 Google LLC
|
|
42
|
+
*
|
|
43
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
44
|
+
* you may not use this file except in compliance with the License.
|
|
45
|
+
* You may obtain a copy of the License at
|
|
46
|
+
*
|
|
47
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
48
|
+
*
|
|
49
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
50
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
51
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
52
|
+
* See the License for the specific language governing permissions and
|
|
53
|
+
* limitations under the License.
|
|
54
|
+
*/
|
|
55
|
+
/**
|
|
56
|
+
* @internal
|
|
57
|
+
* Abstraction around AppCheck's token fetching capabilities.
|
|
58
|
+
*/
|
|
59
|
+
class AppCheckTokenProvider {
|
|
60
|
+
constructor(appName_, appCheckProvider) {
|
|
61
|
+
this.appName_ = appName_;
|
|
62
|
+
this.appCheckProvider = appCheckProvider;
|
|
63
|
+
this.appCheck = appCheckProvider === null || appCheckProvider === void 0 ? void 0 : appCheckProvider.getImmediate({ optional: true });
|
|
64
|
+
if (!this.appCheck) {
|
|
65
|
+
void (appCheckProvider === null || appCheckProvider === void 0 ? void 0 : appCheckProvider.get().then(appCheck => (this.appCheck = appCheck)).catch());
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
getToken(forceRefresh) {
|
|
69
|
+
if (!this.appCheck) {
|
|
70
|
+
return new Promise((resolve, reject) => {
|
|
71
|
+
// Support delayed initialization of FirebaseAppCheck. This allows our
|
|
72
|
+
// customers to initialize the RTDB SDK before initializing Firebase
|
|
73
|
+
// AppCheck and ensures that all requests are authenticated if a token
|
|
74
|
+
// becomes available before the timoeout below expires.
|
|
75
|
+
setTimeout(() => {
|
|
76
|
+
if (this.appCheck) {
|
|
77
|
+
this.getToken(forceRefresh).then(resolve, reject);
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
resolve(null);
|
|
81
|
+
}
|
|
82
|
+
}, 0);
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
return this.appCheck.getToken(forceRefresh);
|
|
86
|
+
}
|
|
87
|
+
addTokenChangeListener(listener) {
|
|
88
|
+
var _a;
|
|
89
|
+
void ((_a = this.appCheckProvider) === null || _a === void 0 ? void 0 : _a.get().then(appCheck => appCheck.addTokenListener(listener)));
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
39
93
|
/**
|
|
40
94
|
* @license
|
|
41
95
|
* Copyright 2024 Google LLC
|
|
@@ -58,7 +112,8 @@ const Code = {
|
|
|
58
112
|
NOT_INITIALIZED: 'not-initialized',
|
|
59
113
|
NOT_SUPPORTED: 'not-supported',
|
|
60
114
|
INVALID_ARGUMENT: 'invalid-argument',
|
|
61
|
-
PARTIAL_ERROR: 'partial-error'
|
|
115
|
+
PARTIAL_ERROR: 'partial-error',
|
|
116
|
+
UNAUTHORIZED: 'unauthorized'
|
|
62
117
|
};
|
|
63
118
|
/** An error returned by a DataConnect operation. */
|
|
64
119
|
class DataConnectError extends util.FirebaseError {
|
|
@@ -125,6 +180,7 @@ function logError(msg) {
|
|
|
125
180
|
* See the License for the specific language governing permissions and
|
|
126
181
|
* limitations under the License.
|
|
127
182
|
*/
|
|
183
|
+
// @internal
|
|
128
184
|
class FirebaseAuthProvider {
|
|
129
185
|
constructor(_appName, _options, _authProvider) {
|
|
130
186
|
this._appName = _appName;
|
|
@@ -167,7 +223,8 @@ class FirebaseAuthProvider {
|
|
|
167
223
|
removeTokenChangeListener(listener) {
|
|
168
224
|
this._authProvider
|
|
169
225
|
.get()
|
|
170
|
-
.then(auth => auth.removeAuthTokenListener(listener))
|
|
226
|
+
.then(auth => auth.removeAuthTokenListener(listener))
|
|
227
|
+
.catch(err => logError(err));
|
|
171
228
|
}
|
|
172
229
|
}
|
|
173
230
|
|
|
@@ -407,7 +464,7 @@ function urlBuilder(projectConfig, transportOptions) {
|
|
|
407
464
|
logError('Port type is of an invalid type');
|
|
408
465
|
throw new DataConnectError(Code.INVALID_ARGUMENT, 'Incorrect type for port passed in!');
|
|
409
466
|
}
|
|
410
|
-
return `${baseUrl}/
|
|
467
|
+
return `${baseUrl}/v1beta/projects/${project}/locations/${location}/services/${service}/connectors/${connector}`;
|
|
411
468
|
}
|
|
412
469
|
function addToken(url, apiKey) {
|
|
413
470
|
if (!apiKey) {
|
|
@@ -435,16 +492,30 @@ function addToken(url, apiKey) {
|
|
|
435
492
|
* limitations under the License.
|
|
436
493
|
*/
|
|
437
494
|
let connectFetch = globalThis.fetch;
|
|
438
|
-
function
|
|
495
|
+
function getGoogApiClientValue(_isUsingGen) {
|
|
496
|
+
let str = 'gl-js/ fire/' + SDK_VERSION;
|
|
497
|
+
if (_isUsingGen) {
|
|
498
|
+
str += ' web/gen';
|
|
499
|
+
}
|
|
500
|
+
return str;
|
|
501
|
+
}
|
|
502
|
+
function dcFetch(url, body, { signal }, appId, accessToken, appCheckToken, _isUsingGen) {
|
|
439
503
|
if (!connectFetch) {
|
|
440
504
|
throw new DataConnectError(Code.OTHER, 'No Fetch Implementation detected!');
|
|
441
505
|
}
|
|
442
506
|
const headers = {
|
|
443
|
-
'Content-Type': 'application/json'
|
|
507
|
+
'Content-Type': 'application/json',
|
|
508
|
+
'X-Goog-Api-Client': getGoogApiClientValue(_isUsingGen)
|
|
444
509
|
};
|
|
445
510
|
if (accessToken) {
|
|
446
511
|
headers['X-Firebase-Auth-Token'] = accessToken;
|
|
447
512
|
}
|
|
513
|
+
if (appId) {
|
|
514
|
+
headers['x-firebase-gmpid'] = appId;
|
|
515
|
+
}
|
|
516
|
+
if (appCheckToken) {
|
|
517
|
+
headers['X-Firebase-AppCheck'] = appCheckToken;
|
|
518
|
+
}
|
|
448
519
|
const bodyStr = JSON.stringify(body);
|
|
449
520
|
logDebug(`Making request out to ${url} with body: ${bodyStr}`);
|
|
450
521
|
return connectFetch(url, {
|
|
@@ -452,8 +523,9 @@ function dcFetch(url, body, { signal }, accessToken) {
|
|
|
452
523
|
method: 'POST',
|
|
453
524
|
headers,
|
|
454
525
|
signal
|
|
455
|
-
})
|
|
456
|
-
|
|
526
|
+
})
|
|
527
|
+
.catch(err => {
|
|
528
|
+
throw new DataConnectError(Code.OTHER, 'Failed to fetch: ' + JSON.stringify(err));
|
|
457
529
|
})
|
|
458
530
|
.then(async (response) => {
|
|
459
531
|
let jsonResponse = null;
|
|
@@ -463,9 +535,13 @@ function dcFetch(url, body, { signal }, accessToken) {
|
|
|
463
535
|
catch (e) {
|
|
464
536
|
throw new DataConnectError(Code.OTHER, JSON.stringify(e));
|
|
465
537
|
}
|
|
538
|
+
const message = getMessage(jsonResponse);
|
|
466
539
|
if (response.status >= 400) {
|
|
467
540
|
logError('Error while performing request: ' + JSON.stringify(jsonResponse));
|
|
468
|
-
|
|
541
|
+
if (response.status === 401) {
|
|
542
|
+
throw new DataConnectError(Code.UNAUTHORIZED, message);
|
|
543
|
+
}
|
|
544
|
+
throw new DataConnectError(Code.OTHER, message);
|
|
469
545
|
}
|
|
470
546
|
return jsonResponse;
|
|
471
547
|
})
|
|
@@ -477,6 +553,12 @@ function dcFetch(url, body, { signal }, accessToken) {
|
|
|
477
553
|
}
|
|
478
554
|
return res;
|
|
479
555
|
});
|
|
556
|
+
}
|
|
557
|
+
function getMessage(obj) {
|
|
558
|
+
if ('message' in obj) {
|
|
559
|
+
return obj.message;
|
|
560
|
+
}
|
|
561
|
+
return JSON.stringify(obj);
|
|
480
562
|
}
|
|
481
563
|
|
|
482
564
|
/**
|
|
@@ -496,41 +578,44 @@ function dcFetch(url, body, { signal }, accessToken) {
|
|
|
496
578
|
* limitations under the License.
|
|
497
579
|
*/
|
|
498
580
|
class RESTTransport {
|
|
499
|
-
constructor(options, apiKey, authProvider, transportOptions) {
|
|
500
|
-
var _a;
|
|
581
|
+
constructor(options, apiKey, appId, authProvider, appCheckProvider, transportOptions, _isUsingGen = false) {
|
|
582
|
+
var _a, _b;
|
|
501
583
|
this.apiKey = apiKey;
|
|
584
|
+
this.appId = appId;
|
|
502
585
|
this.authProvider = authProvider;
|
|
586
|
+
this.appCheckProvider = appCheckProvider;
|
|
587
|
+
this._isUsingGen = _isUsingGen;
|
|
503
588
|
this._host = '';
|
|
504
589
|
this._location = 'l';
|
|
505
590
|
this._connectorName = '';
|
|
506
591
|
this._secure = true;
|
|
507
592
|
this._project = 'p';
|
|
508
593
|
this._accessToken = null;
|
|
509
|
-
this.
|
|
594
|
+
this._appCheckToken = null;
|
|
595
|
+
this._lastToken = null;
|
|
510
596
|
// TODO(mtewani): Update U to include shape of body defined in line 13.
|
|
511
597
|
this.invokeQuery = (queryName, body) => {
|
|
512
598
|
const abortController = new AbortController();
|
|
513
599
|
// TODO(mtewani): Update to proper value
|
|
514
|
-
const withAuth = this.
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
abortController, this._accessToken);
|
|
521
|
-
});
|
|
600
|
+
const withAuth = this.withRetry(() => dcFetch(addToken(`${this.endpointUrl}:executeQuery`, this.apiKey), {
|
|
601
|
+
name: `projects/${this._project}/locations/${this._location}/services/${this._serviceName}/connectors/${this._connectorName}`,
|
|
602
|
+
operationName: queryName,
|
|
603
|
+
variables: body
|
|
604
|
+
}, // TODO(mtewani): This is a patch, fix this.
|
|
605
|
+
abortController, this.appId, this._accessToken, this._appCheckToken, this._isUsingGen));
|
|
522
606
|
return {
|
|
523
|
-
then: withAuth.then.bind(withAuth)
|
|
607
|
+
then: withAuth.then.bind(withAuth),
|
|
608
|
+
catch: withAuth.catch.bind(withAuth)
|
|
524
609
|
};
|
|
525
610
|
};
|
|
526
611
|
this.invokeMutation = (mutationName, body) => {
|
|
527
612
|
const abortController = new AbortController();
|
|
528
|
-
const taskResult = this.
|
|
613
|
+
const taskResult = this.withRetry(() => {
|
|
529
614
|
return dcFetch(addToken(`${this.endpointUrl}:executeMutation`, this.apiKey), {
|
|
530
615
|
name: `projects/${this._project}/locations/${this._location}/services/${this._serviceName}/connectors/${this._connectorName}`,
|
|
531
616
|
operationName: mutationName,
|
|
532
617
|
variables: body
|
|
533
|
-
}, abortController, this._accessToken);
|
|
618
|
+
}, abortController, this.appId, this._accessToken, this._appCheckToken, this._isUsingGen);
|
|
534
619
|
});
|
|
535
620
|
return {
|
|
536
621
|
then: taskResult.then.bind(taskResult),
|
|
@@ -564,6 +649,11 @@ class RESTTransport {
|
|
|
564
649
|
logDebug(`New Token Available: ${token}`);
|
|
565
650
|
this._accessToken = token;
|
|
566
651
|
});
|
|
652
|
+
(_b = this.appCheckProvider) === null || _b === void 0 ? void 0 : _b.addTokenChangeListener(result => {
|
|
653
|
+
const { token } = result;
|
|
654
|
+
logDebug(`New App Check Token Available: ${token}`);
|
|
655
|
+
this._appCheckToken = token;
|
|
656
|
+
});
|
|
567
657
|
}
|
|
568
658
|
get endpointUrl() {
|
|
569
659
|
return urlBuilder({
|
|
@@ -585,26 +675,52 @@ class RESTTransport {
|
|
|
585
675
|
onTokenChanged(newToken) {
|
|
586
676
|
this._accessToken = newToken;
|
|
587
677
|
}
|
|
588
|
-
getWithAuth() {
|
|
678
|
+
async getWithAuth(forceToken = false) {
|
|
679
|
+
var _a;
|
|
589
680
|
let starterPromise = new Promise(resolve => resolve(this._accessToken));
|
|
590
|
-
if (
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
681
|
+
if (this.appCheckProvider) {
|
|
682
|
+
this._appCheckToken = (_a = (await this.appCheckProvider.getToken())) === null || _a === void 0 ? void 0 : _a.token;
|
|
683
|
+
}
|
|
684
|
+
if (this.authProvider) {
|
|
685
|
+
starterPromise = this.authProvider
|
|
686
|
+
.getToken(/*forceToken=*/ forceToken)
|
|
687
|
+
.then(data => {
|
|
688
|
+
if (!data) {
|
|
689
|
+
return null;
|
|
690
|
+
}
|
|
691
|
+
this._accessToken = data.accessToken;
|
|
692
|
+
return this._accessToken;
|
|
693
|
+
});
|
|
694
|
+
}
|
|
695
|
+
else {
|
|
696
|
+
starterPromise = new Promise(resolve => resolve(''));
|
|
605
697
|
}
|
|
606
698
|
return starterPromise;
|
|
607
699
|
}
|
|
700
|
+
_setLastToken(lastToken) {
|
|
701
|
+
this._lastToken = lastToken;
|
|
702
|
+
}
|
|
703
|
+
withRetry(promiseFactory, retry = false) {
|
|
704
|
+
let isNewToken = false;
|
|
705
|
+
return this.getWithAuth(retry)
|
|
706
|
+
.then(res => {
|
|
707
|
+
isNewToken = this._lastToken !== res;
|
|
708
|
+
this._lastToken = res;
|
|
709
|
+
return res;
|
|
710
|
+
})
|
|
711
|
+
.then(promiseFactory)
|
|
712
|
+
.catch(err => {
|
|
713
|
+
// Only retry if the result is unauthorized and the last token isn't the same as the new one.
|
|
714
|
+
if ('code' in err &&
|
|
715
|
+
err.code === Code.UNAUTHORIZED &&
|
|
716
|
+
!retry &&
|
|
717
|
+
isNewToken) {
|
|
718
|
+
logDebug('Retrying due to unauthorized');
|
|
719
|
+
return this.withRetry(promiseFactory, true);
|
|
720
|
+
}
|
|
721
|
+
throw err;
|
|
722
|
+
});
|
|
723
|
+
}
|
|
608
724
|
}
|
|
609
725
|
|
|
610
726
|
/**
|
|
@@ -623,16 +739,26 @@ class RESTTransport {
|
|
|
623
739
|
* See the License for the specific language governing permissions and
|
|
624
740
|
* limitations under the License.
|
|
625
741
|
*/
|
|
626
|
-
|
|
742
|
+
/**
|
|
743
|
+
*
|
|
744
|
+
* @param dcInstance Data Connect instance
|
|
745
|
+
* @param mutationName name of mutation
|
|
746
|
+
* @param variables variables to send with mutation
|
|
747
|
+
* @returns `MutationRef`
|
|
748
|
+
*/
|
|
749
|
+
function mutationRef(dcInstance, mutationName, variables) {
|
|
627
750
|
dcInstance.setInitialized();
|
|
628
751
|
const ref = {
|
|
629
752
|
dataConnect: dcInstance,
|
|
630
|
-
name:
|
|
753
|
+
name: mutationName,
|
|
631
754
|
refType: MUTATION_STR,
|
|
632
755
|
variables: variables
|
|
633
756
|
};
|
|
634
757
|
return ref;
|
|
635
758
|
}
|
|
759
|
+
/**
|
|
760
|
+
* @internal
|
|
761
|
+
*/
|
|
636
762
|
class MutationManager {
|
|
637
763
|
constructor(_transport) {
|
|
638
764
|
this._transport = _transport;
|
|
@@ -650,6 +776,11 @@ class MutationManager {
|
|
|
650
776
|
return withRefPromise;
|
|
651
777
|
}
|
|
652
778
|
}
|
|
779
|
+
/**
|
|
780
|
+
* Execute Mutation
|
|
781
|
+
* @param mutationRef mutation to execute
|
|
782
|
+
* @returns `MutationRef`
|
|
783
|
+
*/
|
|
653
784
|
function executeMutation(mutationRef) {
|
|
654
785
|
return mutationRef.dataConnect._mutationManager.executeMutation(mutationRef);
|
|
655
786
|
}
|
|
@@ -684,15 +815,21 @@ function parseOptions(fullHost) {
|
|
|
684
815
|
const port = Number(portAsString);
|
|
685
816
|
return { host, port, sslEnabled: isSecure };
|
|
686
817
|
}
|
|
818
|
+
/**
|
|
819
|
+
* Class representing Firebase Data Connect
|
|
820
|
+
*/
|
|
687
821
|
class DataConnect {
|
|
822
|
+
// @internal
|
|
688
823
|
constructor(app,
|
|
689
824
|
// TODO(mtewani): Replace with _dataConnectOptions in the future
|
|
690
|
-
dataConnectOptions, _authProvider) {
|
|
825
|
+
dataConnectOptions, _authProvider, _appCheckProvider) {
|
|
691
826
|
this.app = app;
|
|
692
827
|
this.dataConnectOptions = dataConnectOptions;
|
|
693
828
|
this._authProvider = _authProvider;
|
|
829
|
+
this._appCheckProvider = _appCheckProvider;
|
|
694
830
|
this.isEmulator = false;
|
|
695
|
-
this.
|
|
831
|
+
this._initialized = false;
|
|
832
|
+
this._isUsingGeneratedSdk = false;
|
|
696
833
|
if (typeof process !== 'undefined' && process.env) {
|
|
697
834
|
const host = process.env[FIREBASE_DATA_CONNECT_EMULATOR_HOST_VAR];
|
|
698
835
|
if (host) {
|
|
@@ -702,17 +839,25 @@ class DataConnect {
|
|
|
702
839
|
}
|
|
703
840
|
}
|
|
704
841
|
}
|
|
842
|
+
// @internal
|
|
843
|
+
_useGeneratedSdk() {
|
|
844
|
+
if (!this._isUsingGeneratedSdk) {
|
|
845
|
+
this._isUsingGeneratedSdk = true;
|
|
846
|
+
}
|
|
847
|
+
}
|
|
705
848
|
_delete() {
|
|
706
849
|
app._removeServiceInstance(this.app, 'data-connect', JSON.stringify(this.getSettings()));
|
|
707
850
|
return Promise.resolve();
|
|
708
851
|
}
|
|
852
|
+
// @internal
|
|
709
853
|
getSettings() {
|
|
710
854
|
const copy = JSON.parse(JSON.stringify(this.dataConnectOptions));
|
|
711
855
|
delete copy.projectId;
|
|
712
856
|
return copy;
|
|
713
857
|
}
|
|
858
|
+
// @internal
|
|
714
859
|
setInitialized() {
|
|
715
|
-
if (this.
|
|
860
|
+
if (this._initialized) {
|
|
716
861
|
return;
|
|
717
862
|
}
|
|
718
863
|
if (this._transportClass === undefined) {
|
|
@@ -722,16 +867,20 @@ class DataConnect {
|
|
|
722
867
|
if (this._authProvider) {
|
|
723
868
|
this._authTokenProvider = new FirebaseAuthProvider(this.app.name, this.app.options, this._authProvider);
|
|
724
869
|
}
|
|
725
|
-
this.
|
|
726
|
-
|
|
870
|
+
if (this._appCheckProvider) {
|
|
871
|
+
this._appCheckTokenProvider = new AppCheckTokenProvider(this.app.name, this._appCheckProvider);
|
|
872
|
+
}
|
|
873
|
+
this._initialized = true;
|
|
874
|
+
this._transport = new this._transportClass(this.dataConnectOptions, this.app.options.apiKey, this.app.options.appId, this._authTokenProvider, this._appCheckTokenProvider, undefined, this._isUsingGeneratedSdk);
|
|
727
875
|
if (this._transportOptions) {
|
|
728
876
|
this._transport.useEmulator(this._transportOptions.host, this._transportOptions.port, this._transportOptions.sslEnabled);
|
|
729
877
|
}
|
|
730
878
|
this._queryManager = new QueryManager(this._transport);
|
|
731
879
|
this._mutationManager = new MutationManager(this._transport);
|
|
732
880
|
}
|
|
881
|
+
// @internal
|
|
733
882
|
enableEmulator(transportOptions) {
|
|
734
|
-
if (this.
|
|
883
|
+
if (this._initialized) {
|
|
735
884
|
logError('enableEmulator called after initialization');
|
|
736
885
|
throw new DataConnectError(Code.ALREADY_INITIALIZED, 'DataConnect instance already initialized!');
|
|
737
886
|
}
|
|
@@ -739,6 +888,13 @@ class DataConnect {
|
|
|
739
888
|
this.isEmulator = true;
|
|
740
889
|
}
|
|
741
890
|
}
|
|
891
|
+
/**
|
|
892
|
+
* Connect to the DataConnect Emulator
|
|
893
|
+
* @param dc Data Connect instance
|
|
894
|
+
* @param host host of emulator server
|
|
895
|
+
* @param port port of emulator server
|
|
896
|
+
* @param sslEnabled use https
|
|
897
|
+
*/
|
|
742
898
|
function connectDataConnectEmulator(dc, host, port, sslEnabled = false) {
|
|
743
899
|
dc.enableEmulator({ host, port, sslEnabled });
|
|
744
900
|
}
|
|
@@ -753,7 +909,7 @@ function getDataConnect(appOrOptions, optionalOptions) {
|
|
|
753
909
|
dcOptions = optionalOptions;
|
|
754
910
|
app$1 = appOrOptions;
|
|
755
911
|
}
|
|
756
|
-
if (!app$1) {
|
|
912
|
+
if (!app$1 || Object.keys(app$1).length === 0) {
|
|
757
913
|
app$1 = app.getApp();
|
|
758
914
|
}
|
|
759
915
|
const provider = app._getProvider(app$1, 'data-connect');
|
|
@@ -767,9 +923,7 @@ function getDataConnect(appOrOptions, optionalOptions) {
|
|
|
767
923
|
return dcInstance;
|
|
768
924
|
}
|
|
769
925
|
}
|
|
770
|
-
|
|
771
|
-
throw new DataConnectError(Code.INVALID_ARGUMENT, 'DC Option Required');
|
|
772
|
-
}
|
|
926
|
+
validateDCOptions(dcOptions);
|
|
773
927
|
logDebug('Creating new DataConnect instance');
|
|
774
928
|
// Initialize with options.
|
|
775
929
|
return provider.initialize({
|
|
@@ -777,6 +931,29 @@ function getDataConnect(appOrOptions, optionalOptions) {
|
|
|
777
931
|
options: dcOptions
|
|
778
932
|
});
|
|
779
933
|
}
|
|
934
|
+
/**
|
|
935
|
+
*
|
|
936
|
+
* @param dcOptions
|
|
937
|
+
* @returns {void}
|
|
938
|
+
* @internal
|
|
939
|
+
*/
|
|
940
|
+
function validateDCOptions(dcOptions) {
|
|
941
|
+
const fields = ['connector', 'location', 'service'];
|
|
942
|
+
if (!dcOptions) {
|
|
943
|
+
throw new DataConnectError(Code.INVALID_ARGUMENT, 'DC Option Required');
|
|
944
|
+
}
|
|
945
|
+
fields.forEach(field => {
|
|
946
|
+
if (dcOptions[field] === null || dcOptions[field] === undefined) {
|
|
947
|
+
throw new DataConnectError(Code.INVALID_ARGUMENT, `${field} Required`);
|
|
948
|
+
}
|
|
949
|
+
});
|
|
950
|
+
return true;
|
|
951
|
+
}
|
|
952
|
+
/**
|
|
953
|
+
* Delete DataConnect instance
|
|
954
|
+
* @param dataConnect DataConnect instance
|
|
955
|
+
* @returns
|
|
956
|
+
*/
|
|
780
957
|
function terminate(dataConnect) {
|
|
781
958
|
return dataConnect._delete();
|
|
782
959
|
// TODO(mtewani): Stop pending tasks
|
|
@@ -803,11 +980,15 @@ function registerDataConnect(variant) {
|
|
|
803
980
|
app._registerComponent(new component.Component('data-connect', (container, { instanceIdentifier: settings, options }) => {
|
|
804
981
|
const app = container.getProvider('app').getImmediate();
|
|
805
982
|
const authProvider = container.getProvider('auth-internal');
|
|
983
|
+
const appCheckProvider = container.getProvider('app-check-internal');
|
|
806
984
|
let newOpts = options;
|
|
807
985
|
if (settings) {
|
|
808
986
|
newOpts = JSON.parse(settings);
|
|
809
987
|
}
|
|
810
|
-
|
|
988
|
+
if (!app.options.projectId) {
|
|
989
|
+
throw new DataConnectError(Code.INVALID_ARGUMENT, 'Project ID must be provided. Did you pass in a proper projectId to initializeApp?');
|
|
990
|
+
}
|
|
991
|
+
return new DataConnect(app, Object.assign(Object.assign({}, newOpts), { projectId: app.options.projectId }), authProvider, appCheckProvider);
|
|
811
992
|
}, "PUBLIC" /* ComponentType.PUBLIC */).setMultipleInstances(true));
|
|
812
993
|
app.registerVersion(name, version, variant);
|
|
813
994
|
// BUILD_TARGET will be replaced by values like esm5, esm2017, cjs5, etc during the compilation
|
|
@@ -830,9 +1011,22 @@ function registerDataConnect(variant) {
|
|
|
830
1011
|
* See the License for the specific language governing permissions and
|
|
831
1012
|
* limitations under the License.
|
|
832
1013
|
*/
|
|
1014
|
+
/**
|
|
1015
|
+
* Execute Query
|
|
1016
|
+
* @param queryRef query to execute.
|
|
1017
|
+
* @returns `QueryPromise`
|
|
1018
|
+
*/
|
|
833
1019
|
function executeQuery(queryRef) {
|
|
834
1020
|
return queryRef.dataConnect._queryManager.executeQuery(queryRef);
|
|
835
1021
|
}
|
|
1022
|
+
/**
|
|
1023
|
+
* Execute Query
|
|
1024
|
+
* @param dcInstance Data Connect instance to use.
|
|
1025
|
+
* @param queryName Query to execute
|
|
1026
|
+
* @param variables Variables to execute with
|
|
1027
|
+
* @param initialCache initial cache to use for client hydration
|
|
1028
|
+
* @returns `QueryRef`
|
|
1029
|
+
*/
|
|
836
1030
|
function queryRef(dcInstance, queryName, variables, initialCache) {
|
|
837
1031
|
dcInstance.setInitialized();
|
|
838
1032
|
dcInstance._queryManager.track(queryName, variables, initialCache);
|
|
@@ -843,6 +1037,11 @@ function queryRef(dcInstance, queryName, variables, initialCache) {
|
|
|
843
1037
|
variables: variables
|
|
844
1038
|
};
|
|
845
1039
|
}
|
|
1040
|
+
/**
|
|
1041
|
+
* Converts serialized ref to query ref
|
|
1042
|
+
* @param serializedRef ref to convert to `QueryRef`
|
|
1043
|
+
* @returns `QueryRef`
|
|
1044
|
+
*/
|
|
846
1045
|
function toQueryRef(serializedRef) {
|
|
847
1046
|
const { refInfo: { name, variables, connectorConfig } } = serializedRef;
|
|
848
1047
|
return queryRef(getDataConnect(connectorConfig), name, variables);
|
|
@@ -864,6 +1063,57 @@ function toQueryRef(serializedRef) {
|
|
|
864
1063
|
* See the License for the specific language governing permissions and
|
|
865
1064
|
* limitations under the License.
|
|
866
1065
|
*/
|
|
1066
|
+
/**
|
|
1067
|
+
* The generated SDK will allow the user to pass in either the variable or the data connect instance with the variable,
|
|
1068
|
+
* and this function validates the variables and returns back the DataConnect instance and variables based on the arguments passed in.
|
|
1069
|
+
* @param connectorConfig
|
|
1070
|
+
* @param dcOrVars
|
|
1071
|
+
* @param vars
|
|
1072
|
+
* @param validateVars
|
|
1073
|
+
* @returns {DataConnect} and {Variables} instance
|
|
1074
|
+
* @internal
|
|
1075
|
+
*/
|
|
1076
|
+
function validateArgs(connectorConfig, dcOrVars, vars, validateVars) {
|
|
1077
|
+
let dcInstance;
|
|
1078
|
+
let realVars;
|
|
1079
|
+
if (dcOrVars && 'enableEmulator' in dcOrVars) {
|
|
1080
|
+
dcInstance = dcOrVars;
|
|
1081
|
+
realVars = vars;
|
|
1082
|
+
}
|
|
1083
|
+
else {
|
|
1084
|
+
dcInstance = getDataConnect(connectorConfig);
|
|
1085
|
+
realVars = dcOrVars;
|
|
1086
|
+
}
|
|
1087
|
+
if (!dcInstance || (!realVars && validateVars)) {
|
|
1088
|
+
throw new DataConnectError(Code.INVALID_ARGUMENT, 'Variables required.');
|
|
1089
|
+
}
|
|
1090
|
+
return { dc: dcInstance, vars: realVars };
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1093
|
+
/**
|
|
1094
|
+
* @license
|
|
1095
|
+
* Copyright 2024 Google LLC
|
|
1096
|
+
*
|
|
1097
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
1098
|
+
* you may not use this file except in compliance with the License.
|
|
1099
|
+
* You may obtain a copy of the License at
|
|
1100
|
+
*
|
|
1101
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
1102
|
+
*
|
|
1103
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
1104
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
1105
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
1106
|
+
* See the License for the specific language governing permissions and
|
|
1107
|
+
* limitations under the License.
|
|
1108
|
+
*/
|
|
1109
|
+
/**
|
|
1110
|
+
* Subscribe to a `QueryRef`
|
|
1111
|
+
* @param queryRefOrSerializedResult query ref or serialized result.
|
|
1112
|
+
* @param observerOrOnNext observer object or next function.
|
|
1113
|
+
* @param onError Callback to call when error gets thrown.
|
|
1114
|
+
* @param onComplete Called when subscription completes.
|
|
1115
|
+
* @returns `SubscriptionOptions`
|
|
1116
|
+
*/
|
|
867
1117
|
function subscribe(queryRefOrSerializedResult, observerOrOnNext, onError, onComplete) {
|
|
868
1118
|
let ref;
|
|
869
1119
|
let initialCache;
|
|
@@ -903,8 +1153,6 @@ function subscribe(queryRefOrSerializedResult, observerOrOnNext, onError, onComp
|
|
|
903
1153
|
registerDataConnect();
|
|
904
1154
|
|
|
905
1155
|
exports.DataConnect = DataConnect;
|
|
906
|
-
exports.FIREBASE_DATA_CONNECT_EMULATOR_HOST_VAR = FIREBASE_DATA_CONNECT_EMULATOR_HOST_VAR;
|
|
907
|
-
exports.FirebaseAuthProvider = FirebaseAuthProvider;
|
|
908
1156
|
exports.MUTATION_STR = MUTATION_STR;
|
|
909
1157
|
exports.MutationManager = MutationManager;
|
|
910
1158
|
exports.QUERY_STR = QUERY_STR;
|
|
@@ -921,4 +1169,6 @@ exports.setLogLevel = setLogLevel;
|
|
|
921
1169
|
exports.subscribe = subscribe;
|
|
922
1170
|
exports.terminate = terminate;
|
|
923
1171
|
exports.toQueryRef = toQueryRef;
|
|
1172
|
+
exports.validateArgs = validateArgs;
|
|
1173
|
+
exports.validateDCOptions = validateDCOptions;
|
|
924
1174
|
//# sourceMappingURL=index.cjs.js.map
|