@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
|
@@ -25,7 +25,8 @@ const Code = {
|
|
|
25
25
|
NOT_INITIALIZED: 'not-initialized',
|
|
26
26
|
NOT_SUPPORTED: 'not-supported',
|
|
27
27
|
INVALID_ARGUMENT: 'invalid-argument',
|
|
28
|
-
PARTIAL_ERROR: 'partial-error'
|
|
28
|
+
PARTIAL_ERROR: 'partial-error',
|
|
29
|
+
UNAUTHORIZED: 'unauthorized'
|
|
29
30
|
};
|
|
30
31
|
/** An error returned by a DataConnect operation. */
|
|
31
32
|
class DataConnectError extends FirebaseError {
|
|
@@ -122,12 +123,20 @@ let connectFetch = globalThis.fetch;
|
|
|
122
123
|
function initializeFetch(fetchImpl) {
|
|
123
124
|
connectFetch = fetchImpl;
|
|
124
125
|
}
|
|
125
|
-
function
|
|
126
|
+
function getGoogApiClientValue(_isUsingGen) {
|
|
127
|
+
let str = 'gl-js/ fire/' + SDK_VERSION;
|
|
128
|
+
if (_isUsingGen) {
|
|
129
|
+
str += ' web/gen';
|
|
130
|
+
}
|
|
131
|
+
return str;
|
|
132
|
+
}
|
|
133
|
+
function dcFetch(url, body, { signal }, accessToken, _isUsingGen) {
|
|
126
134
|
if (!connectFetch) {
|
|
127
135
|
throw new DataConnectError(Code.OTHER, 'No Fetch Implementation detected!');
|
|
128
136
|
}
|
|
129
137
|
const headers = {
|
|
130
|
-
'Content-Type': 'application/json'
|
|
138
|
+
'Content-Type': 'application/json',
|
|
139
|
+
'X-Goog-Api-Client': getGoogApiClientValue(_isUsingGen)
|
|
131
140
|
};
|
|
132
141
|
if (accessToken) {
|
|
133
142
|
headers['X-Firebase-Auth-Token'] = accessToken;
|
|
@@ -139,8 +148,9 @@ function dcFetch(url, body, { signal }, accessToken) {
|
|
|
139
148
|
method: 'POST',
|
|
140
149
|
headers,
|
|
141
150
|
signal
|
|
142
|
-
})
|
|
143
|
-
|
|
151
|
+
})
|
|
152
|
+
.catch(err => {
|
|
153
|
+
throw new DataConnectError(Code.OTHER, 'Failed to fetch: ' + JSON.stringify(err));
|
|
144
154
|
})
|
|
145
155
|
.then(async (response) => {
|
|
146
156
|
let jsonResponse = null;
|
|
@@ -150,9 +160,13 @@ function dcFetch(url, body, { signal }, accessToken) {
|
|
|
150
160
|
catch (e) {
|
|
151
161
|
throw new DataConnectError(Code.OTHER, JSON.stringify(e));
|
|
152
162
|
}
|
|
163
|
+
const message = getMessage(jsonResponse);
|
|
153
164
|
if (response.status >= 400) {
|
|
154
165
|
logError('Error while performing request: ' + JSON.stringify(jsonResponse));
|
|
155
|
-
|
|
166
|
+
if (response.status === 401) {
|
|
167
|
+
throw new DataConnectError(Code.UNAUTHORIZED, message);
|
|
168
|
+
}
|
|
169
|
+
throw new DataConnectError(Code.OTHER, message);
|
|
156
170
|
}
|
|
157
171
|
return jsonResponse;
|
|
158
172
|
})
|
|
@@ -164,10 +178,16 @@ function dcFetch(url, body, { signal }, accessToken) {
|
|
|
164
178
|
}
|
|
165
179
|
return res;
|
|
166
180
|
});
|
|
181
|
+
}
|
|
182
|
+
function getMessage(obj) {
|
|
183
|
+
if ('message' in obj) {
|
|
184
|
+
return obj.message;
|
|
185
|
+
}
|
|
186
|
+
return JSON.stringify(obj);
|
|
167
187
|
}
|
|
168
188
|
|
|
169
189
|
const name = "@firebase/data-connect";
|
|
170
|
-
const version = "0.0.
|
|
190
|
+
const version = "0.0.3-dataconnect-preview.d986d4bf2";
|
|
171
191
|
|
|
172
192
|
/**
|
|
173
193
|
* @license
|
|
@@ -227,7 +247,8 @@ class FirebaseAuthProvider {
|
|
|
227
247
|
removeTokenChangeListener(listener) {
|
|
228
248
|
this._authProvider
|
|
229
249
|
.get()
|
|
230
|
-
.then(auth => auth.removeAuthTokenListener(listener))
|
|
250
|
+
.then(auth => auth.removeAuthTokenListener(listener))
|
|
251
|
+
.catch(err => logError(err));
|
|
231
252
|
}
|
|
232
253
|
}
|
|
233
254
|
|
|
@@ -495,10 +516,11 @@ function addToken(url, apiKey) {
|
|
|
495
516
|
* limitations under the License.
|
|
496
517
|
*/
|
|
497
518
|
class RESTTransport {
|
|
498
|
-
constructor(options, apiKey, authProvider, transportOptions) {
|
|
519
|
+
constructor(options, apiKey, authProvider, transportOptions, _isUsingGen = false) {
|
|
499
520
|
var _a;
|
|
500
521
|
this.apiKey = apiKey;
|
|
501
522
|
this.authProvider = authProvider;
|
|
523
|
+
this._isUsingGen = _isUsingGen;
|
|
502
524
|
this._host = '';
|
|
503
525
|
this._location = 'l';
|
|
504
526
|
this._connectorName = '';
|
|
@@ -506,30 +528,30 @@ class RESTTransport {
|
|
|
506
528
|
this._project = 'p';
|
|
507
529
|
this._accessToken = null;
|
|
508
530
|
this._authInitialized = false;
|
|
531
|
+
this._lastToken = null;
|
|
509
532
|
// TODO(mtewani): Update U to include shape of body defined in line 13.
|
|
510
533
|
this.invokeQuery = (queryName, body) => {
|
|
511
534
|
const abortController = new AbortController();
|
|
512
535
|
// TODO(mtewani): Update to proper value
|
|
513
|
-
const withAuth = this.
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
abortController, this._accessToken);
|
|
520
|
-
});
|
|
536
|
+
const withAuth = this.withRetry(() => dcFetch(addToken(`${this.endpointUrl}:executeQuery`, this.apiKey), {
|
|
537
|
+
name: `projects/${this._project}/locations/${this._location}/services/${this._serviceName}/connectors/${this._connectorName}`,
|
|
538
|
+
operationName: queryName,
|
|
539
|
+
variables: body
|
|
540
|
+
}, // TODO(mtewani): This is a patch, fix this.
|
|
541
|
+
abortController, this._accessToken, this._isUsingGen));
|
|
521
542
|
return {
|
|
522
|
-
then: withAuth.then.bind(withAuth)
|
|
543
|
+
then: withAuth.then.bind(withAuth),
|
|
544
|
+
catch: withAuth.catch.bind(withAuth)
|
|
523
545
|
};
|
|
524
546
|
};
|
|
525
547
|
this.invokeMutation = (mutationName, body) => {
|
|
526
548
|
const abortController = new AbortController();
|
|
527
|
-
const taskResult = this.
|
|
549
|
+
const taskResult = this.withRetry(() => {
|
|
528
550
|
return dcFetch(addToken(`${this.endpointUrl}:executeMutation`, this.apiKey), {
|
|
529
551
|
name: `projects/${this._project}/locations/${this._location}/services/${this._serviceName}/connectors/${this._connectorName}`,
|
|
530
552
|
operationName: mutationName,
|
|
531
553
|
variables: body
|
|
532
|
-
}, abortController, this._accessToken);
|
|
554
|
+
}, abortController, this._accessToken, this._isUsingGen);
|
|
533
555
|
});
|
|
534
556
|
return {
|
|
535
557
|
then: taskResult.then.bind(taskResult),
|
|
@@ -584,12 +606,12 @@ class RESTTransport {
|
|
|
584
606
|
onTokenChanged(newToken) {
|
|
585
607
|
this._accessToken = newToken;
|
|
586
608
|
}
|
|
587
|
-
getWithAuth() {
|
|
609
|
+
getWithAuth(forceToken = false) {
|
|
588
610
|
let starterPromise = new Promise(resolve => resolve(this._accessToken));
|
|
589
611
|
if (!this._authInitialized) {
|
|
590
612
|
if (this.authProvider) {
|
|
591
613
|
starterPromise = this.authProvider
|
|
592
|
-
.getToken(/*forceToken=*/
|
|
614
|
+
.getToken(/*forceToken=*/ forceToken)
|
|
593
615
|
.then(data => {
|
|
594
616
|
if (!data) {
|
|
595
617
|
return null;
|
|
@@ -604,6 +626,30 @@ class RESTTransport {
|
|
|
604
626
|
}
|
|
605
627
|
return starterPromise;
|
|
606
628
|
}
|
|
629
|
+
_setLastToken(lastToken) {
|
|
630
|
+
this._lastToken = lastToken;
|
|
631
|
+
}
|
|
632
|
+
withRetry(promiseFactory, retry = false) {
|
|
633
|
+
let isNewToken = false;
|
|
634
|
+
return this.getWithAuth(retry)
|
|
635
|
+
.then(res => {
|
|
636
|
+
isNewToken = this._lastToken !== res;
|
|
637
|
+
this._lastToken = res;
|
|
638
|
+
return res;
|
|
639
|
+
})
|
|
640
|
+
.then(promiseFactory)
|
|
641
|
+
.catch(err => {
|
|
642
|
+
// Only retry if the result is unauthorized and the last token isn't the same as the new one.
|
|
643
|
+
if ('code' in err &&
|
|
644
|
+
err.code === Code.UNAUTHORIZED &&
|
|
645
|
+
!retry &&
|
|
646
|
+
isNewToken) {
|
|
647
|
+
logDebug('Retrying due to unauthorized');
|
|
648
|
+
return this.withRetry(promiseFactory, true);
|
|
649
|
+
}
|
|
650
|
+
throw err;
|
|
651
|
+
});
|
|
652
|
+
}
|
|
607
653
|
}
|
|
608
654
|
|
|
609
655
|
/**
|
|
@@ -710,6 +756,7 @@ class DataConnect {
|
|
|
710
756
|
this._authProvider = _authProvider;
|
|
711
757
|
this.isEmulator = false;
|
|
712
758
|
this.initialized = false;
|
|
759
|
+
this._isUsingGeneratedSdk = false;
|
|
713
760
|
if (typeof process !== 'undefined' && process.env) {
|
|
714
761
|
const host = process.env[FIREBASE_DATA_CONNECT_EMULATOR_HOST_VAR];
|
|
715
762
|
if (host) {
|
|
@@ -719,6 +766,14 @@ class DataConnect {
|
|
|
719
766
|
}
|
|
720
767
|
}
|
|
721
768
|
}
|
|
769
|
+
/*
|
|
770
|
+
@internal
|
|
771
|
+
*/
|
|
772
|
+
_useGeneratedSdk() {
|
|
773
|
+
if (!this._isUsingGeneratedSdk) {
|
|
774
|
+
this._isUsingGeneratedSdk = true;
|
|
775
|
+
}
|
|
776
|
+
}
|
|
722
777
|
_delete() {
|
|
723
778
|
_removeServiceInstance(this.app, 'data-connect', JSON.stringify(this.getSettings()));
|
|
724
779
|
return Promise.resolve();
|
|
@@ -740,7 +795,7 @@ class DataConnect {
|
|
|
740
795
|
this._authTokenProvider = new FirebaseAuthProvider(this.app.name, this.app.options, this._authProvider);
|
|
741
796
|
}
|
|
742
797
|
this.initialized = true;
|
|
743
|
-
this._transport = new this._transportClass(this.dataConnectOptions, this.app.options.apiKey, this._authTokenProvider);
|
|
798
|
+
this._transport = new this._transportClass(this.dataConnectOptions, this.app.options.apiKey, this._authTokenProvider, undefined, this._isUsingGeneratedSdk);
|
|
744
799
|
if (this._transportOptions) {
|
|
745
800
|
this._transport.useEmulator(this._transportOptions.host, this._transportOptions.port, this._transportOptions.sslEnabled);
|
|
746
801
|
}
|
|
@@ -777,7 +832,7 @@ function getDataConnect(appOrOptions, optionalOptions) {
|
|
|
777
832
|
dcOptions = optionalOptions;
|
|
778
833
|
app = appOrOptions;
|
|
779
834
|
}
|
|
780
|
-
if (!app) {
|
|
835
|
+
if (!app || Object.keys(app).length === 0) {
|
|
781
836
|
app = getApp();
|
|
782
837
|
}
|
|
783
838
|
const provider = _getProvider(app, 'data-connect');
|
|
@@ -791,9 +846,7 @@ function getDataConnect(appOrOptions, optionalOptions) {
|
|
|
791
846
|
return dcInstance;
|
|
792
847
|
}
|
|
793
848
|
}
|
|
794
|
-
|
|
795
|
-
throw new DataConnectError(Code.INVALID_ARGUMENT, 'DC Option Required');
|
|
796
|
-
}
|
|
849
|
+
validateDCOptions(dcOptions);
|
|
797
850
|
logDebug('Creating new DataConnect instance');
|
|
798
851
|
// Initialize with options.
|
|
799
852
|
return provider.initialize({
|
|
@@ -801,6 +854,24 @@ function getDataConnect(appOrOptions, optionalOptions) {
|
|
|
801
854
|
options: dcOptions
|
|
802
855
|
});
|
|
803
856
|
}
|
|
857
|
+
/**
|
|
858
|
+
*
|
|
859
|
+
* @param dcOptions
|
|
860
|
+
* @returns {void}
|
|
861
|
+
* @internal
|
|
862
|
+
*/
|
|
863
|
+
function validateDCOptions(dcOptions) {
|
|
864
|
+
const fields = ['connector', 'location', 'service'];
|
|
865
|
+
if (!dcOptions) {
|
|
866
|
+
throw new DataConnectError(Code.INVALID_ARGUMENT, 'DC Option Required');
|
|
867
|
+
}
|
|
868
|
+
fields.forEach(field => {
|
|
869
|
+
if (dcOptions[field] === null || dcOptions[field] === undefined) {
|
|
870
|
+
throw new DataConnectError(Code.INVALID_ARGUMENT, `${field} Required`);
|
|
871
|
+
}
|
|
872
|
+
});
|
|
873
|
+
return true;
|
|
874
|
+
}
|
|
804
875
|
/**
|
|
805
876
|
* Delete DataConnect instance
|
|
806
877
|
* @param dataConnect DataConnect instance
|
|
@@ -836,6 +907,9 @@ function registerDataConnect(variant) {
|
|
|
836
907
|
if (settings) {
|
|
837
908
|
newOpts = JSON.parse(settings);
|
|
838
909
|
}
|
|
910
|
+
if (!app.options.projectId) {
|
|
911
|
+
throw new DataConnectError(Code.INVALID_ARGUMENT, 'Project ID must be provided. Did you pass in a proper projectId to initializeApp?');
|
|
912
|
+
}
|
|
839
913
|
return new DataConnect(app, Object.assign(Object.assign({}, newOpts), { projectId: app.options.projectId }), authProvider);
|
|
840
914
|
}, "PUBLIC" /* ComponentType.PUBLIC */).setMultipleInstances(true));
|
|
841
915
|
registerVersion(name, version, variant);
|
|
@@ -895,6 +969,49 @@ function toQueryRef(serializedRef) {
|
|
|
895
969
|
return queryRef(getDataConnect(connectorConfig), name, variables);
|
|
896
970
|
}
|
|
897
971
|
|
|
972
|
+
/**
|
|
973
|
+
* @license
|
|
974
|
+
* Copyright 2024 Google LLC
|
|
975
|
+
*
|
|
976
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
977
|
+
* you may not use this file except in compliance with the License.
|
|
978
|
+
* You may obtain a copy of the License at
|
|
979
|
+
*
|
|
980
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
981
|
+
*
|
|
982
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
983
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
984
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
985
|
+
* See the License for the specific language governing permissions and
|
|
986
|
+
* limitations under the License.
|
|
987
|
+
*/
|
|
988
|
+
/**
|
|
989
|
+
* The generated SDK will allow the user to pass in either the variable or the data connect instance with the variable,
|
|
990
|
+
* and this function validates the variables and returns back the DataConnect instance and variables based on the arguments passed in.
|
|
991
|
+
* @param connectorConfig
|
|
992
|
+
* @param dcOrVars
|
|
993
|
+
* @param vars
|
|
994
|
+
* @param validateVars
|
|
995
|
+
* @returns {DataConnect} and {Variables} instance
|
|
996
|
+
* @internal
|
|
997
|
+
*/
|
|
998
|
+
function validateArgs(connectorConfig, dcOrVars, vars, validateVars) {
|
|
999
|
+
let dcInstance;
|
|
1000
|
+
let realVars;
|
|
1001
|
+
if (dcOrVars && 'enableEmulator' in dcOrVars) {
|
|
1002
|
+
dcInstance = dcOrVars;
|
|
1003
|
+
realVars = vars;
|
|
1004
|
+
}
|
|
1005
|
+
else {
|
|
1006
|
+
dcInstance = getDataConnect(connectorConfig);
|
|
1007
|
+
realVars = dcOrVars;
|
|
1008
|
+
}
|
|
1009
|
+
if (!dcInstance || (!realVars && validateVars)) {
|
|
1010
|
+
throw new DataConnectError(Code.INVALID_ARGUMENT, 'Variables required.');
|
|
1011
|
+
}
|
|
1012
|
+
return { dc: dcInstance, vars: realVars };
|
|
1013
|
+
}
|
|
1014
|
+
|
|
898
1015
|
/**
|
|
899
1016
|
* @license
|
|
900
1017
|
* Copyright 2024 Google LLC
|
|
@@ -969,5 +1086,5 @@ function subscribe(queryRefOrSerializedResult, observerOrOnNext, onError, onComp
|
|
|
969
1086
|
initializeFetch(fetch);
|
|
970
1087
|
registerDataConnect('node');
|
|
971
1088
|
|
|
972
|
-
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 };
|
|
1089
|
+
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 };
|
|
973
1090
|
//# sourceMappingURL=index.node.esm.js.map
|