@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
|
@@ -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,16 +123,30 @@ 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 }, appId, accessToken, appCheckToken, _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;
|
|
134
143
|
}
|
|
144
|
+
if (appId) {
|
|
145
|
+
headers['x-firebase-gmpid'] = appId;
|
|
146
|
+
}
|
|
147
|
+
if (appCheckToken) {
|
|
148
|
+
headers['X-Firebase-AppCheck'] = appCheckToken;
|
|
149
|
+
}
|
|
135
150
|
const bodyStr = JSON.stringify(body);
|
|
136
151
|
logDebug(`Making request out to ${url} with body: ${bodyStr}`);
|
|
137
152
|
return connectFetch(url, {
|
|
@@ -139,8 +154,9 @@ function dcFetch(url, body, { signal }, accessToken) {
|
|
|
139
154
|
method: 'POST',
|
|
140
155
|
headers,
|
|
141
156
|
signal
|
|
142
|
-
})
|
|
143
|
-
|
|
157
|
+
})
|
|
158
|
+
.catch(err => {
|
|
159
|
+
throw new DataConnectError(Code.OTHER, 'Failed to fetch: ' + JSON.stringify(err));
|
|
144
160
|
})
|
|
145
161
|
.then(async (response) => {
|
|
146
162
|
let jsonResponse = null;
|
|
@@ -150,9 +166,13 @@ function dcFetch(url, body, { signal }, accessToken) {
|
|
|
150
166
|
catch (e) {
|
|
151
167
|
throw new DataConnectError(Code.OTHER, JSON.stringify(e));
|
|
152
168
|
}
|
|
169
|
+
const message = getMessage(jsonResponse);
|
|
153
170
|
if (response.status >= 400) {
|
|
154
171
|
logError('Error while performing request: ' + JSON.stringify(jsonResponse));
|
|
155
|
-
|
|
172
|
+
if (response.status === 401) {
|
|
173
|
+
throw new DataConnectError(Code.UNAUTHORIZED, message);
|
|
174
|
+
}
|
|
175
|
+
throw new DataConnectError(Code.OTHER, message);
|
|
156
176
|
}
|
|
157
177
|
return jsonResponse;
|
|
158
178
|
})
|
|
@@ -164,10 +184,16 @@ function dcFetch(url, body, { signal }, accessToken) {
|
|
|
164
184
|
}
|
|
165
185
|
return res;
|
|
166
186
|
});
|
|
187
|
+
}
|
|
188
|
+
function getMessage(obj) {
|
|
189
|
+
if ('message' in obj) {
|
|
190
|
+
return obj.message;
|
|
191
|
+
}
|
|
192
|
+
return JSON.stringify(obj);
|
|
167
193
|
}
|
|
168
194
|
|
|
169
195
|
const name = "@firebase/data-connect";
|
|
170
|
-
const version = "0.0.
|
|
196
|
+
const version = "0.0.3-canary.beaa4dffb";
|
|
171
197
|
|
|
172
198
|
/**
|
|
173
199
|
* @license
|
|
@@ -185,6 +211,61 @@ const version = "0.0.2-dataconnect-preview.877f8b7d0";
|
|
|
185
211
|
* See the License for the specific language governing permissions and
|
|
186
212
|
* limitations under the License.
|
|
187
213
|
*/
|
|
214
|
+
/**
|
|
215
|
+
* @internal
|
|
216
|
+
* Abstraction around AppCheck's token fetching capabilities.
|
|
217
|
+
*/
|
|
218
|
+
class AppCheckTokenProvider {
|
|
219
|
+
constructor(appName_, appCheckProvider) {
|
|
220
|
+
this.appName_ = appName_;
|
|
221
|
+
this.appCheckProvider = appCheckProvider;
|
|
222
|
+
this.appCheck = appCheckProvider === null || appCheckProvider === void 0 ? void 0 : appCheckProvider.getImmediate({ optional: true });
|
|
223
|
+
if (!this.appCheck) {
|
|
224
|
+
void (appCheckProvider === null || appCheckProvider === void 0 ? void 0 : appCheckProvider.get().then(appCheck => (this.appCheck = appCheck)).catch());
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
getToken(forceRefresh) {
|
|
228
|
+
if (!this.appCheck) {
|
|
229
|
+
return new Promise((resolve, reject) => {
|
|
230
|
+
// Support delayed initialization of FirebaseAppCheck. This allows our
|
|
231
|
+
// customers to initialize the RTDB SDK before initializing Firebase
|
|
232
|
+
// AppCheck and ensures that all requests are authenticated if a token
|
|
233
|
+
// becomes available before the timoeout below expires.
|
|
234
|
+
setTimeout(() => {
|
|
235
|
+
if (this.appCheck) {
|
|
236
|
+
this.getToken(forceRefresh).then(resolve, reject);
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
resolve(null);
|
|
240
|
+
}
|
|
241
|
+
}, 0);
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
return this.appCheck.getToken(forceRefresh);
|
|
245
|
+
}
|
|
246
|
+
addTokenChangeListener(listener) {
|
|
247
|
+
var _a;
|
|
248
|
+
void ((_a = this.appCheckProvider) === null || _a === void 0 ? void 0 : _a.get().then(appCheck => appCheck.addTokenListener(listener)));
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* @license
|
|
254
|
+
* Copyright 2024 Google LLC
|
|
255
|
+
*
|
|
256
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
257
|
+
* you may not use this file except in compliance with the License.
|
|
258
|
+
* You may obtain a copy of the License at
|
|
259
|
+
*
|
|
260
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
261
|
+
*
|
|
262
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
263
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
264
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
265
|
+
* See the License for the specific language governing permissions and
|
|
266
|
+
* limitations under the License.
|
|
267
|
+
*/
|
|
268
|
+
// @internal
|
|
188
269
|
class FirebaseAuthProvider {
|
|
189
270
|
constructor(_appName, _options, _authProvider) {
|
|
190
271
|
this._appName = _appName;
|
|
@@ -227,7 +308,8 @@ class FirebaseAuthProvider {
|
|
|
227
308
|
removeTokenChangeListener(listener) {
|
|
228
309
|
this._authProvider
|
|
229
310
|
.get()
|
|
230
|
-
.then(auth => auth.removeAuthTokenListener(listener))
|
|
311
|
+
.then(auth => auth.removeAuthTokenListener(listener))
|
|
312
|
+
.catch(err => logError(err));
|
|
231
313
|
}
|
|
232
314
|
}
|
|
233
315
|
|
|
@@ -467,7 +549,7 @@ function urlBuilder(projectConfig, transportOptions) {
|
|
|
467
549
|
logError('Port type is of an invalid type');
|
|
468
550
|
throw new DataConnectError(Code.INVALID_ARGUMENT, 'Incorrect type for port passed in!');
|
|
469
551
|
}
|
|
470
|
-
return `${baseUrl}/
|
|
552
|
+
return `${baseUrl}/v1beta/projects/${project}/locations/${location}/services/${service}/connectors/${connector}`;
|
|
471
553
|
}
|
|
472
554
|
function addToken(url, apiKey) {
|
|
473
555
|
if (!apiKey) {
|
|
@@ -495,41 +577,44 @@ function addToken(url, apiKey) {
|
|
|
495
577
|
* limitations under the License.
|
|
496
578
|
*/
|
|
497
579
|
class RESTTransport {
|
|
498
|
-
constructor(options, apiKey, authProvider, transportOptions) {
|
|
499
|
-
var _a;
|
|
580
|
+
constructor(options, apiKey, appId, authProvider, appCheckProvider, transportOptions, _isUsingGen = false) {
|
|
581
|
+
var _a, _b;
|
|
500
582
|
this.apiKey = apiKey;
|
|
583
|
+
this.appId = appId;
|
|
501
584
|
this.authProvider = authProvider;
|
|
585
|
+
this.appCheckProvider = appCheckProvider;
|
|
586
|
+
this._isUsingGen = _isUsingGen;
|
|
502
587
|
this._host = '';
|
|
503
588
|
this._location = 'l';
|
|
504
589
|
this._connectorName = '';
|
|
505
590
|
this._secure = true;
|
|
506
591
|
this._project = 'p';
|
|
507
592
|
this._accessToken = null;
|
|
508
|
-
this.
|
|
593
|
+
this._appCheckToken = null;
|
|
594
|
+
this._lastToken = null;
|
|
509
595
|
// TODO(mtewani): Update U to include shape of body defined in line 13.
|
|
510
596
|
this.invokeQuery = (queryName, body) => {
|
|
511
597
|
const abortController = new AbortController();
|
|
512
598
|
// TODO(mtewani): Update to proper value
|
|
513
|
-
const withAuth = this.
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
abortController, this._accessToken);
|
|
520
|
-
});
|
|
599
|
+
const withAuth = this.withRetry(() => dcFetch(addToken(`${this.endpointUrl}:executeQuery`, this.apiKey), {
|
|
600
|
+
name: `projects/${this._project}/locations/${this._location}/services/${this._serviceName}/connectors/${this._connectorName}`,
|
|
601
|
+
operationName: queryName,
|
|
602
|
+
variables: body
|
|
603
|
+
}, // TODO(mtewani): This is a patch, fix this.
|
|
604
|
+
abortController, this.appId, this._accessToken, this._appCheckToken, this._isUsingGen));
|
|
521
605
|
return {
|
|
522
|
-
then: withAuth.then.bind(withAuth)
|
|
606
|
+
then: withAuth.then.bind(withAuth),
|
|
607
|
+
catch: withAuth.catch.bind(withAuth)
|
|
523
608
|
};
|
|
524
609
|
};
|
|
525
610
|
this.invokeMutation = (mutationName, body) => {
|
|
526
611
|
const abortController = new AbortController();
|
|
527
|
-
const taskResult = this.
|
|
612
|
+
const taskResult = this.withRetry(() => {
|
|
528
613
|
return dcFetch(addToken(`${this.endpointUrl}:executeMutation`, this.apiKey), {
|
|
529
614
|
name: `projects/${this._project}/locations/${this._location}/services/${this._serviceName}/connectors/${this._connectorName}`,
|
|
530
615
|
operationName: mutationName,
|
|
531
616
|
variables: body
|
|
532
|
-
}, abortController, this._accessToken);
|
|
617
|
+
}, abortController, this.appId, this._accessToken, this._appCheckToken, this._isUsingGen);
|
|
533
618
|
});
|
|
534
619
|
return {
|
|
535
620
|
then: taskResult.then.bind(taskResult),
|
|
@@ -563,6 +648,11 @@ class RESTTransport {
|
|
|
563
648
|
logDebug(`New Token Available: ${token}`);
|
|
564
649
|
this._accessToken = token;
|
|
565
650
|
});
|
|
651
|
+
(_b = this.appCheckProvider) === null || _b === void 0 ? void 0 : _b.addTokenChangeListener(result => {
|
|
652
|
+
const { token } = result;
|
|
653
|
+
logDebug(`New App Check Token Available: ${token}`);
|
|
654
|
+
this._appCheckToken = token;
|
|
655
|
+
});
|
|
566
656
|
}
|
|
567
657
|
get endpointUrl() {
|
|
568
658
|
return urlBuilder({
|
|
@@ -584,26 +674,52 @@ class RESTTransport {
|
|
|
584
674
|
onTokenChanged(newToken) {
|
|
585
675
|
this._accessToken = newToken;
|
|
586
676
|
}
|
|
587
|
-
getWithAuth() {
|
|
677
|
+
async getWithAuth(forceToken = false) {
|
|
678
|
+
var _a;
|
|
588
679
|
let starterPromise = new Promise(resolve => resolve(this._accessToken));
|
|
589
|
-
if (
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
680
|
+
if (this.appCheckProvider) {
|
|
681
|
+
this._appCheckToken = (_a = (await this.appCheckProvider.getToken())) === null || _a === void 0 ? void 0 : _a.token;
|
|
682
|
+
}
|
|
683
|
+
if (this.authProvider) {
|
|
684
|
+
starterPromise = this.authProvider
|
|
685
|
+
.getToken(/*forceToken=*/ forceToken)
|
|
686
|
+
.then(data => {
|
|
687
|
+
if (!data) {
|
|
688
|
+
return null;
|
|
689
|
+
}
|
|
690
|
+
this._accessToken = data.accessToken;
|
|
691
|
+
return this._accessToken;
|
|
692
|
+
});
|
|
693
|
+
}
|
|
694
|
+
else {
|
|
695
|
+
starterPromise = new Promise(resolve => resolve(''));
|
|
604
696
|
}
|
|
605
697
|
return starterPromise;
|
|
606
698
|
}
|
|
699
|
+
_setLastToken(lastToken) {
|
|
700
|
+
this._lastToken = lastToken;
|
|
701
|
+
}
|
|
702
|
+
withRetry(promiseFactory, retry = false) {
|
|
703
|
+
let isNewToken = false;
|
|
704
|
+
return this.getWithAuth(retry)
|
|
705
|
+
.then(res => {
|
|
706
|
+
isNewToken = this._lastToken !== res;
|
|
707
|
+
this._lastToken = res;
|
|
708
|
+
return res;
|
|
709
|
+
})
|
|
710
|
+
.then(promiseFactory)
|
|
711
|
+
.catch(err => {
|
|
712
|
+
// Only retry if the result is unauthorized and the last token isn't the same as the new one.
|
|
713
|
+
if ('code' in err &&
|
|
714
|
+
err.code === Code.UNAUTHORIZED &&
|
|
715
|
+
!retry &&
|
|
716
|
+
isNewToken) {
|
|
717
|
+
logDebug('Retrying due to unauthorized');
|
|
718
|
+
return this.withRetry(promiseFactory, true);
|
|
719
|
+
}
|
|
720
|
+
throw err;
|
|
721
|
+
});
|
|
722
|
+
}
|
|
607
723
|
}
|
|
608
724
|
|
|
609
725
|
/**
|
|
@@ -622,16 +738,26 @@ class RESTTransport {
|
|
|
622
738
|
* See the License for the specific language governing permissions and
|
|
623
739
|
* limitations under the License.
|
|
624
740
|
*/
|
|
625
|
-
|
|
741
|
+
/**
|
|
742
|
+
*
|
|
743
|
+
* @param dcInstance Data Connect instance
|
|
744
|
+
* @param mutationName name of mutation
|
|
745
|
+
* @param variables variables to send with mutation
|
|
746
|
+
* @returns `MutationRef`
|
|
747
|
+
*/
|
|
748
|
+
function mutationRef(dcInstance, mutationName, variables) {
|
|
626
749
|
dcInstance.setInitialized();
|
|
627
750
|
const ref = {
|
|
628
751
|
dataConnect: dcInstance,
|
|
629
|
-
name:
|
|
752
|
+
name: mutationName,
|
|
630
753
|
refType: MUTATION_STR,
|
|
631
754
|
variables: variables
|
|
632
755
|
};
|
|
633
756
|
return ref;
|
|
634
757
|
}
|
|
758
|
+
/**
|
|
759
|
+
* @internal
|
|
760
|
+
*/
|
|
635
761
|
class MutationManager {
|
|
636
762
|
constructor(_transport) {
|
|
637
763
|
this._transport = _transport;
|
|
@@ -649,6 +775,11 @@ class MutationManager {
|
|
|
649
775
|
return withRefPromise;
|
|
650
776
|
}
|
|
651
777
|
}
|
|
778
|
+
/**
|
|
779
|
+
* Execute Mutation
|
|
780
|
+
* @param mutationRef mutation to execute
|
|
781
|
+
* @returns `MutationRef`
|
|
782
|
+
*/
|
|
652
783
|
function executeMutation(mutationRef) {
|
|
653
784
|
return mutationRef.dataConnect._mutationManager.executeMutation(mutationRef);
|
|
654
785
|
}
|
|
@@ -683,15 +814,21 @@ function parseOptions(fullHost) {
|
|
|
683
814
|
const port = Number(portAsString);
|
|
684
815
|
return { host, port, sslEnabled: isSecure };
|
|
685
816
|
}
|
|
817
|
+
/**
|
|
818
|
+
* Class representing Firebase Data Connect
|
|
819
|
+
*/
|
|
686
820
|
class DataConnect {
|
|
821
|
+
// @internal
|
|
687
822
|
constructor(app,
|
|
688
823
|
// TODO(mtewani): Replace with _dataConnectOptions in the future
|
|
689
|
-
dataConnectOptions, _authProvider) {
|
|
824
|
+
dataConnectOptions, _authProvider, _appCheckProvider) {
|
|
690
825
|
this.app = app;
|
|
691
826
|
this.dataConnectOptions = dataConnectOptions;
|
|
692
827
|
this._authProvider = _authProvider;
|
|
828
|
+
this._appCheckProvider = _appCheckProvider;
|
|
693
829
|
this.isEmulator = false;
|
|
694
|
-
this.
|
|
830
|
+
this._initialized = false;
|
|
831
|
+
this._isUsingGeneratedSdk = false;
|
|
695
832
|
if (typeof process !== 'undefined' && process.env) {
|
|
696
833
|
const host = process.env[FIREBASE_DATA_CONNECT_EMULATOR_HOST_VAR];
|
|
697
834
|
if (host) {
|
|
@@ -701,17 +838,25 @@ class DataConnect {
|
|
|
701
838
|
}
|
|
702
839
|
}
|
|
703
840
|
}
|
|
841
|
+
// @internal
|
|
842
|
+
_useGeneratedSdk() {
|
|
843
|
+
if (!this._isUsingGeneratedSdk) {
|
|
844
|
+
this._isUsingGeneratedSdk = true;
|
|
845
|
+
}
|
|
846
|
+
}
|
|
704
847
|
_delete() {
|
|
705
848
|
_removeServiceInstance(this.app, 'data-connect', JSON.stringify(this.getSettings()));
|
|
706
849
|
return Promise.resolve();
|
|
707
850
|
}
|
|
851
|
+
// @internal
|
|
708
852
|
getSettings() {
|
|
709
853
|
const copy = JSON.parse(JSON.stringify(this.dataConnectOptions));
|
|
710
854
|
delete copy.projectId;
|
|
711
855
|
return copy;
|
|
712
856
|
}
|
|
857
|
+
// @internal
|
|
713
858
|
setInitialized() {
|
|
714
|
-
if (this.
|
|
859
|
+
if (this._initialized) {
|
|
715
860
|
return;
|
|
716
861
|
}
|
|
717
862
|
if (this._transportClass === undefined) {
|
|
@@ -721,16 +866,20 @@ class DataConnect {
|
|
|
721
866
|
if (this._authProvider) {
|
|
722
867
|
this._authTokenProvider = new FirebaseAuthProvider(this.app.name, this.app.options, this._authProvider);
|
|
723
868
|
}
|
|
724
|
-
this.
|
|
725
|
-
|
|
869
|
+
if (this._appCheckProvider) {
|
|
870
|
+
this._appCheckTokenProvider = new AppCheckTokenProvider(this.app.name, this._appCheckProvider);
|
|
871
|
+
}
|
|
872
|
+
this._initialized = true;
|
|
873
|
+
this._transport = new this._transportClass(this.dataConnectOptions, this.app.options.apiKey, this.app.options.appId, this._authTokenProvider, this._appCheckTokenProvider, undefined, this._isUsingGeneratedSdk);
|
|
726
874
|
if (this._transportOptions) {
|
|
727
875
|
this._transport.useEmulator(this._transportOptions.host, this._transportOptions.port, this._transportOptions.sslEnabled);
|
|
728
876
|
}
|
|
729
877
|
this._queryManager = new QueryManager(this._transport);
|
|
730
878
|
this._mutationManager = new MutationManager(this._transport);
|
|
731
879
|
}
|
|
880
|
+
// @internal
|
|
732
881
|
enableEmulator(transportOptions) {
|
|
733
|
-
if (this.
|
|
882
|
+
if (this._initialized) {
|
|
734
883
|
logError('enableEmulator called after initialization');
|
|
735
884
|
throw new DataConnectError(Code.ALREADY_INITIALIZED, 'DataConnect instance already initialized!');
|
|
736
885
|
}
|
|
@@ -738,6 +887,13 @@ class DataConnect {
|
|
|
738
887
|
this.isEmulator = true;
|
|
739
888
|
}
|
|
740
889
|
}
|
|
890
|
+
/**
|
|
891
|
+
* Connect to the DataConnect Emulator
|
|
892
|
+
* @param dc Data Connect instance
|
|
893
|
+
* @param host host of emulator server
|
|
894
|
+
* @param port port of emulator server
|
|
895
|
+
* @param sslEnabled use https
|
|
896
|
+
*/
|
|
741
897
|
function connectDataConnectEmulator(dc, host, port, sslEnabled = false) {
|
|
742
898
|
dc.enableEmulator({ host, port, sslEnabled });
|
|
743
899
|
}
|
|
@@ -752,7 +908,7 @@ function getDataConnect(appOrOptions, optionalOptions) {
|
|
|
752
908
|
dcOptions = optionalOptions;
|
|
753
909
|
app = appOrOptions;
|
|
754
910
|
}
|
|
755
|
-
if (!app) {
|
|
911
|
+
if (!app || Object.keys(app).length === 0) {
|
|
756
912
|
app = getApp();
|
|
757
913
|
}
|
|
758
914
|
const provider = _getProvider(app, 'data-connect');
|
|
@@ -766,9 +922,7 @@ function getDataConnect(appOrOptions, optionalOptions) {
|
|
|
766
922
|
return dcInstance;
|
|
767
923
|
}
|
|
768
924
|
}
|
|
769
|
-
|
|
770
|
-
throw new DataConnectError(Code.INVALID_ARGUMENT, 'DC Option Required');
|
|
771
|
-
}
|
|
925
|
+
validateDCOptions(dcOptions);
|
|
772
926
|
logDebug('Creating new DataConnect instance');
|
|
773
927
|
// Initialize with options.
|
|
774
928
|
return provider.initialize({
|
|
@@ -776,6 +930,29 @@ function getDataConnect(appOrOptions, optionalOptions) {
|
|
|
776
930
|
options: dcOptions
|
|
777
931
|
});
|
|
778
932
|
}
|
|
933
|
+
/**
|
|
934
|
+
*
|
|
935
|
+
* @param dcOptions
|
|
936
|
+
* @returns {void}
|
|
937
|
+
* @internal
|
|
938
|
+
*/
|
|
939
|
+
function validateDCOptions(dcOptions) {
|
|
940
|
+
const fields = ['connector', 'location', 'service'];
|
|
941
|
+
if (!dcOptions) {
|
|
942
|
+
throw new DataConnectError(Code.INVALID_ARGUMENT, 'DC Option Required');
|
|
943
|
+
}
|
|
944
|
+
fields.forEach(field => {
|
|
945
|
+
if (dcOptions[field] === null || dcOptions[field] === undefined) {
|
|
946
|
+
throw new DataConnectError(Code.INVALID_ARGUMENT, `${field} Required`);
|
|
947
|
+
}
|
|
948
|
+
});
|
|
949
|
+
return true;
|
|
950
|
+
}
|
|
951
|
+
/**
|
|
952
|
+
* Delete DataConnect instance
|
|
953
|
+
* @param dataConnect DataConnect instance
|
|
954
|
+
* @returns
|
|
955
|
+
*/
|
|
779
956
|
function terminate(dataConnect) {
|
|
780
957
|
return dataConnect._delete();
|
|
781
958
|
// TODO(mtewani): Stop pending tasks
|
|
@@ -802,11 +979,15 @@ function registerDataConnect(variant) {
|
|
|
802
979
|
_registerComponent(new Component('data-connect', (container, { instanceIdentifier: settings, options }) => {
|
|
803
980
|
const app = container.getProvider('app').getImmediate();
|
|
804
981
|
const authProvider = container.getProvider('auth-internal');
|
|
982
|
+
const appCheckProvider = container.getProvider('app-check-internal');
|
|
805
983
|
let newOpts = options;
|
|
806
984
|
if (settings) {
|
|
807
985
|
newOpts = JSON.parse(settings);
|
|
808
986
|
}
|
|
809
|
-
|
|
987
|
+
if (!app.options.projectId) {
|
|
988
|
+
throw new DataConnectError(Code.INVALID_ARGUMENT, 'Project ID must be provided. Did you pass in a proper projectId to initializeApp?');
|
|
989
|
+
}
|
|
990
|
+
return new DataConnect(app, Object.assign(Object.assign({}, newOpts), { projectId: app.options.projectId }), authProvider, appCheckProvider);
|
|
810
991
|
}, "PUBLIC" /* ComponentType.PUBLIC */).setMultipleInstances(true));
|
|
811
992
|
registerVersion(name, version, variant);
|
|
812
993
|
// BUILD_TARGET will be replaced by values like esm5, esm2017, cjs5, etc during the compilation
|
|
@@ -829,9 +1010,22 @@ function registerDataConnect(variant) {
|
|
|
829
1010
|
* See the License for the specific language governing permissions and
|
|
830
1011
|
* limitations under the License.
|
|
831
1012
|
*/
|
|
1013
|
+
/**
|
|
1014
|
+
* Execute Query
|
|
1015
|
+
* @param queryRef query to execute.
|
|
1016
|
+
* @returns `QueryPromise`
|
|
1017
|
+
*/
|
|
832
1018
|
function executeQuery(queryRef) {
|
|
833
1019
|
return queryRef.dataConnect._queryManager.executeQuery(queryRef);
|
|
834
1020
|
}
|
|
1021
|
+
/**
|
|
1022
|
+
* Execute Query
|
|
1023
|
+
* @param dcInstance Data Connect instance to use.
|
|
1024
|
+
* @param queryName Query to execute
|
|
1025
|
+
* @param variables Variables to execute with
|
|
1026
|
+
* @param initialCache initial cache to use for client hydration
|
|
1027
|
+
* @returns `QueryRef`
|
|
1028
|
+
*/
|
|
835
1029
|
function queryRef(dcInstance, queryName, variables, initialCache) {
|
|
836
1030
|
dcInstance.setInitialized();
|
|
837
1031
|
dcInstance._queryManager.track(queryName, variables, initialCache);
|
|
@@ -842,6 +1036,11 @@ function queryRef(dcInstance, queryName, variables, initialCache) {
|
|
|
842
1036
|
variables: variables
|
|
843
1037
|
};
|
|
844
1038
|
}
|
|
1039
|
+
/**
|
|
1040
|
+
* Converts serialized ref to query ref
|
|
1041
|
+
* @param serializedRef ref to convert to `QueryRef`
|
|
1042
|
+
* @returns `QueryRef`
|
|
1043
|
+
*/
|
|
845
1044
|
function toQueryRef(serializedRef) {
|
|
846
1045
|
const { refInfo: { name, variables, connectorConfig } } = serializedRef;
|
|
847
1046
|
return queryRef(getDataConnect(connectorConfig), name, variables);
|
|
@@ -863,6 +1062,57 @@ function toQueryRef(serializedRef) {
|
|
|
863
1062
|
* See the License for the specific language governing permissions and
|
|
864
1063
|
* limitations under the License.
|
|
865
1064
|
*/
|
|
1065
|
+
/**
|
|
1066
|
+
* The generated SDK will allow the user to pass in either the variable or the data connect instance with the variable,
|
|
1067
|
+
* and this function validates the variables and returns back the DataConnect instance and variables based on the arguments passed in.
|
|
1068
|
+
* @param connectorConfig
|
|
1069
|
+
* @param dcOrVars
|
|
1070
|
+
* @param vars
|
|
1071
|
+
* @param validateVars
|
|
1072
|
+
* @returns {DataConnect} and {Variables} instance
|
|
1073
|
+
* @internal
|
|
1074
|
+
*/
|
|
1075
|
+
function validateArgs(connectorConfig, dcOrVars, vars, validateVars) {
|
|
1076
|
+
let dcInstance;
|
|
1077
|
+
let realVars;
|
|
1078
|
+
if (dcOrVars && 'enableEmulator' in dcOrVars) {
|
|
1079
|
+
dcInstance = dcOrVars;
|
|
1080
|
+
realVars = vars;
|
|
1081
|
+
}
|
|
1082
|
+
else {
|
|
1083
|
+
dcInstance = getDataConnect(connectorConfig);
|
|
1084
|
+
realVars = dcOrVars;
|
|
1085
|
+
}
|
|
1086
|
+
if (!dcInstance || (!realVars && validateVars)) {
|
|
1087
|
+
throw new DataConnectError(Code.INVALID_ARGUMENT, 'Variables required.');
|
|
1088
|
+
}
|
|
1089
|
+
return { dc: dcInstance, vars: realVars };
|
|
1090
|
+
}
|
|
1091
|
+
|
|
1092
|
+
/**
|
|
1093
|
+
* @license
|
|
1094
|
+
* Copyright 2024 Google LLC
|
|
1095
|
+
*
|
|
1096
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
1097
|
+
* you may not use this file except in compliance with the License.
|
|
1098
|
+
* You may obtain a copy of the License at
|
|
1099
|
+
*
|
|
1100
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
1101
|
+
*
|
|
1102
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
1103
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
1104
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
1105
|
+
* See the License for the specific language governing permissions and
|
|
1106
|
+
* limitations under the License.
|
|
1107
|
+
*/
|
|
1108
|
+
/**
|
|
1109
|
+
* Subscribe to a `QueryRef`
|
|
1110
|
+
* @param queryRefOrSerializedResult query ref or serialized result.
|
|
1111
|
+
* @param observerOrOnNext observer object or next function.
|
|
1112
|
+
* @param onError Callback to call when error gets thrown.
|
|
1113
|
+
* @param onComplete Called when subscription completes.
|
|
1114
|
+
* @returns `SubscriptionOptions`
|
|
1115
|
+
*/
|
|
866
1116
|
function subscribe(queryRefOrSerializedResult, observerOrOnNext, onError, onComplete) {
|
|
867
1117
|
let ref;
|
|
868
1118
|
let initialCache;
|
|
@@ -913,5 +1163,5 @@ function subscribe(queryRefOrSerializedResult, observerOrOnNext, onError, onComp
|
|
|
913
1163
|
initializeFetch(fetch);
|
|
914
1164
|
registerDataConnect('node');
|
|
915
1165
|
|
|
916
|
-
export { DataConnect,
|
|
1166
|
+
export { DataConnect, MUTATION_STR, MutationManager, QUERY_STR, SOURCE_CACHE, SOURCE_SERVER, connectDataConnectEmulator, executeMutation, executeQuery, getDataConnect, mutationRef, parseOptions, queryRef, setLogLevel, subscribe, terminate, toQueryRef, validateArgs, validateDCOptions };
|
|
917
1167
|
//# sourceMappingURL=index.node.esm.js.map
|