@firebase/data-connect 0.0.2-dataconnect-preview.388b61c7e → 0.0.3-dataconnect-preview.d986d4bf2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs.js +146 -27
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm2017.js +145 -28
- package/dist/index.esm2017.js.map +1 -1
- package/dist/index.esm5.js +146 -23
- package/dist/index.esm5.js.map +1 -1
- package/dist/index.node.cjs.js +147 -22
- package/dist/index.node.cjs.js.map +1 -1
- package/dist/internal.d.ts +32 -5
- package/dist/node-esm/index.node.esm.js +145 -28
- package/dist/node-esm/index.node.esm.js.map +1 -1
- package/dist/node-esm/src/api/DataConnect.d.ts +9 -0
- package/dist/node-esm/src/api/index.d.ts +1 -0
- package/dist/node-esm/src/api/query.d.ts +1 -1
- 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 +1 -1
- package/dist/node-esm/src/network/transport/rest.d.ts +20 -9
- package/dist/node-esm/src/util/validateArgs.d.ts +33 -0
- package/dist/private.d.ts +16 -5
- package/dist/public.d.ts +5 -3
- package/dist/src/api/DataConnect.d.ts +9 -0
- package/dist/src/api/index.d.ts +1 -0
- package/dist/src/api/query.d.ts +1 -1
- 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 +1 -1
- package/dist/src/network/transport/rest.d.ts +20 -9
- package/dist/src/util/validateArgs.d.ts +33 -0
- package/package.json +10 -6
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-dataconnect-preview.d986d4bf2";
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* @license
|
|
@@ -54,7 +54,8 @@ const Code = {
|
|
|
54
54
|
NOT_INITIALIZED: 'not-initialized',
|
|
55
55
|
NOT_SUPPORTED: 'not-supported',
|
|
56
56
|
INVALID_ARGUMENT: 'invalid-argument',
|
|
57
|
-
PARTIAL_ERROR: 'partial-error'
|
|
57
|
+
PARTIAL_ERROR: 'partial-error',
|
|
58
|
+
UNAUTHORIZED: 'unauthorized'
|
|
58
59
|
};
|
|
59
60
|
/** An error returned by a DataConnect operation. */
|
|
60
61
|
class DataConnectError extends FirebaseError {
|
|
@@ -163,7 +164,8 @@ class FirebaseAuthProvider {
|
|
|
163
164
|
removeTokenChangeListener(listener) {
|
|
164
165
|
this._authProvider
|
|
165
166
|
.get()
|
|
166
|
-
.then(auth => auth.removeAuthTokenListener(listener))
|
|
167
|
+
.then(auth => auth.removeAuthTokenListener(listener))
|
|
168
|
+
.catch(err => logError(err));
|
|
167
169
|
}
|
|
168
170
|
}
|
|
169
171
|
|
|
@@ -431,12 +433,20 @@ function addToken(url, apiKey) {
|
|
|
431
433
|
* limitations under the License.
|
|
432
434
|
*/
|
|
433
435
|
let connectFetch = globalThis.fetch;
|
|
434
|
-
function
|
|
436
|
+
function getGoogApiClientValue(_isUsingGen) {
|
|
437
|
+
let str = 'gl-js/ fire/' + SDK_VERSION;
|
|
438
|
+
if (_isUsingGen) {
|
|
439
|
+
str += ' web/gen';
|
|
440
|
+
}
|
|
441
|
+
return str;
|
|
442
|
+
}
|
|
443
|
+
function dcFetch(url, body, { signal }, accessToken, _isUsingGen) {
|
|
435
444
|
if (!connectFetch) {
|
|
436
445
|
throw new DataConnectError(Code.OTHER, 'No Fetch Implementation detected!');
|
|
437
446
|
}
|
|
438
447
|
const headers = {
|
|
439
|
-
'Content-Type': 'application/json'
|
|
448
|
+
'Content-Type': 'application/json',
|
|
449
|
+
'X-Goog-Api-Client': getGoogApiClientValue(_isUsingGen)
|
|
440
450
|
};
|
|
441
451
|
if (accessToken) {
|
|
442
452
|
headers['X-Firebase-Auth-Token'] = accessToken;
|
|
@@ -448,8 +458,9 @@ function dcFetch(url, body, { signal }, accessToken) {
|
|
|
448
458
|
method: 'POST',
|
|
449
459
|
headers,
|
|
450
460
|
signal
|
|
451
|
-
})
|
|
452
|
-
|
|
461
|
+
})
|
|
462
|
+
.catch(err => {
|
|
463
|
+
throw new DataConnectError(Code.OTHER, 'Failed to fetch: ' + JSON.stringify(err));
|
|
453
464
|
})
|
|
454
465
|
.then(async (response) => {
|
|
455
466
|
let jsonResponse = null;
|
|
@@ -459,9 +470,13 @@ function dcFetch(url, body, { signal }, accessToken) {
|
|
|
459
470
|
catch (e) {
|
|
460
471
|
throw new DataConnectError(Code.OTHER, JSON.stringify(e));
|
|
461
472
|
}
|
|
473
|
+
const message = getMessage(jsonResponse);
|
|
462
474
|
if (response.status >= 400) {
|
|
463
475
|
logError('Error while performing request: ' + JSON.stringify(jsonResponse));
|
|
464
|
-
|
|
476
|
+
if (response.status === 401) {
|
|
477
|
+
throw new DataConnectError(Code.UNAUTHORIZED, message);
|
|
478
|
+
}
|
|
479
|
+
throw new DataConnectError(Code.OTHER, message);
|
|
465
480
|
}
|
|
466
481
|
return jsonResponse;
|
|
467
482
|
})
|
|
@@ -473,6 +488,12 @@ function dcFetch(url, body, { signal }, accessToken) {
|
|
|
473
488
|
}
|
|
474
489
|
return res;
|
|
475
490
|
});
|
|
491
|
+
}
|
|
492
|
+
function getMessage(obj) {
|
|
493
|
+
if ('message' in obj) {
|
|
494
|
+
return obj.message;
|
|
495
|
+
}
|
|
496
|
+
return JSON.stringify(obj);
|
|
476
497
|
}
|
|
477
498
|
|
|
478
499
|
/**
|
|
@@ -492,10 +513,11 @@ function dcFetch(url, body, { signal }, accessToken) {
|
|
|
492
513
|
* limitations under the License.
|
|
493
514
|
*/
|
|
494
515
|
class RESTTransport {
|
|
495
|
-
constructor(options, apiKey, authProvider, transportOptions) {
|
|
516
|
+
constructor(options, apiKey, authProvider, transportOptions, _isUsingGen = false) {
|
|
496
517
|
var _a;
|
|
497
518
|
this.apiKey = apiKey;
|
|
498
519
|
this.authProvider = authProvider;
|
|
520
|
+
this._isUsingGen = _isUsingGen;
|
|
499
521
|
this._host = '';
|
|
500
522
|
this._location = 'l';
|
|
501
523
|
this._connectorName = '';
|
|
@@ -503,30 +525,30 @@ class RESTTransport {
|
|
|
503
525
|
this._project = 'p';
|
|
504
526
|
this._accessToken = null;
|
|
505
527
|
this._authInitialized = false;
|
|
528
|
+
this._lastToken = null;
|
|
506
529
|
// TODO(mtewani): Update U to include shape of body defined in line 13.
|
|
507
530
|
this.invokeQuery = (queryName, body) => {
|
|
508
531
|
const abortController = new AbortController();
|
|
509
532
|
// TODO(mtewani): Update to proper value
|
|
510
|
-
const withAuth = this.
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
abortController, this._accessToken);
|
|
517
|
-
});
|
|
533
|
+
const withAuth = this.withRetry(() => dcFetch(addToken(`${this.endpointUrl}:executeQuery`, this.apiKey), {
|
|
534
|
+
name: `projects/${this._project}/locations/${this._location}/services/${this._serviceName}/connectors/${this._connectorName}`,
|
|
535
|
+
operationName: queryName,
|
|
536
|
+
variables: body
|
|
537
|
+
}, // TODO(mtewani): This is a patch, fix this.
|
|
538
|
+
abortController, this._accessToken, this._isUsingGen));
|
|
518
539
|
return {
|
|
519
|
-
then: withAuth.then.bind(withAuth)
|
|
540
|
+
then: withAuth.then.bind(withAuth),
|
|
541
|
+
catch: withAuth.catch.bind(withAuth)
|
|
520
542
|
};
|
|
521
543
|
};
|
|
522
544
|
this.invokeMutation = (mutationName, body) => {
|
|
523
545
|
const abortController = new AbortController();
|
|
524
|
-
const taskResult = this.
|
|
546
|
+
const taskResult = this.withRetry(() => {
|
|
525
547
|
return dcFetch(addToken(`${this.endpointUrl}:executeMutation`, this.apiKey), {
|
|
526
548
|
name: `projects/${this._project}/locations/${this._location}/services/${this._serviceName}/connectors/${this._connectorName}`,
|
|
527
549
|
operationName: mutationName,
|
|
528
550
|
variables: body
|
|
529
|
-
}, abortController, this._accessToken);
|
|
551
|
+
}, abortController, this._accessToken, this._isUsingGen);
|
|
530
552
|
});
|
|
531
553
|
return {
|
|
532
554
|
then: taskResult.then.bind(taskResult),
|
|
@@ -581,12 +603,12 @@ class RESTTransport {
|
|
|
581
603
|
onTokenChanged(newToken) {
|
|
582
604
|
this._accessToken = newToken;
|
|
583
605
|
}
|
|
584
|
-
getWithAuth() {
|
|
606
|
+
getWithAuth(forceToken = false) {
|
|
585
607
|
let starterPromise = new Promise(resolve => resolve(this._accessToken));
|
|
586
608
|
if (!this._authInitialized) {
|
|
587
609
|
if (this.authProvider) {
|
|
588
610
|
starterPromise = this.authProvider
|
|
589
|
-
.getToken(/*forceToken=*/
|
|
611
|
+
.getToken(/*forceToken=*/ forceToken)
|
|
590
612
|
.then(data => {
|
|
591
613
|
if (!data) {
|
|
592
614
|
return null;
|
|
@@ -601,6 +623,30 @@ class RESTTransport {
|
|
|
601
623
|
}
|
|
602
624
|
return starterPromise;
|
|
603
625
|
}
|
|
626
|
+
_setLastToken(lastToken) {
|
|
627
|
+
this._lastToken = lastToken;
|
|
628
|
+
}
|
|
629
|
+
withRetry(promiseFactory, retry = false) {
|
|
630
|
+
let isNewToken = false;
|
|
631
|
+
return this.getWithAuth(retry)
|
|
632
|
+
.then(res => {
|
|
633
|
+
isNewToken = this._lastToken !== res;
|
|
634
|
+
this._lastToken = res;
|
|
635
|
+
return res;
|
|
636
|
+
})
|
|
637
|
+
.then(promiseFactory)
|
|
638
|
+
.catch(err => {
|
|
639
|
+
// Only retry if the result is unauthorized and the last token isn't the same as the new one.
|
|
640
|
+
if ('code' in err &&
|
|
641
|
+
err.code === Code.UNAUTHORIZED &&
|
|
642
|
+
!retry &&
|
|
643
|
+
isNewToken) {
|
|
644
|
+
logDebug('Retrying due to unauthorized');
|
|
645
|
+
return this.withRetry(promiseFactory, true);
|
|
646
|
+
}
|
|
647
|
+
throw err;
|
|
648
|
+
});
|
|
649
|
+
}
|
|
604
650
|
}
|
|
605
651
|
|
|
606
652
|
/**
|
|
@@ -707,6 +753,7 @@ class DataConnect {
|
|
|
707
753
|
this._authProvider = _authProvider;
|
|
708
754
|
this.isEmulator = false;
|
|
709
755
|
this.initialized = false;
|
|
756
|
+
this._isUsingGeneratedSdk = false;
|
|
710
757
|
if (typeof process !== 'undefined' && process.env) {
|
|
711
758
|
const host = process.env[FIREBASE_DATA_CONNECT_EMULATOR_HOST_VAR];
|
|
712
759
|
if (host) {
|
|
@@ -716,6 +763,14 @@ class DataConnect {
|
|
|
716
763
|
}
|
|
717
764
|
}
|
|
718
765
|
}
|
|
766
|
+
/*
|
|
767
|
+
@internal
|
|
768
|
+
*/
|
|
769
|
+
_useGeneratedSdk() {
|
|
770
|
+
if (!this._isUsingGeneratedSdk) {
|
|
771
|
+
this._isUsingGeneratedSdk = true;
|
|
772
|
+
}
|
|
773
|
+
}
|
|
719
774
|
_delete() {
|
|
720
775
|
_removeServiceInstance(this.app, 'data-connect', JSON.stringify(this.getSettings()));
|
|
721
776
|
return Promise.resolve();
|
|
@@ -737,7 +792,7 @@ class DataConnect {
|
|
|
737
792
|
this._authTokenProvider = new FirebaseAuthProvider(this.app.name, this.app.options, this._authProvider);
|
|
738
793
|
}
|
|
739
794
|
this.initialized = true;
|
|
740
|
-
this._transport = new this._transportClass(this.dataConnectOptions, this.app.options.apiKey, this._authTokenProvider);
|
|
795
|
+
this._transport = new this._transportClass(this.dataConnectOptions, this.app.options.apiKey, this._authTokenProvider, undefined, this._isUsingGeneratedSdk);
|
|
741
796
|
if (this._transportOptions) {
|
|
742
797
|
this._transport.useEmulator(this._transportOptions.host, this._transportOptions.port, this._transportOptions.sslEnabled);
|
|
743
798
|
}
|
|
@@ -774,7 +829,7 @@ function getDataConnect(appOrOptions, optionalOptions) {
|
|
|
774
829
|
dcOptions = optionalOptions;
|
|
775
830
|
app = appOrOptions;
|
|
776
831
|
}
|
|
777
|
-
if (!app) {
|
|
832
|
+
if (!app || Object.keys(app).length === 0) {
|
|
778
833
|
app = getApp();
|
|
779
834
|
}
|
|
780
835
|
const provider = _getProvider(app, 'data-connect');
|
|
@@ -788,9 +843,7 @@ function getDataConnect(appOrOptions, optionalOptions) {
|
|
|
788
843
|
return dcInstance;
|
|
789
844
|
}
|
|
790
845
|
}
|
|
791
|
-
|
|
792
|
-
throw new DataConnectError(Code.INVALID_ARGUMENT, 'DC Option Required');
|
|
793
|
-
}
|
|
846
|
+
validateDCOptions(dcOptions);
|
|
794
847
|
logDebug('Creating new DataConnect instance');
|
|
795
848
|
// Initialize with options.
|
|
796
849
|
return provider.initialize({
|
|
@@ -798,6 +851,24 @@ function getDataConnect(appOrOptions, optionalOptions) {
|
|
|
798
851
|
options: dcOptions
|
|
799
852
|
});
|
|
800
853
|
}
|
|
854
|
+
/**
|
|
855
|
+
*
|
|
856
|
+
* @param dcOptions
|
|
857
|
+
* @returns {void}
|
|
858
|
+
* @internal
|
|
859
|
+
*/
|
|
860
|
+
function validateDCOptions(dcOptions) {
|
|
861
|
+
const fields = ['connector', 'location', 'service'];
|
|
862
|
+
if (!dcOptions) {
|
|
863
|
+
throw new DataConnectError(Code.INVALID_ARGUMENT, 'DC Option Required');
|
|
864
|
+
}
|
|
865
|
+
fields.forEach(field => {
|
|
866
|
+
if (dcOptions[field] === null || dcOptions[field] === undefined) {
|
|
867
|
+
throw new DataConnectError(Code.INVALID_ARGUMENT, `${field} Required`);
|
|
868
|
+
}
|
|
869
|
+
});
|
|
870
|
+
return true;
|
|
871
|
+
}
|
|
801
872
|
/**
|
|
802
873
|
* Delete DataConnect instance
|
|
803
874
|
* @param dataConnect DataConnect instance
|
|
@@ -833,6 +904,9 @@ function registerDataConnect(variant) {
|
|
|
833
904
|
if (settings) {
|
|
834
905
|
newOpts = JSON.parse(settings);
|
|
835
906
|
}
|
|
907
|
+
if (!app.options.projectId) {
|
|
908
|
+
throw new DataConnectError(Code.INVALID_ARGUMENT, 'Project ID must be provided. Did you pass in a proper projectId to initializeApp?');
|
|
909
|
+
}
|
|
836
910
|
return new DataConnect(app, Object.assign(Object.assign({}, newOpts), { projectId: app.options.projectId }), authProvider);
|
|
837
911
|
}, "PUBLIC" /* ComponentType.PUBLIC */).setMultipleInstances(true));
|
|
838
912
|
registerVersion(name, version, variant);
|
|
@@ -892,6 +966,49 @@ function toQueryRef(serializedRef) {
|
|
|
892
966
|
return queryRef(getDataConnect(connectorConfig), name, variables);
|
|
893
967
|
}
|
|
894
968
|
|
|
969
|
+
/**
|
|
970
|
+
* @license
|
|
971
|
+
* Copyright 2024 Google LLC
|
|
972
|
+
*
|
|
973
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
974
|
+
* you may not use this file except in compliance with the License.
|
|
975
|
+
* You may obtain a copy of the License at
|
|
976
|
+
*
|
|
977
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
978
|
+
*
|
|
979
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
980
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
981
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
982
|
+
* See the License for the specific language governing permissions and
|
|
983
|
+
* limitations under the License.
|
|
984
|
+
*/
|
|
985
|
+
/**
|
|
986
|
+
* The generated SDK will allow the user to pass in either the variable or the data connect instance with the variable,
|
|
987
|
+
* and this function validates the variables and returns back the DataConnect instance and variables based on the arguments passed in.
|
|
988
|
+
* @param connectorConfig
|
|
989
|
+
* @param dcOrVars
|
|
990
|
+
* @param vars
|
|
991
|
+
* @param validateVars
|
|
992
|
+
* @returns {DataConnect} and {Variables} instance
|
|
993
|
+
* @internal
|
|
994
|
+
*/
|
|
995
|
+
function validateArgs(connectorConfig, dcOrVars, vars, validateVars) {
|
|
996
|
+
let dcInstance;
|
|
997
|
+
let realVars;
|
|
998
|
+
if (dcOrVars && 'enableEmulator' in dcOrVars) {
|
|
999
|
+
dcInstance = dcOrVars;
|
|
1000
|
+
realVars = vars;
|
|
1001
|
+
}
|
|
1002
|
+
else {
|
|
1003
|
+
dcInstance = getDataConnect(connectorConfig);
|
|
1004
|
+
realVars = dcOrVars;
|
|
1005
|
+
}
|
|
1006
|
+
if (!dcInstance || (!realVars && validateVars)) {
|
|
1007
|
+
throw new DataConnectError(Code.INVALID_ARGUMENT, 'Variables required.');
|
|
1008
|
+
}
|
|
1009
|
+
return { dc: dcInstance, vars: realVars };
|
|
1010
|
+
}
|
|
1011
|
+
|
|
895
1012
|
/**
|
|
896
1013
|
* @license
|
|
897
1014
|
* Copyright 2024 Google LLC
|
|
@@ -954,5 +1071,5 @@ function subscribe(queryRefOrSerializedResult, observerOrOnNext, onError, onComp
|
|
|
954
1071
|
*/
|
|
955
1072
|
registerDataConnect();
|
|
956
1073
|
|
|
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 };
|
|
1074
|
+
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, validateArgs, validateDCOptions };
|
|
958
1075
|
//# sourceMappingURL=index.esm2017.js.map
|