@firebase/data-connect 0.1.1 → 0.1.2
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 +1108 -1108
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm2017.js +1108 -1108
- package/dist/index.esm2017.js.map +1 -1
- package/dist/index.node.cjs.js +1123 -1123
- package/dist/index.node.cjs.js.map +1 -1
- package/dist/node-esm/index.node.esm.js +1123 -1123
- package/dist/node-esm/index.node.esm.js.map +1 -1
- package/dist/node-esm/src/api/DataConnect.d.ts +108 -108
- package/dist/node-esm/src/api/Mutation.d.ts +61 -61
- package/dist/node-esm/src/api/Reference.d.ts +51 -51
- package/dist/node-esm/src/api/index.d.ts +23 -23
- package/dist/node-esm/src/api/query.d.ts +96 -96
- package/dist/node-esm/src/api.browser.d.ts +34 -34
- package/dist/node-esm/src/api.node.d.ts +17 -17
- package/dist/node-esm/src/core/AppCheckTokenProvider.d.ts +30 -30
- package/dist/node-esm/src/core/FirebaseAuthProvider.d.ts +34 -34
- package/dist/node-esm/src/core/QueryManager.d.ts +36 -36
- package/dist/node-esm/src/core/error.d.ts +51 -51
- package/dist/node-esm/src/core/version.d.ts +23 -23
- package/dist/node-esm/src/index.d.ts +29 -29
- package/dist/node-esm/src/index.node.d.ts +18 -18
- package/dist/node-esm/src/logger.d.ts +20 -20
- package/dist/node-esm/src/network/fetch.d.ts +21 -21
- package/dist/node-esm/src/network/index.d.ts +17 -17
- package/dist/node-esm/src/network/transport/index.d.ts +43 -43
- package/dist/node-esm/src/network/transport/rest.d.ts +58 -58
- package/dist/node-esm/src/register.d.ts +1 -1
- package/dist/node-esm/src/util/encoder.d.ts +19 -19
- package/dist/node-esm/src/util/map.d.ts +17 -17
- package/dist/node-esm/src/util/url.d.ts +19 -19
- package/dist/node-esm/src/util/validateArgs.d.ts +33 -33
- package/dist/src/api/DataConnect.d.ts +108 -108
- package/dist/src/api/Mutation.d.ts +61 -61
- package/dist/src/api/Reference.d.ts +51 -51
- package/dist/src/api/index.d.ts +23 -23
- package/dist/src/api/query.d.ts +96 -96
- package/dist/src/api.browser.d.ts +34 -34
- package/dist/src/api.node.d.ts +17 -17
- package/dist/src/core/AppCheckTokenProvider.d.ts +30 -30
- package/dist/src/core/FirebaseAuthProvider.d.ts +34 -34
- package/dist/src/core/QueryManager.d.ts +36 -36
- package/dist/src/core/error.d.ts +51 -51
- package/dist/src/core/version.d.ts +23 -23
- package/dist/src/index.d.ts +29 -29
- package/dist/src/index.node.d.ts +18 -18
- package/dist/src/logger.d.ts +20 -20
- package/dist/src/network/fetch.d.ts +21 -21
- package/dist/src/network/index.d.ts +17 -17
- package/dist/src/network/transport/index.d.ts +43 -43
- package/dist/src/network/transport/rest.d.ts +58 -58
- package/dist/src/register.d.ts +1 -1
- package/dist/src/util/encoder.d.ts +19 -19
- package/dist/src/util/map.d.ts +17 -17
- package/dist/src/util/url.d.ts +19 -19
- package/dist/src/util/validateArgs.d.ts +33 -33
- package/package.json +7 -7
package/dist/index.esm2017.js
CHANGED
|
@@ -4,1151 +4,1151 @@ 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.1.
|
|
7
|
+
const version = "0.1.2";
|
|
8
8
|
|
|
9
|
-
/**
|
|
10
|
-
* @license
|
|
11
|
-
* Copyright 2024 Google LLC
|
|
12
|
-
*
|
|
13
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
14
|
-
* you may not use this file except in compliance with the License.
|
|
15
|
-
* You may obtain a copy of the License at
|
|
16
|
-
*
|
|
17
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
18
|
-
*
|
|
19
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
20
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
21
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
22
|
-
* See the License for the specific language governing permissions and
|
|
23
|
-
* limitations under the License.
|
|
24
|
-
*/
|
|
25
|
-
/** The semver (www.semver.org) version of the SDK. */
|
|
26
|
-
let SDK_VERSION = '';
|
|
27
|
-
/**
|
|
28
|
-
* SDK_VERSION should be set before any database instance is created
|
|
29
|
-
* @internal
|
|
30
|
-
*/
|
|
31
|
-
function setSDKVersion(version) {
|
|
32
|
-
SDK_VERSION = version;
|
|
9
|
+
/**
|
|
10
|
+
* @license
|
|
11
|
+
* Copyright 2024 Google LLC
|
|
12
|
+
*
|
|
13
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
14
|
+
* you may not use this file except in compliance with the License.
|
|
15
|
+
* You may obtain a copy of the License at
|
|
16
|
+
*
|
|
17
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
18
|
+
*
|
|
19
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
20
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
21
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
22
|
+
* See the License for the specific language governing permissions and
|
|
23
|
+
* limitations under the License.
|
|
24
|
+
*/
|
|
25
|
+
/** The semver (www.semver.org) version of the SDK. */
|
|
26
|
+
let SDK_VERSION = '';
|
|
27
|
+
/**
|
|
28
|
+
* SDK_VERSION should be set before any database instance is created
|
|
29
|
+
* @internal
|
|
30
|
+
*/
|
|
31
|
+
function setSDKVersion(version) {
|
|
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
|
-
}
|
|
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
87
|
}
|
|
88
88
|
|
|
89
|
-
/**
|
|
90
|
-
* @license
|
|
91
|
-
* Copyright 2024 Google LLC
|
|
92
|
-
*
|
|
93
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
94
|
-
* you may not use this file except in compliance with the License.
|
|
95
|
-
* You may obtain a copy of the License at
|
|
96
|
-
*
|
|
97
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
98
|
-
*
|
|
99
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
100
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
101
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
102
|
-
* See the License for the specific language governing permissions and
|
|
103
|
-
* limitations under the License.
|
|
104
|
-
*/
|
|
105
|
-
const Code = {
|
|
106
|
-
OTHER: 'other',
|
|
107
|
-
ALREADY_INITIALIZED: 'already-initialized',
|
|
108
|
-
NOT_INITIALIZED: 'not-initialized',
|
|
109
|
-
NOT_SUPPORTED: 'not-supported',
|
|
110
|
-
INVALID_ARGUMENT: 'invalid-argument',
|
|
111
|
-
PARTIAL_ERROR: 'partial-error',
|
|
112
|
-
UNAUTHORIZED: 'unauthorized'
|
|
113
|
-
};
|
|
114
|
-
/** An error returned by a DataConnect operation. */
|
|
115
|
-
class DataConnectError extends FirebaseError {
|
|
116
|
-
/** @hideconstructor */
|
|
117
|
-
constructor(
|
|
118
|
-
/**
|
|
119
|
-
* The backend error code associated with this error.
|
|
120
|
-
*/
|
|
121
|
-
code,
|
|
122
|
-
/**
|
|
123
|
-
* A custom error description.
|
|
124
|
-
*/
|
|
125
|
-
message) {
|
|
126
|
-
super(code, message);
|
|
127
|
-
this.code = code;
|
|
128
|
-
this.message = message;
|
|
129
|
-
// HACK: We write a toString property directly because Error is not a real
|
|
130
|
-
// class and so inheritance does not work correctly. We could alternatively
|
|
131
|
-
// do the same "back-door inheritance" trick that FirebaseError does.
|
|
132
|
-
this.toString = () => `${this.name}: [code=${this.code}]: ${this.message}`;
|
|
133
|
-
}
|
|
89
|
+
/**
|
|
90
|
+
* @license
|
|
91
|
+
* Copyright 2024 Google LLC
|
|
92
|
+
*
|
|
93
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
94
|
+
* you may not use this file except in compliance with the License.
|
|
95
|
+
* You may obtain a copy of the License at
|
|
96
|
+
*
|
|
97
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
98
|
+
*
|
|
99
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
100
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
101
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
102
|
+
* See the License for the specific language governing permissions and
|
|
103
|
+
* limitations under the License.
|
|
104
|
+
*/
|
|
105
|
+
const Code = {
|
|
106
|
+
OTHER: 'other',
|
|
107
|
+
ALREADY_INITIALIZED: 'already-initialized',
|
|
108
|
+
NOT_INITIALIZED: 'not-initialized',
|
|
109
|
+
NOT_SUPPORTED: 'not-supported',
|
|
110
|
+
INVALID_ARGUMENT: 'invalid-argument',
|
|
111
|
+
PARTIAL_ERROR: 'partial-error',
|
|
112
|
+
UNAUTHORIZED: 'unauthorized'
|
|
113
|
+
};
|
|
114
|
+
/** An error returned by a DataConnect operation. */
|
|
115
|
+
class DataConnectError extends FirebaseError {
|
|
116
|
+
/** @hideconstructor */
|
|
117
|
+
constructor(
|
|
118
|
+
/**
|
|
119
|
+
* The backend error code associated with this error.
|
|
120
|
+
*/
|
|
121
|
+
code,
|
|
122
|
+
/**
|
|
123
|
+
* A custom error description.
|
|
124
|
+
*/
|
|
125
|
+
message) {
|
|
126
|
+
super(code, message);
|
|
127
|
+
this.code = code;
|
|
128
|
+
this.message = message;
|
|
129
|
+
// HACK: We write a toString property directly because Error is not a real
|
|
130
|
+
// class and so inheritance does not work correctly. We could alternatively
|
|
131
|
+
// do the same "back-door inheritance" trick that FirebaseError does.
|
|
132
|
+
this.toString = () => `${this.name}: [code=${this.code}]: ${this.message}`;
|
|
133
|
+
}
|
|
134
134
|
}
|
|
135
135
|
|
|
136
|
-
/**
|
|
137
|
-
* @license
|
|
138
|
-
* Copyright 2024 Google LLC
|
|
139
|
-
*
|
|
140
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
141
|
-
* you may not use this file except in compliance with the License.
|
|
142
|
-
* You may obtain a copy of the License at
|
|
143
|
-
*
|
|
144
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
145
|
-
*
|
|
146
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
147
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
148
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
149
|
-
* See the License for the specific language governing permissions and
|
|
150
|
-
* limitations under the License.
|
|
151
|
-
*/
|
|
152
|
-
const logger = new Logger('@firebase/data-connect');
|
|
153
|
-
function setLogLevel(logLevel) {
|
|
154
|
-
logger.setLogLevel(logLevel);
|
|
155
|
-
}
|
|
156
|
-
function logDebug(msg) {
|
|
157
|
-
logger.debug(`DataConnect (${SDK_VERSION}): ${msg}`);
|
|
158
|
-
}
|
|
159
|
-
function logError(msg) {
|
|
160
|
-
logger.error(`DataConnect (${SDK_VERSION}): ${msg}`);
|
|
136
|
+
/**
|
|
137
|
+
* @license
|
|
138
|
+
* Copyright 2024 Google LLC
|
|
139
|
+
*
|
|
140
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
141
|
+
* you may not use this file except in compliance with the License.
|
|
142
|
+
* You may obtain a copy of the License at
|
|
143
|
+
*
|
|
144
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
145
|
+
*
|
|
146
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
147
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
148
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
149
|
+
* See the License for the specific language governing permissions and
|
|
150
|
+
* limitations under the License.
|
|
151
|
+
*/
|
|
152
|
+
const logger = new Logger('@firebase/data-connect');
|
|
153
|
+
function setLogLevel(logLevel) {
|
|
154
|
+
logger.setLogLevel(logLevel);
|
|
155
|
+
}
|
|
156
|
+
function logDebug(msg) {
|
|
157
|
+
logger.debug(`DataConnect (${SDK_VERSION}): ${msg}`);
|
|
158
|
+
}
|
|
159
|
+
function logError(msg) {
|
|
160
|
+
logger.error(`DataConnect (${SDK_VERSION}): ${msg}`);
|
|
161
161
|
}
|
|
162
162
|
|
|
163
|
-
/**
|
|
164
|
-
* @license
|
|
165
|
-
* Copyright 2024 Google LLC
|
|
166
|
-
*
|
|
167
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
168
|
-
* you may not use this file except in compliance with the License.
|
|
169
|
-
* You may obtain a copy of the License at
|
|
170
|
-
*
|
|
171
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
172
|
-
*
|
|
173
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
174
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
175
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
176
|
-
* See the License for the specific language governing permissions and
|
|
177
|
-
* limitations under the License.
|
|
178
|
-
*/
|
|
179
|
-
// @internal
|
|
180
|
-
class FirebaseAuthProvider {
|
|
181
|
-
constructor(_appName, _options, _authProvider) {
|
|
182
|
-
this._appName = _appName;
|
|
183
|
-
this._options = _options;
|
|
184
|
-
this._authProvider = _authProvider;
|
|
185
|
-
this._auth = _authProvider.getImmediate({ optional: true });
|
|
186
|
-
if (!this._auth) {
|
|
187
|
-
_authProvider.onInit(auth => (this._auth = auth));
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
getToken(forceRefresh) {
|
|
191
|
-
if (!this._auth) {
|
|
192
|
-
return new Promise((resolve, reject) => {
|
|
193
|
-
setTimeout(() => {
|
|
194
|
-
if (this._auth) {
|
|
195
|
-
this.getToken(forceRefresh).then(resolve, reject);
|
|
196
|
-
}
|
|
197
|
-
else {
|
|
198
|
-
resolve(null);
|
|
199
|
-
}
|
|
200
|
-
}, 0);
|
|
201
|
-
});
|
|
202
|
-
}
|
|
203
|
-
return this._auth.getToken(forceRefresh).catch(error => {
|
|
204
|
-
if (error && error.code === 'auth/token-not-initialized') {
|
|
205
|
-
logDebug('Got auth/token-not-initialized error. Treating as null token.');
|
|
206
|
-
return null;
|
|
207
|
-
}
|
|
208
|
-
else {
|
|
209
|
-
logError('Error received when attempting to retrieve token: ' +
|
|
210
|
-
JSON.stringify(error));
|
|
211
|
-
return Promise.reject(error);
|
|
212
|
-
}
|
|
213
|
-
});
|
|
214
|
-
}
|
|
215
|
-
addTokenChangeListener(listener) {
|
|
216
|
-
var _a;
|
|
217
|
-
(_a = this._auth) === null || _a === void 0 ? void 0 : _a.addAuthTokenListener(listener);
|
|
218
|
-
}
|
|
219
|
-
removeTokenChangeListener(listener) {
|
|
220
|
-
this._authProvider
|
|
221
|
-
.get()
|
|
222
|
-
.then(auth => auth.removeAuthTokenListener(listener))
|
|
223
|
-
.catch(err => logError(err));
|
|
224
|
-
}
|
|
163
|
+
/**
|
|
164
|
+
* @license
|
|
165
|
+
* Copyright 2024 Google LLC
|
|
166
|
+
*
|
|
167
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
168
|
+
* you may not use this file except in compliance with the License.
|
|
169
|
+
* You may obtain a copy of the License at
|
|
170
|
+
*
|
|
171
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
172
|
+
*
|
|
173
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
174
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
175
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
176
|
+
* See the License for the specific language governing permissions and
|
|
177
|
+
* limitations under the License.
|
|
178
|
+
*/
|
|
179
|
+
// @internal
|
|
180
|
+
class FirebaseAuthProvider {
|
|
181
|
+
constructor(_appName, _options, _authProvider) {
|
|
182
|
+
this._appName = _appName;
|
|
183
|
+
this._options = _options;
|
|
184
|
+
this._authProvider = _authProvider;
|
|
185
|
+
this._auth = _authProvider.getImmediate({ optional: true });
|
|
186
|
+
if (!this._auth) {
|
|
187
|
+
_authProvider.onInit(auth => (this._auth = auth));
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
getToken(forceRefresh) {
|
|
191
|
+
if (!this._auth) {
|
|
192
|
+
return new Promise((resolve, reject) => {
|
|
193
|
+
setTimeout(() => {
|
|
194
|
+
if (this._auth) {
|
|
195
|
+
this.getToken(forceRefresh).then(resolve, reject);
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
resolve(null);
|
|
199
|
+
}
|
|
200
|
+
}, 0);
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
return this._auth.getToken(forceRefresh).catch(error => {
|
|
204
|
+
if (error && error.code === 'auth/token-not-initialized') {
|
|
205
|
+
logDebug('Got auth/token-not-initialized error. Treating as null token.');
|
|
206
|
+
return null;
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
logError('Error received when attempting to retrieve token: ' +
|
|
210
|
+
JSON.stringify(error));
|
|
211
|
+
return Promise.reject(error);
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
addTokenChangeListener(listener) {
|
|
216
|
+
var _a;
|
|
217
|
+
(_a = this._auth) === null || _a === void 0 ? void 0 : _a.addAuthTokenListener(listener);
|
|
218
|
+
}
|
|
219
|
+
removeTokenChangeListener(listener) {
|
|
220
|
+
this._authProvider
|
|
221
|
+
.get()
|
|
222
|
+
.then(auth => auth.removeAuthTokenListener(listener))
|
|
223
|
+
.catch(err => logError(err));
|
|
224
|
+
}
|
|
225
225
|
}
|
|
226
226
|
|
|
227
|
-
/**
|
|
228
|
-
* @license
|
|
229
|
-
* Copyright 2024 Google LLC
|
|
230
|
-
*
|
|
231
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
232
|
-
* you may not use this file except in compliance with the License.
|
|
233
|
-
* You may obtain a copy of the License at
|
|
234
|
-
*
|
|
235
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
236
|
-
*
|
|
237
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
238
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
239
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
240
|
-
* See the License for the specific language governing permissions and
|
|
241
|
-
* limitations under the License.
|
|
242
|
-
*/
|
|
243
|
-
const QUERY_STR = 'query';
|
|
244
|
-
const MUTATION_STR = 'mutation';
|
|
245
|
-
const SOURCE_SERVER = 'SERVER';
|
|
227
|
+
/**
|
|
228
|
+
* @license
|
|
229
|
+
* Copyright 2024 Google LLC
|
|
230
|
+
*
|
|
231
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
232
|
+
* you may not use this file except in compliance with the License.
|
|
233
|
+
* You may obtain a copy of the License at
|
|
234
|
+
*
|
|
235
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
236
|
+
*
|
|
237
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
238
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
239
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
240
|
+
* See the License for the specific language governing permissions and
|
|
241
|
+
* limitations under the License.
|
|
242
|
+
*/
|
|
243
|
+
const QUERY_STR = 'query';
|
|
244
|
+
const MUTATION_STR = 'mutation';
|
|
245
|
+
const SOURCE_SERVER = 'SERVER';
|
|
246
246
|
const SOURCE_CACHE = 'CACHE';
|
|
247
247
|
|
|
248
|
-
/**
|
|
249
|
-
* @license
|
|
250
|
-
* Copyright 2024 Google LLC
|
|
251
|
-
*
|
|
252
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
253
|
-
* you may not use this file except in compliance with the License.
|
|
254
|
-
* You may obtain a copy of the License at
|
|
255
|
-
*
|
|
256
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
257
|
-
*
|
|
258
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
259
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
260
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
261
|
-
* See the License for the specific language governing permissions and
|
|
262
|
-
* limitations under the License.
|
|
263
|
-
*/
|
|
264
|
-
let encoderImpl;
|
|
265
|
-
function setEncoder(encoder) {
|
|
266
|
-
encoderImpl = encoder;
|
|
267
|
-
}
|
|
248
|
+
/**
|
|
249
|
+
* @license
|
|
250
|
+
* Copyright 2024 Google LLC
|
|
251
|
+
*
|
|
252
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
253
|
+
* you may not use this file except in compliance with the License.
|
|
254
|
+
* You may obtain a copy of the License at
|
|
255
|
+
*
|
|
256
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
257
|
+
*
|
|
258
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
259
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
260
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
261
|
+
* See the License for the specific language governing permissions and
|
|
262
|
+
* limitations under the License.
|
|
263
|
+
*/
|
|
264
|
+
let encoderImpl;
|
|
265
|
+
function setEncoder(encoder) {
|
|
266
|
+
encoderImpl = encoder;
|
|
267
|
+
}
|
|
268
268
|
setEncoder(o => JSON.stringify(o));
|
|
269
269
|
|
|
270
|
-
/**
|
|
271
|
-
* @license
|
|
272
|
-
* Copyright 2024 Google LLC
|
|
273
|
-
*
|
|
274
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
275
|
-
* you may not use this file except in compliance with the License.
|
|
276
|
-
* You may obtain a copy of the License at
|
|
277
|
-
*
|
|
278
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
279
|
-
*
|
|
280
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
281
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
282
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
283
|
-
* See the License for the specific language governing permissions and
|
|
284
|
-
* limitations under the License.
|
|
285
|
-
*/
|
|
286
|
-
function setIfNotExists(map, key, val) {
|
|
287
|
-
if (!map.has(key)) {
|
|
288
|
-
map.set(key, val);
|
|
289
|
-
}
|
|
270
|
+
/**
|
|
271
|
+
* @license
|
|
272
|
+
* Copyright 2024 Google LLC
|
|
273
|
+
*
|
|
274
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
275
|
+
* you may not use this file except in compliance with the License.
|
|
276
|
+
* You may obtain a copy of the License at
|
|
277
|
+
*
|
|
278
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
279
|
+
*
|
|
280
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
281
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
282
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
283
|
+
* See the License for the specific language governing permissions and
|
|
284
|
+
* limitations under the License.
|
|
285
|
+
*/
|
|
286
|
+
function setIfNotExists(map, key, val) {
|
|
287
|
+
if (!map.has(key)) {
|
|
288
|
+
map.set(key, val);
|
|
289
|
+
}
|
|
290
290
|
}
|
|
291
291
|
|
|
292
|
-
/**
|
|
293
|
-
* @license
|
|
294
|
-
* Copyright 2024 Google LLC
|
|
295
|
-
*
|
|
296
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
297
|
-
* you may not use this file except in compliance with the License.
|
|
298
|
-
* You may obtain a copy of the License at
|
|
299
|
-
*
|
|
300
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
301
|
-
*
|
|
302
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
303
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
304
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
305
|
-
* See the License for the specific language governing permissions and
|
|
306
|
-
* limitations under the License.
|
|
307
|
-
*/
|
|
308
|
-
function getRefSerializer(queryRef, data, source) {
|
|
309
|
-
return function toJSON() {
|
|
310
|
-
return {
|
|
311
|
-
data,
|
|
312
|
-
refInfo: {
|
|
313
|
-
name: queryRef.name,
|
|
314
|
-
variables: queryRef.variables,
|
|
315
|
-
connectorConfig: Object.assign({ projectId: queryRef.dataConnect.app.options.projectId }, queryRef.dataConnect.getSettings())
|
|
316
|
-
},
|
|
317
|
-
fetchTime: Date.now().toLocaleString(),
|
|
318
|
-
source
|
|
319
|
-
};
|
|
320
|
-
};
|
|
321
|
-
}
|
|
322
|
-
class QueryManager {
|
|
323
|
-
constructor(transport) {
|
|
324
|
-
this.transport = transport;
|
|
325
|
-
this._queries = new Map();
|
|
326
|
-
}
|
|
327
|
-
track(queryName, variables, initialCache) {
|
|
328
|
-
const ref = {
|
|
329
|
-
name: queryName,
|
|
330
|
-
variables,
|
|
331
|
-
refType: QUERY_STR
|
|
332
|
-
};
|
|
333
|
-
const key = encoderImpl(ref);
|
|
334
|
-
const newTrackedQuery = {
|
|
335
|
-
ref,
|
|
336
|
-
subscriptions: [],
|
|
337
|
-
currentCache: initialCache || null,
|
|
338
|
-
lastError: null
|
|
339
|
-
};
|
|
340
|
-
// @ts-ignore
|
|
341
|
-
setIfNotExists(this._queries, key, newTrackedQuery);
|
|
342
|
-
return this._queries.get(key);
|
|
343
|
-
}
|
|
344
|
-
addSubscription(queryRef, onResultCallback, onErrorCallback, initialCache) {
|
|
345
|
-
const key = encoderImpl({
|
|
346
|
-
name: queryRef.name,
|
|
347
|
-
variables: queryRef.variables,
|
|
348
|
-
refType: QUERY_STR
|
|
349
|
-
});
|
|
350
|
-
const trackedQuery = this._queries.get(key);
|
|
351
|
-
const subscription = {
|
|
352
|
-
userCallback: onResultCallback,
|
|
353
|
-
errCallback: onErrorCallback
|
|
354
|
-
};
|
|
355
|
-
const unsubscribe = () => {
|
|
356
|
-
const trackedQuery = this._queries.get(key);
|
|
357
|
-
trackedQuery.subscriptions = trackedQuery.subscriptions.filter(sub => sub !== subscription);
|
|
358
|
-
};
|
|
359
|
-
if (initialCache && trackedQuery.currentCache !== initialCache) {
|
|
360
|
-
logDebug('Initial cache found. Comparing dates.');
|
|
361
|
-
if (!trackedQuery.currentCache ||
|
|
362
|
-
(trackedQuery.currentCache &&
|
|
363
|
-
compareDates(trackedQuery.currentCache.fetchTime, initialCache.fetchTime))) {
|
|
364
|
-
trackedQuery.currentCache = initialCache;
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
if (trackedQuery.currentCache !== null) {
|
|
368
|
-
const cachedData = trackedQuery.currentCache.data;
|
|
369
|
-
onResultCallback({
|
|
370
|
-
data: cachedData,
|
|
371
|
-
source: SOURCE_CACHE,
|
|
372
|
-
ref: queryRef,
|
|
373
|
-
toJSON: getRefSerializer(queryRef, trackedQuery.currentCache.data, SOURCE_CACHE),
|
|
374
|
-
fetchTime: trackedQuery.currentCache.fetchTime
|
|
375
|
-
});
|
|
376
|
-
if (trackedQuery.lastError !== null && onErrorCallback) {
|
|
377
|
-
onErrorCallback(undefined);
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
trackedQuery.subscriptions.push({
|
|
381
|
-
userCallback: onResultCallback,
|
|
382
|
-
errCallback: onErrorCallback,
|
|
383
|
-
unsubscribe
|
|
384
|
-
});
|
|
385
|
-
if (!trackedQuery.currentCache) {
|
|
386
|
-
logDebug(`No cache available for query ${queryRef.name} with variables ${JSON.stringify(queryRef.variables)}. Calling executeQuery.`);
|
|
387
|
-
const promise = this.executeQuery(queryRef);
|
|
388
|
-
// We want to ignore the error and let subscriptions handle it
|
|
389
|
-
promise.then(undefined, err => { });
|
|
390
|
-
}
|
|
391
|
-
return unsubscribe;
|
|
392
|
-
}
|
|
393
|
-
executeQuery(queryRef) {
|
|
394
|
-
if (queryRef.refType !== QUERY_STR) {
|
|
395
|
-
throw new DataConnectError(Code.INVALID_ARGUMENT, `ExecuteQuery can only execute query operation`);
|
|
396
|
-
}
|
|
397
|
-
const key = encoderImpl({
|
|
398
|
-
name: queryRef.name,
|
|
399
|
-
variables: queryRef.variables,
|
|
400
|
-
refType: QUERY_STR
|
|
401
|
-
});
|
|
402
|
-
const trackedQuery = this._queries.get(key);
|
|
403
|
-
const result = this.transport.invokeQuery(queryRef.name, queryRef.variables);
|
|
404
|
-
const newR = result.then(res => {
|
|
405
|
-
const fetchTime = new Date().toString();
|
|
406
|
-
const result = Object.assign(Object.assign({}, res), { source: SOURCE_SERVER, ref: queryRef, toJSON: getRefSerializer(queryRef, res.data, SOURCE_SERVER), fetchTime });
|
|
407
|
-
trackedQuery.subscriptions.forEach(subscription => {
|
|
408
|
-
subscription.userCallback(result);
|
|
409
|
-
});
|
|
410
|
-
trackedQuery.currentCache = {
|
|
411
|
-
data: res.data,
|
|
412
|
-
source: SOURCE_CACHE,
|
|
413
|
-
fetchTime
|
|
414
|
-
};
|
|
415
|
-
return result;
|
|
416
|
-
}, err => {
|
|
417
|
-
trackedQuery.lastError = err;
|
|
418
|
-
trackedQuery.subscriptions.forEach(subscription => {
|
|
419
|
-
if (subscription.errCallback) {
|
|
420
|
-
subscription.errCallback(err);
|
|
421
|
-
}
|
|
422
|
-
});
|
|
423
|
-
throw err;
|
|
424
|
-
});
|
|
425
|
-
return newR;
|
|
426
|
-
}
|
|
427
|
-
enableEmulator(host, port) {
|
|
428
|
-
this.transport.useEmulator(host, port);
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
function compareDates(str1, str2) {
|
|
432
|
-
const date1 = new Date(str1);
|
|
433
|
-
const date2 = new Date(str2);
|
|
434
|
-
return date1.getTime() < date2.getTime();
|
|
292
|
+
/**
|
|
293
|
+
* @license
|
|
294
|
+
* Copyright 2024 Google LLC
|
|
295
|
+
*
|
|
296
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
297
|
+
* you may not use this file except in compliance with the License.
|
|
298
|
+
* You may obtain a copy of the License at
|
|
299
|
+
*
|
|
300
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
301
|
+
*
|
|
302
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
303
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
304
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
305
|
+
* See the License for the specific language governing permissions and
|
|
306
|
+
* limitations under the License.
|
|
307
|
+
*/
|
|
308
|
+
function getRefSerializer(queryRef, data, source) {
|
|
309
|
+
return function toJSON() {
|
|
310
|
+
return {
|
|
311
|
+
data,
|
|
312
|
+
refInfo: {
|
|
313
|
+
name: queryRef.name,
|
|
314
|
+
variables: queryRef.variables,
|
|
315
|
+
connectorConfig: Object.assign({ projectId: queryRef.dataConnect.app.options.projectId }, queryRef.dataConnect.getSettings())
|
|
316
|
+
},
|
|
317
|
+
fetchTime: Date.now().toLocaleString(),
|
|
318
|
+
source
|
|
319
|
+
};
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
class QueryManager {
|
|
323
|
+
constructor(transport) {
|
|
324
|
+
this.transport = transport;
|
|
325
|
+
this._queries = new Map();
|
|
326
|
+
}
|
|
327
|
+
track(queryName, variables, initialCache) {
|
|
328
|
+
const ref = {
|
|
329
|
+
name: queryName,
|
|
330
|
+
variables,
|
|
331
|
+
refType: QUERY_STR
|
|
332
|
+
};
|
|
333
|
+
const key = encoderImpl(ref);
|
|
334
|
+
const newTrackedQuery = {
|
|
335
|
+
ref,
|
|
336
|
+
subscriptions: [],
|
|
337
|
+
currentCache: initialCache || null,
|
|
338
|
+
lastError: null
|
|
339
|
+
};
|
|
340
|
+
// @ts-ignore
|
|
341
|
+
setIfNotExists(this._queries, key, newTrackedQuery);
|
|
342
|
+
return this._queries.get(key);
|
|
343
|
+
}
|
|
344
|
+
addSubscription(queryRef, onResultCallback, onErrorCallback, initialCache) {
|
|
345
|
+
const key = encoderImpl({
|
|
346
|
+
name: queryRef.name,
|
|
347
|
+
variables: queryRef.variables,
|
|
348
|
+
refType: QUERY_STR
|
|
349
|
+
});
|
|
350
|
+
const trackedQuery = this._queries.get(key);
|
|
351
|
+
const subscription = {
|
|
352
|
+
userCallback: onResultCallback,
|
|
353
|
+
errCallback: onErrorCallback
|
|
354
|
+
};
|
|
355
|
+
const unsubscribe = () => {
|
|
356
|
+
const trackedQuery = this._queries.get(key);
|
|
357
|
+
trackedQuery.subscriptions = trackedQuery.subscriptions.filter(sub => sub !== subscription);
|
|
358
|
+
};
|
|
359
|
+
if (initialCache && trackedQuery.currentCache !== initialCache) {
|
|
360
|
+
logDebug('Initial cache found. Comparing dates.');
|
|
361
|
+
if (!trackedQuery.currentCache ||
|
|
362
|
+
(trackedQuery.currentCache &&
|
|
363
|
+
compareDates(trackedQuery.currentCache.fetchTime, initialCache.fetchTime))) {
|
|
364
|
+
trackedQuery.currentCache = initialCache;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
if (trackedQuery.currentCache !== null) {
|
|
368
|
+
const cachedData = trackedQuery.currentCache.data;
|
|
369
|
+
onResultCallback({
|
|
370
|
+
data: cachedData,
|
|
371
|
+
source: SOURCE_CACHE,
|
|
372
|
+
ref: queryRef,
|
|
373
|
+
toJSON: getRefSerializer(queryRef, trackedQuery.currentCache.data, SOURCE_CACHE),
|
|
374
|
+
fetchTime: trackedQuery.currentCache.fetchTime
|
|
375
|
+
});
|
|
376
|
+
if (trackedQuery.lastError !== null && onErrorCallback) {
|
|
377
|
+
onErrorCallback(undefined);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
trackedQuery.subscriptions.push({
|
|
381
|
+
userCallback: onResultCallback,
|
|
382
|
+
errCallback: onErrorCallback,
|
|
383
|
+
unsubscribe
|
|
384
|
+
});
|
|
385
|
+
if (!trackedQuery.currentCache) {
|
|
386
|
+
logDebug(`No cache available for query ${queryRef.name} with variables ${JSON.stringify(queryRef.variables)}. Calling executeQuery.`);
|
|
387
|
+
const promise = this.executeQuery(queryRef);
|
|
388
|
+
// We want to ignore the error and let subscriptions handle it
|
|
389
|
+
promise.then(undefined, err => { });
|
|
390
|
+
}
|
|
391
|
+
return unsubscribe;
|
|
392
|
+
}
|
|
393
|
+
executeQuery(queryRef) {
|
|
394
|
+
if (queryRef.refType !== QUERY_STR) {
|
|
395
|
+
throw new DataConnectError(Code.INVALID_ARGUMENT, `ExecuteQuery can only execute query operation`);
|
|
396
|
+
}
|
|
397
|
+
const key = encoderImpl({
|
|
398
|
+
name: queryRef.name,
|
|
399
|
+
variables: queryRef.variables,
|
|
400
|
+
refType: QUERY_STR
|
|
401
|
+
});
|
|
402
|
+
const trackedQuery = this._queries.get(key);
|
|
403
|
+
const result = this.transport.invokeQuery(queryRef.name, queryRef.variables);
|
|
404
|
+
const newR = result.then(res => {
|
|
405
|
+
const fetchTime = new Date().toString();
|
|
406
|
+
const result = Object.assign(Object.assign({}, res), { source: SOURCE_SERVER, ref: queryRef, toJSON: getRefSerializer(queryRef, res.data, SOURCE_SERVER), fetchTime });
|
|
407
|
+
trackedQuery.subscriptions.forEach(subscription => {
|
|
408
|
+
subscription.userCallback(result);
|
|
409
|
+
});
|
|
410
|
+
trackedQuery.currentCache = {
|
|
411
|
+
data: res.data,
|
|
412
|
+
source: SOURCE_CACHE,
|
|
413
|
+
fetchTime
|
|
414
|
+
};
|
|
415
|
+
return result;
|
|
416
|
+
}, err => {
|
|
417
|
+
trackedQuery.lastError = err;
|
|
418
|
+
trackedQuery.subscriptions.forEach(subscription => {
|
|
419
|
+
if (subscription.errCallback) {
|
|
420
|
+
subscription.errCallback(err);
|
|
421
|
+
}
|
|
422
|
+
});
|
|
423
|
+
throw err;
|
|
424
|
+
});
|
|
425
|
+
return newR;
|
|
426
|
+
}
|
|
427
|
+
enableEmulator(host, port) {
|
|
428
|
+
this.transport.useEmulator(host, port);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
function compareDates(str1, str2) {
|
|
432
|
+
const date1 = new Date(str1);
|
|
433
|
+
const date2 = new Date(str2);
|
|
434
|
+
return date1.getTime() < date2.getTime();
|
|
435
435
|
}
|
|
436
436
|
|
|
437
|
-
/**
|
|
438
|
-
* @license
|
|
439
|
-
* Copyright 2024 Google LLC
|
|
440
|
-
*
|
|
441
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
442
|
-
* you may not use this file except in compliance with the License.
|
|
443
|
-
* You may obtain a copy of the License at
|
|
444
|
-
*
|
|
445
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
446
|
-
*
|
|
447
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
448
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
449
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
450
|
-
* See the License for the specific language governing permissions and
|
|
451
|
-
* limitations under the License.
|
|
452
|
-
*/
|
|
453
|
-
function urlBuilder(projectConfig, transportOptions) {
|
|
454
|
-
const { connector, location, projectId: project, service } = projectConfig;
|
|
455
|
-
const { host, sslEnabled, port } = transportOptions;
|
|
456
|
-
const protocol = sslEnabled ? 'https' : 'http';
|
|
457
|
-
const realHost = host || `firebasedataconnect.googleapis.com`;
|
|
458
|
-
let baseUrl = `${protocol}://${realHost}`;
|
|
459
|
-
if (typeof port === 'number') {
|
|
460
|
-
baseUrl += `:${port}`;
|
|
461
|
-
}
|
|
462
|
-
else if (typeof port !== 'undefined') {
|
|
463
|
-
logError('Port type is of an invalid type');
|
|
464
|
-
throw new DataConnectError(Code.INVALID_ARGUMENT, 'Incorrect type for port passed in!');
|
|
465
|
-
}
|
|
466
|
-
return `${baseUrl}/v1beta/projects/${project}/locations/${location}/services/${service}/connectors/${connector}`;
|
|
467
|
-
}
|
|
468
|
-
function addToken(url, apiKey) {
|
|
469
|
-
if (!apiKey) {
|
|
470
|
-
return url;
|
|
471
|
-
}
|
|
472
|
-
const newUrl = new URL(url);
|
|
473
|
-
newUrl.searchParams.append('key', apiKey);
|
|
474
|
-
return newUrl.toString();
|
|
437
|
+
/**
|
|
438
|
+
* @license
|
|
439
|
+
* Copyright 2024 Google LLC
|
|
440
|
+
*
|
|
441
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
442
|
+
* you may not use this file except in compliance with the License.
|
|
443
|
+
* You may obtain a copy of the License at
|
|
444
|
+
*
|
|
445
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
446
|
+
*
|
|
447
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
448
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
449
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
450
|
+
* See the License for the specific language governing permissions and
|
|
451
|
+
* limitations under the License.
|
|
452
|
+
*/
|
|
453
|
+
function urlBuilder(projectConfig, transportOptions) {
|
|
454
|
+
const { connector, location, projectId: project, service } = projectConfig;
|
|
455
|
+
const { host, sslEnabled, port } = transportOptions;
|
|
456
|
+
const protocol = sslEnabled ? 'https' : 'http';
|
|
457
|
+
const realHost = host || `firebasedataconnect.googleapis.com`;
|
|
458
|
+
let baseUrl = `${protocol}://${realHost}`;
|
|
459
|
+
if (typeof port === 'number') {
|
|
460
|
+
baseUrl += `:${port}`;
|
|
461
|
+
}
|
|
462
|
+
else if (typeof port !== 'undefined') {
|
|
463
|
+
logError('Port type is of an invalid type');
|
|
464
|
+
throw new DataConnectError(Code.INVALID_ARGUMENT, 'Incorrect type for port passed in!');
|
|
465
|
+
}
|
|
466
|
+
return `${baseUrl}/v1beta/projects/${project}/locations/${location}/services/${service}/connectors/${connector}`;
|
|
467
|
+
}
|
|
468
|
+
function addToken(url, apiKey) {
|
|
469
|
+
if (!apiKey) {
|
|
470
|
+
return url;
|
|
471
|
+
}
|
|
472
|
+
const newUrl = new URL(url);
|
|
473
|
+
newUrl.searchParams.append('key', apiKey);
|
|
474
|
+
return newUrl.toString();
|
|
475
475
|
}
|
|
476
476
|
|
|
477
|
-
/**
|
|
478
|
-
* @license
|
|
479
|
-
* Copyright 2024 Google LLC
|
|
480
|
-
*
|
|
481
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
482
|
-
* you may not use this file except in compliance with the License.
|
|
483
|
-
* You may obtain a copy of the License at
|
|
484
|
-
*
|
|
485
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
486
|
-
*
|
|
487
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
488
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
489
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
490
|
-
* See the License for the specific language governing permissions and
|
|
491
|
-
* limitations under the License.
|
|
492
|
-
*/
|
|
493
|
-
let connectFetch = globalThis.fetch;
|
|
494
|
-
function getGoogApiClientValue(_isUsingGen) {
|
|
495
|
-
let str = 'gl-js/ fire/' + SDK_VERSION;
|
|
496
|
-
if (_isUsingGen) {
|
|
497
|
-
str += ' js/gen';
|
|
498
|
-
}
|
|
499
|
-
return str;
|
|
500
|
-
}
|
|
501
|
-
function dcFetch(url, body, { signal }, appId, accessToken, appCheckToken, _isUsingGen) {
|
|
502
|
-
if (!connectFetch) {
|
|
503
|
-
throw new DataConnectError(Code.OTHER, 'No Fetch Implementation detected!');
|
|
504
|
-
}
|
|
505
|
-
const headers = {
|
|
506
|
-
'Content-Type': 'application/json',
|
|
507
|
-
'X-Goog-Api-Client': getGoogApiClientValue(_isUsingGen)
|
|
508
|
-
};
|
|
509
|
-
if (accessToken) {
|
|
510
|
-
headers['X-Firebase-Auth-Token'] = accessToken;
|
|
511
|
-
}
|
|
512
|
-
if (appId) {
|
|
513
|
-
headers['x-firebase-gmpid'] = appId;
|
|
514
|
-
}
|
|
515
|
-
if (appCheckToken) {
|
|
516
|
-
headers['X-Firebase-AppCheck'] = appCheckToken;
|
|
517
|
-
}
|
|
518
|
-
const bodyStr = JSON.stringify(body);
|
|
519
|
-
logDebug(`Making request out to ${url} with body: ${bodyStr}`);
|
|
520
|
-
return connectFetch(url, {
|
|
521
|
-
body: bodyStr,
|
|
522
|
-
method: 'POST',
|
|
523
|
-
headers,
|
|
524
|
-
signal
|
|
525
|
-
})
|
|
526
|
-
.catch(err => {
|
|
527
|
-
throw new DataConnectError(Code.OTHER, 'Failed to fetch: ' + JSON.stringify(err));
|
|
528
|
-
})
|
|
529
|
-
.then(async (response) => {
|
|
530
|
-
let jsonResponse = null;
|
|
531
|
-
try {
|
|
532
|
-
jsonResponse = await response.json();
|
|
533
|
-
}
|
|
534
|
-
catch (e) {
|
|
535
|
-
throw new DataConnectError(Code.OTHER, JSON.stringify(e));
|
|
536
|
-
}
|
|
537
|
-
const message = getMessage(jsonResponse);
|
|
538
|
-
if (response.status >= 400) {
|
|
539
|
-
logError('Error while performing request: ' + JSON.stringify(jsonResponse));
|
|
540
|
-
if (response.status === 401) {
|
|
541
|
-
throw new DataConnectError(Code.UNAUTHORIZED, message);
|
|
542
|
-
}
|
|
543
|
-
throw new DataConnectError(Code.OTHER, message);
|
|
544
|
-
}
|
|
545
|
-
return jsonResponse;
|
|
546
|
-
})
|
|
547
|
-
.then(res => {
|
|
548
|
-
if (res.errors && res.errors.length) {
|
|
549
|
-
const stringified = JSON.stringify(res.errors);
|
|
550
|
-
logError('DataConnect error while performing request: ' + stringified);
|
|
551
|
-
throw new DataConnectError(Code.OTHER, stringified);
|
|
552
|
-
}
|
|
553
|
-
return res;
|
|
554
|
-
});
|
|
555
|
-
}
|
|
556
|
-
function getMessage(obj) {
|
|
557
|
-
if ('message' in obj) {
|
|
558
|
-
return obj.message;
|
|
559
|
-
}
|
|
560
|
-
return JSON.stringify(obj);
|
|
477
|
+
/**
|
|
478
|
+
* @license
|
|
479
|
+
* Copyright 2024 Google LLC
|
|
480
|
+
*
|
|
481
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
482
|
+
* you may not use this file except in compliance with the License.
|
|
483
|
+
* You may obtain a copy of the License at
|
|
484
|
+
*
|
|
485
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
486
|
+
*
|
|
487
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
488
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
489
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
490
|
+
* See the License for the specific language governing permissions and
|
|
491
|
+
* limitations under the License.
|
|
492
|
+
*/
|
|
493
|
+
let connectFetch = globalThis.fetch;
|
|
494
|
+
function getGoogApiClientValue(_isUsingGen) {
|
|
495
|
+
let str = 'gl-js/ fire/' + SDK_VERSION;
|
|
496
|
+
if (_isUsingGen) {
|
|
497
|
+
str += ' js/gen';
|
|
498
|
+
}
|
|
499
|
+
return str;
|
|
500
|
+
}
|
|
501
|
+
function dcFetch(url, body, { signal }, appId, accessToken, appCheckToken, _isUsingGen) {
|
|
502
|
+
if (!connectFetch) {
|
|
503
|
+
throw new DataConnectError(Code.OTHER, 'No Fetch Implementation detected!');
|
|
504
|
+
}
|
|
505
|
+
const headers = {
|
|
506
|
+
'Content-Type': 'application/json',
|
|
507
|
+
'X-Goog-Api-Client': getGoogApiClientValue(_isUsingGen)
|
|
508
|
+
};
|
|
509
|
+
if (accessToken) {
|
|
510
|
+
headers['X-Firebase-Auth-Token'] = accessToken;
|
|
511
|
+
}
|
|
512
|
+
if (appId) {
|
|
513
|
+
headers['x-firebase-gmpid'] = appId;
|
|
514
|
+
}
|
|
515
|
+
if (appCheckToken) {
|
|
516
|
+
headers['X-Firebase-AppCheck'] = appCheckToken;
|
|
517
|
+
}
|
|
518
|
+
const bodyStr = JSON.stringify(body);
|
|
519
|
+
logDebug(`Making request out to ${url} with body: ${bodyStr}`);
|
|
520
|
+
return connectFetch(url, {
|
|
521
|
+
body: bodyStr,
|
|
522
|
+
method: 'POST',
|
|
523
|
+
headers,
|
|
524
|
+
signal
|
|
525
|
+
})
|
|
526
|
+
.catch(err => {
|
|
527
|
+
throw new DataConnectError(Code.OTHER, 'Failed to fetch: ' + JSON.stringify(err));
|
|
528
|
+
})
|
|
529
|
+
.then(async (response) => {
|
|
530
|
+
let jsonResponse = null;
|
|
531
|
+
try {
|
|
532
|
+
jsonResponse = await response.json();
|
|
533
|
+
}
|
|
534
|
+
catch (e) {
|
|
535
|
+
throw new DataConnectError(Code.OTHER, JSON.stringify(e));
|
|
536
|
+
}
|
|
537
|
+
const message = getMessage(jsonResponse);
|
|
538
|
+
if (response.status >= 400) {
|
|
539
|
+
logError('Error while performing request: ' + JSON.stringify(jsonResponse));
|
|
540
|
+
if (response.status === 401) {
|
|
541
|
+
throw new DataConnectError(Code.UNAUTHORIZED, message);
|
|
542
|
+
}
|
|
543
|
+
throw new DataConnectError(Code.OTHER, message);
|
|
544
|
+
}
|
|
545
|
+
return jsonResponse;
|
|
546
|
+
})
|
|
547
|
+
.then(res => {
|
|
548
|
+
if (res.errors && res.errors.length) {
|
|
549
|
+
const stringified = JSON.stringify(res.errors);
|
|
550
|
+
logError('DataConnect error while performing request: ' + stringified);
|
|
551
|
+
throw new DataConnectError(Code.OTHER, stringified);
|
|
552
|
+
}
|
|
553
|
+
return res;
|
|
554
|
+
});
|
|
555
|
+
}
|
|
556
|
+
function getMessage(obj) {
|
|
557
|
+
if ('message' in obj) {
|
|
558
|
+
return obj.message;
|
|
559
|
+
}
|
|
560
|
+
return JSON.stringify(obj);
|
|
561
561
|
}
|
|
562
562
|
|
|
563
|
-
/**
|
|
564
|
-
* @license
|
|
565
|
-
* Copyright 2024 Google LLC
|
|
566
|
-
*
|
|
567
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
568
|
-
* you may not use this file except in compliance with the License.
|
|
569
|
-
* You may obtain a copy of the License at
|
|
570
|
-
*
|
|
571
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
572
|
-
*
|
|
573
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
574
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
575
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
576
|
-
* See the License for the specific language governing permissions and
|
|
577
|
-
* limitations under the License.
|
|
578
|
-
*/
|
|
579
|
-
class RESTTransport {
|
|
580
|
-
constructor(options, apiKey, appId, authProvider, appCheckProvider, transportOptions, _isUsingGen = false) {
|
|
581
|
-
var _a, _b;
|
|
582
|
-
this.apiKey = apiKey;
|
|
583
|
-
this.appId = appId;
|
|
584
|
-
this.authProvider = authProvider;
|
|
585
|
-
this.appCheckProvider = appCheckProvider;
|
|
586
|
-
this._isUsingGen = _isUsingGen;
|
|
587
|
-
this._host = '';
|
|
588
|
-
this._location = 'l';
|
|
589
|
-
this._connectorName = '';
|
|
590
|
-
this._secure = true;
|
|
591
|
-
this._project = 'p';
|
|
592
|
-
this._accessToken = null;
|
|
593
|
-
this._appCheckToken = null;
|
|
594
|
-
this._lastToken = null;
|
|
595
|
-
// TODO(mtewani): Update U to include shape of body defined in line 13.
|
|
596
|
-
this.invokeQuery = (queryName, body) => {
|
|
597
|
-
const abortController = new AbortController();
|
|
598
|
-
// TODO(mtewani): Update to proper value
|
|
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));
|
|
605
|
-
return {
|
|
606
|
-
then: withAuth.then.bind(withAuth),
|
|
607
|
-
catch: withAuth.catch.bind(withAuth)
|
|
608
|
-
};
|
|
609
|
-
};
|
|
610
|
-
this.invokeMutation = (mutationName, body) => {
|
|
611
|
-
const abortController = new AbortController();
|
|
612
|
-
const taskResult = this.withRetry(() => {
|
|
613
|
-
return dcFetch(addToken(`${this.endpointUrl}:executeMutation`, this.apiKey), {
|
|
614
|
-
name: `projects/${this._project}/locations/${this._location}/services/${this._serviceName}/connectors/${this._connectorName}`,
|
|
615
|
-
operationName: mutationName,
|
|
616
|
-
variables: body
|
|
617
|
-
}, abortController, this.appId, this._accessToken, this._appCheckToken, this._isUsingGen);
|
|
618
|
-
});
|
|
619
|
-
return {
|
|
620
|
-
then: taskResult.then.bind(taskResult),
|
|
621
|
-
// catch: taskResult.catch.bind(taskResult),
|
|
622
|
-
// finally: taskResult.finally.bind(taskResult),
|
|
623
|
-
cancel: () => abortController.abort()
|
|
624
|
-
};
|
|
625
|
-
};
|
|
626
|
-
if (transportOptions) {
|
|
627
|
-
if (typeof transportOptions.port === 'number') {
|
|
628
|
-
this._port = transportOptions.port;
|
|
629
|
-
}
|
|
630
|
-
if (typeof transportOptions.sslEnabled !== 'undefined') {
|
|
631
|
-
this._secure = transportOptions.sslEnabled;
|
|
632
|
-
}
|
|
633
|
-
this._host = transportOptions.host;
|
|
634
|
-
}
|
|
635
|
-
const { location, projectId: project, connector, service } = options;
|
|
636
|
-
if (location) {
|
|
637
|
-
this._location = location;
|
|
638
|
-
}
|
|
639
|
-
if (project) {
|
|
640
|
-
this._project = project;
|
|
641
|
-
}
|
|
642
|
-
this._serviceName = service;
|
|
643
|
-
if (!connector) {
|
|
644
|
-
throw new DataConnectError(Code.INVALID_ARGUMENT, 'Connector Name required!');
|
|
645
|
-
}
|
|
646
|
-
this._connectorName = connector;
|
|
647
|
-
(_a = this.authProvider) === null || _a === void 0 ? void 0 : _a.addTokenChangeListener(token => {
|
|
648
|
-
logDebug(`New Token Available: ${token}`);
|
|
649
|
-
this._accessToken = token;
|
|
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
|
-
});
|
|
656
|
-
}
|
|
657
|
-
get endpointUrl() {
|
|
658
|
-
return urlBuilder({
|
|
659
|
-
connector: this._connectorName,
|
|
660
|
-
location: this._location,
|
|
661
|
-
projectId: this._project,
|
|
662
|
-
service: this._serviceName
|
|
663
|
-
}, { host: this._host, sslEnabled: this._secure, port: this._port });
|
|
664
|
-
}
|
|
665
|
-
useEmulator(host, port, isSecure) {
|
|
666
|
-
this._host = host;
|
|
667
|
-
if (typeof port === 'number') {
|
|
668
|
-
this._port = port;
|
|
669
|
-
}
|
|
670
|
-
if (typeof isSecure !== 'undefined') {
|
|
671
|
-
this._secure = isSecure;
|
|
672
|
-
}
|
|
673
|
-
}
|
|
674
|
-
onTokenChanged(newToken) {
|
|
675
|
-
this._accessToken = newToken;
|
|
676
|
-
}
|
|
677
|
-
async getWithAuth(forceToken = false) {
|
|
678
|
-
var _a;
|
|
679
|
-
let starterPromise = new Promise(resolve => resolve(this._accessToken));
|
|
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(''));
|
|
696
|
-
}
|
|
697
|
-
return starterPromise;
|
|
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
|
-
}
|
|
563
|
+
/**
|
|
564
|
+
* @license
|
|
565
|
+
* Copyright 2024 Google LLC
|
|
566
|
+
*
|
|
567
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
568
|
+
* you may not use this file except in compliance with the License.
|
|
569
|
+
* You may obtain a copy of the License at
|
|
570
|
+
*
|
|
571
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
572
|
+
*
|
|
573
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
574
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
575
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
576
|
+
* See the License for the specific language governing permissions and
|
|
577
|
+
* limitations under the License.
|
|
578
|
+
*/
|
|
579
|
+
class RESTTransport {
|
|
580
|
+
constructor(options, apiKey, appId, authProvider, appCheckProvider, transportOptions, _isUsingGen = false) {
|
|
581
|
+
var _a, _b;
|
|
582
|
+
this.apiKey = apiKey;
|
|
583
|
+
this.appId = appId;
|
|
584
|
+
this.authProvider = authProvider;
|
|
585
|
+
this.appCheckProvider = appCheckProvider;
|
|
586
|
+
this._isUsingGen = _isUsingGen;
|
|
587
|
+
this._host = '';
|
|
588
|
+
this._location = 'l';
|
|
589
|
+
this._connectorName = '';
|
|
590
|
+
this._secure = true;
|
|
591
|
+
this._project = 'p';
|
|
592
|
+
this._accessToken = null;
|
|
593
|
+
this._appCheckToken = null;
|
|
594
|
+
this._lastToken = null;
|
|
595
|
+
// TODO(mtewani): Update U to include shape of body defined in line 13.
|
|
596
|
+
this.invokeQuery = (queryName, body) => {
|
|
597
|
+
const abortController = new AbortController();
|
|
598
|
+
// TODO(mtewani): Update to proper value
|
|
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));
|
|
605
|
+
return {
|
|
606
|
+
then: withAuth.then.bind(withAuth),
|
|
607
|
+
catch: withAuth.catch.bind(withAuth)
|
|
608
|
+
};
|
|
609
|
+
};
|
|
610
|
+
this.invokeMutation = (mutationName, body) => {
|
|
611
|
+
const abortController = new AbortController();
|
|
612
|
+
const taskResult = this.withRetry(() => {
|
|
613
|
+
return dcFetch(addToken(`${this.endpointUrl}:executeMutation`, this.apiKey), {
|
|
614
|
+
name: `projects/${this._project}/locations/${this._location}/services/${this._serviceName}/connectors/${this._connectorName}`,
|
|
615
|
+
operationName: mutationName,
|
|
616
|
+
variables: body
|
|
617
|
+
}, abortController, this.appId, this._accessToken, this._appCheckToken, this._isUsingGen);
|
|
618
|
+
});
|
|
619
|
+
return {
|
|
620
|
+
then: taskResult.then.bind(taskResult),
|
|
621
|
+
// catch: taskResult.catch.bind(taskResult),
|
|
622
|
+
// finally: taskResult.finally.bind(taskResult),
|
|
623
|
+
cancel: () => abortController.abort()
|
|
624
|
+
};
|
|
625
|
+
};
|
|
626
|
+
if (transportOptions) {
|
|
627
|
+
if (typeof transportOptions.port === 'number') {
|
|
628
|
+
this._port = transportOptions.port;
|
|
629
|
+
}
|
|
630
|
+
if (typeof transportOptions.sslEnabled !== 'undefined') {
|
|
631
|
+
this._secure = transportOptions.sslEnabled;
|
|
632
|
+
}
|
|
633
|
+
this._host = transportOptions.host;
|
|
634
|
+
}
|
|
635
|
+
const { location, projectId: project, connector, service } = options;
|
|
636
|
+
if (location) {
|
|
637
|
+
this._location = location;
|
|
638
|
+
}
|
|
639
|
+
if (project) {
|
|
640
|
+
this._project = project;
|
|
641
|
+
}
|
|
642
|
+
this._serviceName = service;
|
|
643
|
+
if (!connector) {
|
|
644
|
+
throw new DataConnectError(Code.INVALID_ARGUMENT, 'Connector Name required!');
|
|
645
|
+
}
|
|
646
|
+
this._connectorName = connector;
|
|
647
|
+
(_a = this.authProvider) === null || _a === void 0 ? void 0 : _a.addTokenChangeListener(token => {
|
|
648
|
+
logDebug(`New Token Available: ${token}`);
|
|
649
|
+
this._accessToken = token;
|
|
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
|
+
});
|
|
656
|
+
}
|
|
657
|
+
get endpointUrl() {
|
|
658
|
+
return urlBuilder({
|
|
659
|
+
connector: this._connectorName,
|
|
660
|
+
location: this._location,
|
|
661
|
+
projectId: this._project,
|
|
662
|
+
service: this._serviceName
|
|
663
|
+
}, { host: this._host, sslEnabled: this._secure, port: this._port });
|
|
664
|
+
}
|
|
665
|
+
useEmulator(host, port, isSecure) {
|
|
666
|
+
this._host = host;
|
|
667
|
+
if (typeof port === 'number') {
|
|
668
|
+
this._port = port;
|
|
669
|
+
}
|
|
670
|
+
if (typeof isSecure !== 'undefined') {
|
|
671
|
+
this._secure = isSecure;
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
onTokenChanged(newToken) {
|
|
675
|
+
this._accessToken = newToken;
|
|
676
|
+
}
|
|
677
|
+
async getWithAuth(forceToken = false) {
|
|
678
|
+
var _a;
|
|
679
|
+
let starterPromise = new Promise(resolve => resolve(this._accessToken));
|
|
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(''));
|
|
696
|
+
}
|
|
697
|
+
return starterPromise;
|
|
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
|
+
}
|
|
723
723
|
}
|
|
724
724
|
|
|
725
|
-
/**
|
|
726
|
-
* @license
|
|
727
|
-
* Copyright 2024 Google LLC
|
|
728
|
-
*
|
|
729
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
730
|
-
* you may not use this file except in compliance with the License.
|
|
731
|
-
* You may obtain a copy of the License at
|
|
732
|
-
*
|
|
733
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
734
|
-
*
|
|
735
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
736
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
737
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
738
|
-
* See the License for the specific language governing permissions and
|
|
739
|
-
* limitations under the License.
|
|
740
|
-
*/
|
|
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) {
|
|
749
|
-
dcInstance.setInitialized();
|
|
750
|
-
const ref = {
|
|
751
|
-
dataConnect: dcInstance,
|
|
752
|
-
name: mutationName,
|
|
753
|
-
refType: MUTATION_STR,
|
|
754
|
-
variables: variables
|
|
755
|
-
};
|
|
756
|
-
return ref;
|
|
757
|
-
}
|
|
758
|
-
/**
|
|
759
|
-
* @internal
|
|
760
|
-
*/
|
|
761
|
-
class MutationManager {
|
|
762
|
-
constructor(_transport) {
|
|
763
|
-
this._transport = _transport;
|
|
764
|
-
this._inflight = [];
|
|
765
|
-
}
|
|
766
|
-
executeMutation(mutationRef) {
|
|
767
|
-
const result = this._transport.invokeMutation(mutationRef.name, mutationRef.variables);
|
|
768
|
-
const withRefPromise = result.then(res => {
|
|
769
|
-
const obj = Object.assign(Object.assign({}, res), { source: SOURCE_SERVER, ref: mutationRef, fetchTime: Date.now().toLocaleString() });
|
|
770
|
-
return obj;
|
|
771
|
-
});
|
|
772
|
-
this._inflight.push(result);
|
|
773
|
-
const removePromise = () => (this._inflight = this._inflight.filter(promise => promise !== result));
|
|
774
|
-
result.then(removePromise, removePromise);
|
|
775
|
-
return withRefPromise;
|
|
776
|
-
}
|
|
777
|
-
}
|
|
778
|
-
/**
|
|
779
|
-
* Execute Mutation
|
|
780
|
-
* @param mutationRef mutation to execute
|
|
781
|
-
* @returns `MutationRef`
|
|
782
|
-
*/
|
|
783
|
-
function executeMutation(mutationRef) {
|
|
784
|
-
return mutationRef.dataConnect._mutationManager.executeMutation(mutationRef);
|
|
725
|
+
/**
|
|
726
|
+
* @license
|
|
727
|
+
* Copyright 2024 Google LLC
|
|
728
|
+
*
|
|
729
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
730
|
+
* you may not use this file except in compliance with the License.
|
|
731
|
+
* You may obtain a copy of the License at
|
|
732
|
+
*
|
|
733
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
734
|
+
*
|
|
735
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
736
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
737
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
738
|
+
* See the License for the specific language governing permissions and
|
|
739
|
+
* limitations under the License.
|
|
740
|
+
*/
|
|
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) {
|
|
749
|
+
dcInstance.setInitialized();
|
|
750
|
+
const ref = {
|
|
751
|
+
dataConnect: dcInstance,
|
|
752
|
+
name: mutationName,
|
|
753
|
+
refType: MUTATION_STR,
|
|
754
|
+
variables: variables
|
|
755
|
+
};
|
|
756
|
+
return ref;
|
|
757
|
+
}
|
|
758
|
+
/**
|
|
759
|
+
* @internal
|
|
760
|
+
*/
|
|
761
|
+
class MutationManager {
|
|
762
|
+
constructor(_transport) {
|
|
763
|
+
this._transport = _transport;
|
|
764
|
+
this._inflight = [];
|
|
765
|
+
}
|
|
766
|
+
executeMutation(mutationRef) {
|
|
767
|
+
const result = this._transport.invokeMutation(mutationRef.name, mutationRef.variables);
|
|
768
|
+
const withRefPromise = result.then(res => {
|
|
769
|
+
const obj = Object.assign(Object.assign({}, res), { source: SOURCE_SERVER, ref: mutationRef, fetchTime: Date.now().toLocaleString() });
|
|
770
|
+
return obj;
|
|
771
|
+
});
|
|
772
|
+
this._inflight.push(result);
|
|
773
|
+
const removePromise = () => (this._inflight = this._inflight.filter(promise => promise !== result));
|
|
774
|
+
result.then(removePromise, removePromise);
|
|
775
|
+
return withRefPromise;
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
/**
|
|
779
|
+
* Execute Mutation
|
|
780
|
+
* @param mutationRef mutation to execute
|
|
781
|
+
* @returns `MutationRef`
|
|
782
|
+
*/
|
|
783
|
+
function executeMutation(mutationRef) {
|
|
784
|
+
return mutationRef.dataConnect._mutationManager.executeMutation(mutationRef);
|
|
785
785
|
}
|
|
786
786
|
|
|
787
|
-
/**
|
|
788
|
-
* @license
|
|
789
|
-
* Copyright 2024 Google LLC
|
|
790
|
-
*
|
|
791
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
792
|
-
* you may not use this file except in compliance with the License.
|
|
793
|
-
* You may obtain a copy of the License at
|
|
794
|
-
*
|
|
795
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
796
|
-
*
|
|
797
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
798
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
799
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
800
|
-
* See the License for the specific language governing permissions and
|
|
801
|
-
* limitations under the License.
|
|
802
|
-
*/
|
|
803
|
-
const FIREBASE_DATA_CONNECT_EMULATOR_HOST_VAR = 'FIREBASE_DATA_CONNECT_EMULATOR_HOST';
|
|
804
|
-
/**
|
|
805
|
-
*
|
|
806
|
-
* @param fullHost
|
|
807
|
-
* @returns TransportOptions
|
|
808
|
-
* @internal
|
|
809
|
-
*/
|
|
810
|
-
function parseOptions(fullHost) {
|
|
811
|
-
const [protocol, hostName] = fullHost.split('://');
|
|
812
|
-
const isSecure = protocol === 'https';
|
|
813
|
-
const [host, portAsString] = hostName.split(':');
|
|
814
|
-
const port = Number(portAsString);
|
|
815
|
-
return { host, port, sslEnabled: isSecure };
|
|
816
|
-
}
|
|
817
|
-
/**
|
|
818
|
-
* Class representing Firebase Data Connect
|
|
819
|
-
*/
|
|
820
|
-
class DataConnect {
|
|
821
|
-
// @internal
|
|
822
|
-
constructor(app,
|
|
823
|
-
// TODO(mtewani): Replace with _dataConnectOptions in the future
|
|
824
|
-
dataConnectOptions, _authProvider, _appCheckProvider) {
|
|
825
|
-
this.app = app;
|
|
826
|
-
this.dataConnectOptions = dataConnectOptions;
|
|
827
|
-
this._authProvider = _authProvider;
|
|
828
|
-
this._appCheckProvider = _appCheckProvider;
|
|
829
|
-
this.isEmulator = false;
|
|
830
|
-
this._initialized = false;
|
|
831
|
-
this._isUsingGeneratedSdk = false;
|
|
832
|
-
if (typeof process !== 'undefined' && process.env) {
|
|
833
|
-
const host = process.env[FIREBASE_DATA_CONNECT_EMULATOR_HOST_VAR];
|
|
834
|
-
if (host) {
|
|
835
|
-
logDebug('Found custom host. Using emulator');
|
|
836
|
-
this.isEmulator = true;
|
|
837
|
-
this._transportOptions = parseOptions(host);
|
|
838
|
-
}
|
|
839
|
-
}
|
|
840
|
-
}
|
|
841
|
-
// @internal
|
|
842
|
-
_useGeneratedSdk() {
|
|
843
|
-
if (!this._isUsingGeneratedSdk) {
|
|
844
|
-
this._isUsingGeneratedSdk = true;
|
|
845
|
-
}
|
|
846
|
-
}
|
|
847
|
-
_delete() {
|
|
848
|
-
_removeServiceInstance(this.app, 'data-connect', JSON.stringify(this.getSettings()));
|
|
849
|
-
return Promise.resolve();
|
|
850
|
-
}
|
|
851
|
-
// @internal
|
|
852
|
-
getSettings() {
|
|
853
|
-
const copy = JSON.parse(JSON.stringify(this.dataConnectOptions));
|
|
854
|
-
delete copy.projectId;
|
|
855
|
-
return copy;
|
|
856
|
-
}
|
|
857
|
-
// @internal
|
|
858
|
-
setInitialized() {
|
|
859
|
-
if (this._initialized) {
|
|
860
|
-
return;
|
|
861
|
-
}
|
|
862
|
-
if (this._transportClass === undefined) {
|
|
863
|
-
logDebug('transportClass not provided. Defaulting to RESTTransport.');
|
|
864
|
-
this._transportClass = RESTTransport;
|
|
865
|
-
}
|
|
866
|
-
if (this._authProvider) {
|
|
867
|
-
this._authTokenProvider = new FirebaseAuthProvider(this.app.name, this.app.options, this._authProvider);
|
|
868
|
-
}
|
|
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);
|
|
874
|
-
if (this._transportOptions) {
|
|
875
|
-
this._transport.useEmulator(this._transportOptions.host, this._transportOptions.port, this._transportOptions.sslEnabled);
|
|
876
|
-
}
|
|
877
|
-
this._queryManager = new QueryManager(this._transport);
|
|
878
|
-
this._mutationManager = new MutationManager(this._transport);
|
|
879
|
-
}
|
|
880
|
-
// @internal
|
|
881
|
-
enableEmulator(transportOptions) {
|
|
882
|
-
if (this._initialized) {
|
|
883
|
-
logError('enableEmulator called after initialization');
|
|
884
|
-
throw new DataConnectError(Code.ALREADY_INITIALIZED, 'DataConnect instance already initialized!');
|
|
885
|
-
}
|
|
886
|
-
this._transportOptions = transportOptions;
|
|
887
|
-
this.isEmulator = true;
|
|
888
|
-
}
|
|
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
|
-
*/
|
|
897
|
-
function connectDataConnectEmulator(dc, host, port, sslEnabled = false) {
|
|
898
|
-
dc.enableEmulator({ host, port, sslEnabled });
|
|
899
|
-
}
|
|
900
|
-
function getDataConnect(appOrOptions, optionalOptions) {
|
|
901
|
-
let app;
|
|
902
|
-
let dcOptions;
|
|
903
|
-
if ('location' in appOrOptions) {
|
|
904
|
-
dcOptions = appOrOptions;
|
|
905
|
-
app = getApp();
|
|
906
|
-
}
|
|
907
|
-
else {
|
|
908
|
-
dcOptions = optionalOptions;
|
|
909
|
-
app = appOrOptions;
|
|
910
|
-
}
|
|
911
|
-
if (!app || Object.keys(app).length === 0) {
|
|
912
|
-
app = getApp();
|
|
913
|
-
}
|
|
914
|
-
const provider = _getProvider(app, 'data-connect');
|
|
915
|
-
const identifier = JSON.stringify(dcOptions);
|
|
916
|
-
if (provider.isInitialized(identifier)) {
|
|
917
|
-
const dcInstance = provider.getImmediate({ identifier });
|
|
918
|
-
const options = provider.getOptions(identifier);
|
|
919
|
-
const optionsValid = Object.keys(options).length > 0;
|
|
920
|
-
if (optionsValid) {
|
|
921
|
-
logDebug('Re-using cached instance');
|
|
922
|
-
return dcInstance;
|
|
923
|
-
}
|
|
924
|
-
}
|
|
925
|
-
validateDCOptions(dcOptions);
|
|
926
|
-
logDebug('Creating new DataConnect instance');
|
|
927
|
-
// Initialize with options.
|
|
928
|
-
return provider.initialize({
|
|
929
|
-
instanceIdentifier: identifier,
|
|
930
|
-
options: dcOptions
|
|
931
|
-
});
|
|
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
|
-
*/
|
|
956
|
-
function terminate(dataConnect) {
|
|
957
|
-
return dataConnect._delete();
|
|
958
|
-
// TODO(mtewani): Stop pending tasks
|
|
787
|
+
/**
|
|
788
|
+
* @license
|
|
789
|
+
* Copyright 2024 Google LLC
|
|
790
|
+
*
|
|
791
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
792
|
+
* you may not use this file except in compliance with the License.
|
|
793
|
+
* You may obtain a copy of the License at
|
|
794
|
+
*
|
|
795
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
796
|
+
*
|
|
797
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
798
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
799
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
800
|
+
* See the License for the specific language governing permissions and
|
|
801
|
+
* limitations under the License.
|
|
802
|
+
*/
|
|
803
|
+
const FIREBASE_DATA_CONNECT_EMULATOR_HOST_VAR = 'FIREBASE_DATA_CONNECT_EMULATOR_HOST';
|
|
804
|
+
/**
|
|
805
|
+
*
|
|
806
|
+
* @param fullHost
|
|
807
|
+
* @returns TransportOptions
|
|
808
|
+
* @internal
|
|
809
|
+
*/
|
|
810
|
+
function parseOptions(fullHost) {
|
|
811
|
+
const [protocol, hostName] = fullHost.split('://');
|
|
812
|
+
const isSecure = protocol === 'https';
|
|
813
|
+
const [host, portAsString] = hostName.split(':');
|
|
814
|
+
const port = Number(portAsString);
|
|
815
|
+
return { host, port, sslEnabled: isSecure };
|
|
816
|
+
}
|
|
817
|
+
/**
|
|
818
|
+
* Class representing Firebase Data Connect
|
|
819
|
+
*/
|
|
820
|
+
class DataConnect {
|
|
821
|
+
// @internal
|
|
822
|
+
constructor(app,
|
|
823
|
+
// TODO(mtewani): Replace with _dataConnectOptions in the future
|
|
824
|
+
dataConnectOptions, _authProvider, _appCheckProvider) {
|
|
825
|
+
this.app = app;
|
|
826
|
+
this.dataConnectOptions = dataConnectOptions;
|
|
827
|
+
this._authProvider = _authProvider;
|
|
828
|
+
this._appCheckProvider = _appCheckProvider;
|
|
829
|
+
this.isEmulator = false;
|
|
830
|
+
this._initialized = false;
|
|
831
|
+
this._isUsingGeneratedSdk = false;
|
|
832
|
+
if (typeof process !== 'undefined' && process.env) {
|
|
833
|
+
const host = process.env[FIREBASE_DATA_CONNECT_EMULATOR_HOST_VAR];
|
|
834
|
+
if (host) {
|
|
835
|
+
logDebug('Found custom host. Using emulator');
|
|
836
|
+
this.isEmulator = true;
|
|
837
|
+
this._transportOptions = parseOptions(host);
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
// @internal
|
|
842
|
+
_useGeneratedSdk() {
|
|
843
|
+
if (!this._isUsingGeneratedSdk) {
|
|
844
|
+
this._isUsingGeneratedSdk = true;
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
_delete() {
|
|
848
|
+
_removeServiceInstance(this.app, 'data-connect', JSON.stringify(this.getSettings()));
|
|
849
|
+
return Promise.resolve();
|
|
850
|
+
}
|
|
851
|
+
// @internal
|
|
852
|
+
getSettings() {
|
|
853
|
+
const copy = JSON.parse(JSON.stringify(this.dataConnectOptions));
|
|
854
|
+
delete copy.projectId;
|
|
855
|
+
return copy;
|
|
856
|
+
}
|
|
857
|
+
// @internal
|
|
858
|
+
setInitialized() {
|
|
859
|
+
if (this._initialized) {
|
|
860
|
+
return;
|
|
861
|
+
}
|
|
862
|
+
if (this._transportClass === undefined) {
|
|
863
|
+
logDebug('transportClass not provided. Defaulting to RESTTransport.');
|
|
864
|
+
this._transportClass = RESTTransport;
|
|
865
|
+
}
|
|
866
|
+
if (this._authProvider) {
|
|
867
|
+
this._authTokenProvider = new FirebaseAuthProvider(this.app.name, this.app.options, this._authProvider);
|
|
868
|
+
}
|
|
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);
|
|
874
|
+
if (this._transportOptions) {
|
|
875
|
+
this._transport.useEmulator(this._transportOptions.host, this._transportOptions.port, this._transportOptions.sslEnabled);
|
|
876
|
+
}
|
|
877
|
+
this._queryManager = new QueryManager(this._transport);
|
|
878
|
+
this._mutationManager = new MutationManager(this._transport);
|
|
879
|
+
}
|
|
880
|
+
// @internal
|
|
881
|
+
enableEmulator(transportOptions) {
|
|
882
|
+
if (this._initialized) {
|
|
883
|
+
logError('enableEmulator called after initialization');
|
|
884
|
+
throw new DataConnectError(Code.ALREADY_INITIALIZED, 'DataConnect instance already initialized!');
|
|
885
|
+
}
|
|
886
|
+
this._transportOptions = transportOptions;
|
|
887
|
+
this.isEmulator = true;
|
|
888
|
+
}
|
|
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
|
+
*/
|
|
897
|
+
function connectDataConnectEmulator(dc, host, port, sslEnabled = false) {
|
|
898
|
+
dc.enableEmulator({ host, port, sslEnabled });
|
|
899
|
+
}
|
|
900
|
+
function getDataConnect(appOrOptions, optionalOptions) {
|
|
901
|
+
let app;
|
|
902
|
+
let dcOptions;
|
|
903
|
+
if ('location' in appOrOptions) {
|
|
904
|
+
dcOptions = appOrOptions;
|
|
905
|
+
app = getApp();
|
|
906
|
+
}
|
|
907
|
+
else {
|
|
908
|
+
dcOptions = optionalOptions;
|
|
909
|
+
app = appOrOptions;
|
|
910
|
+
}
|
|
911
|
+
if (!app || Object.keys(app).length === 0) {
|
|
912
|
+
app = getApp();
|
|
913
|
+
}
|
|
914
|
+
const provider = _getProvider(app, 'data-connect');
|
|
915
|
+
const identifier = JSON.stringify(dcOptions);
|
|
916
|
+
if (provider.isInitialized(identifier)) {
|
|
917
|
+
const dcInstance = provider.getImmediate({ identifier });
|
|
918
|
+
const options = provider.getOptions(identifier);
|
|
919
|
+
const optionsValid = Object.keys(options).length > 0;
|
|
920
|
+
if (optionsValid) {
|
|
921
|
+
logDebug('Re-using cached instance');
|
|
922
|
+
return dcInstance;
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
validateDCOptions(dcOptions);
|
|
926
|
+
logDebug('Creating new DataConnect instance');
|
|
927
|
+
// Initialize with options.
|
|
928
|
+
return provider.initialize({
|
|
929
|
+
instanceIdentifier: identifier,
|
|
930
|
+
options: dcOptions
|
|
931
|
+
});
|
|
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
|
+
*/
|
|
956
|
+
function terminate(dataConnect) {
|
|
957
|
+
return dataConnect._delete();
|
|
958
|
+
// TODO(mtewani): Stop pending tasks
|
|
959
959
|
}
|
|
960
960
|
|
|
961
|
-
/**
|
|
962
|
-
* @license
|
|
963
|
-
* Copyright 2024 Google LLC
|
|
964
|
-
*
|
|
965
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
966
|
-
* you may not use this file except in compliance with the License.
|
|
967
|
-
* You may obtain a copy of the License at
|
|
968
|
-
*
|
|
969
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
970
|
-
*
|
|
971
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
972
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
973
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
974
|
-
* See the License for the specific language governing permissions and
|
|
975
|
-
* limitations under the License.
|
|
976
|
-
*/
|
|
977
|
-
function registerDataConnect(variant) {
|
|
978
|
-
setSDKVersion(SDK_VERSION$1);
|
|
979
|
-
_registerComponent(new Component('data-connect', (container, { instanceIdentifier: settings, options }) => {
|
|
980
|
-
const app = container.getProvider('app').getImmediate();
|
|
981
|
-
const authProvider = container.getProvider('auth-internal');
|
|
982
|
-
const appCheckProvider = container.getProvider('app-check-internal');
|
|
983
|
-
let newOpts = options;
|
|
984
|
-
if (settings) {
|
|
985
|
-
newOpts = JSON.parse(settings);
|
|
986
|
-
}
|
|
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);
|
|
991
|
-
}, "PUBLIC" /* ComponentType.PUBLIC */).setMultipleInstances(true));
|
|
992
|
-
registerVersion(name, version, variant);
|
|
993
|
-
// BUILD_TARGET will be replaced by values like esm5, esm2017, cjs5, etc during the compilation
|
|
994
|
-
registerVersion(name, version, 'esm2017');
|
|
961
|
+
/**
|
|
962
|
+
* @license
|
|
963
|
+
* Copyright 2024 Google LLC
|
|
964
|
+
*
|
|
965
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
966
|
+
* you may not use this file except in compliance with the License.
|
|
967
|
+
* You may obtain a copy of the License at
|
|
968
|
+
*
|
|
969
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
970
|
+
*
|
|
971
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
972
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
973
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
974
|
+
* See the License for the specific language governing permissions and
|
|
975
|
+
* limitations under the License.
|
|
976
|
+
*/
|
|
977
|
+
function registerDataConnect(variant) {
|
|
978
|
+
setSDKVersion(SDK_VERSION$1);
|
|
979
|
+
_registerComponent(new Component('data-connect', (container, { instanceIdentifier: settings, options }) => {
|
|
980
|
+
const app = container.getProvider('app').getImmediate();
|
|
981
|
+
const authProvider = container.getProvider('auth-internal');
|
|
982
|
+
const appCheckProvider = container.getProvider('app-check-internal');
|
|
983
|
+
let newOpts = options;
|
|
984
|
+
if (settings) {
|
|
985
|
+
newOpts = JSON.parse(settings);
|
|
986
|
+
}
|
|
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);
|
|
991
|
+
}, "PUBLIC" /* ComponentType.PUBLIC */).setMultipleInstances(true));
|
|
992
|
+
registerVersion(name, version, variant);
|
|
993
|
+
// BUILD_TARGET will be replaced by values like esm5, esm2017, cjs5, etc during the compilation
|
|
994
|
+
registerVersion(name, version, 'esm2017');
|
|
995
995
|
}
|
|
996
996
|
|
|
997
|
-
/**
|
|
998
|
-
* @license
|
|
999
|
-
* Copyright 2024 Google LLC
|
|
1000
|
-
*
|
|
1001
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
1002
|
-
* you may not use this file except in compliance with the License.
|
|
1003
|
-
* You may obtain a copy of the License at
|
|
1004
|
-
*
|
|
1005
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
1006
|
-
*
|
|
1007
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
1008
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
1009
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
1010
|
-
* See the License for the specific language governing permissions and
|
|
1011
|
-
* limitations under the License.
|
|
1012
|
-
*/
|
|
1013
|
-
/**
|
|
1014
|
-
* Execute Query
|
|
1015
|
-
* @param queryRef query to execute.
|
|
1016
|
-
* @returns `QueryPromise`
|
|
1017
|
-
*/
|
|
1018
|
-
function executeQuery(queryRef) {
|
|
1019
|
-
return queryRef.dataConnect._queryManager.executeQuery(queryRef);
|
|
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
|
-
*/
|
|
1029
|
-
function queryRef(dcInstance, queryName, variables, initialCache) {
|
|
1030
|
-
dcInstance.setInitialized();
|
|
1031
|
-
dcInstance._queryManager.track(queryName, variables, initialCache);
|
|
1032
|
-
return {
|
|
1033
|
-
dataConnect: dcInstance,
|
|
1034
|
-
refType: QUERY_STR,
|
|
1035
|
-
name: queryName,
|
|
1036
|
-
variables: variables
|
|
1037
|
-
};
|
|
1038
|
-
}
|
|
1039
|
-
/**
|
|
1040
|
-
* Converts serialized ref to query ref
|
|
1041
|
-
* @param serializedRef ref to convert to `QueryRef`
|
|
1042
|
-
* @returns `QueryRef`
|
|
1043
|
-
*/
|
|
1044
|
-
function toQueryRef(serializedRef) {
|
|
1045
|
-
const { refInfo: { name, variables, connectorConfig } } = serializedRef;
|
|
1046
|
-
return queryRef(getDataConnect(connectorConfig), name, variables);
|
|
997
|
+
/**
|
|
998
|
+
* @license
|
|
999
|
+
* Copyright 2024 Google LLC
|
|
1000
|
+
*
|
|
1001
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
1002
|
+
* you may not use this file except in compliance with the License.
|
|
1003
|
+
* You may obtain a copy of the License at
|
|
1004
|
+
*
|
|
1005
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
1006
|
+
*
|
|
1007
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
1008
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
1009
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
1010
|
+
* See the License for the specific language governing permissions and
|
|
1011
|
+
* limitations under the License.
|
|
1012
|
+
*/
|
|
1013
|
+
/**
|
|
1014
|
+
* Execute Query
|
|
1015
|
+
* @param queryRef query to execute.
|
|
1016
|
+
* @returns `QueryPromise`
|
|
1017
|
+
*/
|
|
1018
|
+
function executeQuery(queryRef) {
|
|
1019
|
+
return queryRef.dataConnect._queryManager.executeQuery(queryRef);
|
|
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
|
+
*/
|
|
1029
|
+
function queryRef(dcInstance, queryName, variables, initialCache) {
|
|
1030
|
+
dcInstance.setInitialized();
|
|
1031
|
+
dcInstance._queryManager.track(queryName, variables, initialCache);
|
|
1032
|
+
return {
|
|
1033
|
+
dataConnect: dcInstance,
|
|
1034
|
+
refType: QUERY_STR,
|
|
1035
|
+
name: queryName,
|
|
1036
|
+
variables: variables
|
|
1037
|
+
};
|
|
1038
|
+
}
|
|
1039
|
+
/**
|
|
1040
|
+
* Converts serialized ref to query ref
|
|
1041
|
+
* @param serializedRef ref to convert to `QueryRef`
|
|
1042
|
+
* @returns `QueryRef`
|
|
1043
|
+
*/
|
|
1044
|
+
function toQueryRef(serializedRef) {
|
|
1045
|
+
const { refInfo: { name, variables, connectorConfig } } = serializedRef;
|
|
1046
|
+
return queryRef(getDataConnect(connectorConfig), name, variables);
|
|
1047
1047
|
}
|
|
1048
1048
|
|
|
1049
|
-
/**
|
|
1050
|
-
* @license
|
|
1051
|
-
* Copyright 2024 Google LLC
|
|
1052
|
-
*
|
|
1053
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
1054
|
-
* you may not use this file except in compliance with the License.
|
|
1055
|
-
* You may obtain a copy of the License at
|
|
1056
|
-
*
|
|
1057
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
1058
|
-
*
|
|
1059
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
1060
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
1061
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
1062
|
-
* See the License for the specific language governing permissions and
|
|
1063
|
-
* limitations under the License.
|
|
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 };
|
|
1049
|
+
/**
|
|
1050
|
+
* @license
|
|
1051
|
+
* Copyright 2024 Google LLC
|
|
1052
|
+
*
|
|
1053
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
1054
|
+
* you may not use this file except in compliance with the License.
|
|
1055
|
+
* You may obtain a copy of the License at
|
|
1056
|
+
*
|
|
1057
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
1058
|
+
*
|
|
1059
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
1060
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
1061
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
1062
|
+
* See the License for the specific language governing permissions and
|
|
1063
|
+
* limitations under the License.
|
|
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
1090
|
}
|
|
1091
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
|
-
*/
|
|
1116
|
-
function subscribe(queryRefOrSerializedResult, observerOrOnNext, onError, onComplete) {
|
|
1117
|
-
let ref;
|
|
1118
|
-
let initialCache;
|
|
1119
|
-
if ('refInfo' in queryRefOrSerializedResult) {
|
|
1120
|
-
const serializedRef = queryRefOrSerializedResult;
|
|
1121
|
-
const { data, source, fetchTime } = serializedRef;
|
|
1122
|
-
initialCache = {
|
|
1123
|
-
data,
|
|
1124
|
-
source,
|
|
1125
|
-
fetchTime
|
|
1126
|
-
};
|
|
1127
|
-
ref = toQueryRef(serializedRef);
|
|
1128
|
-
}
|
|
1129
|
-
else {
|
|
1130
|
-
ref = queryRefOrSerializedResult;
|
|
1131
|
-
}
|
|
1132
|
-
let onResult = undefined;
|
|
1133
|
-
if (typeof observerOrOnNext === 'function') {
|
|
1134
|
-
onResult = observerOrOnNext;
|
|
1135
|
-
}
|
|
1136
|
-
else {
|
|
1137
|
-
onResult = observerOrOnNext.onNext;
|
|
1138
|
-
onError = observerOrOnNext.onErr;
|
|
1139
|
-
observerOrOnNext.onComplete;
|
|
1140
|
-
}
|
|
1141
|
-
if (!onResult) {
|
|
1142
|
-
throw new DataConnectError(Code.INVALID_ARGUMENT, 'Must provide onNext');
|
|
1143
|
-
}
|
|
1144
|
-
return ref.dataConnect._queryManager.addSubscription(ref, onResult, onError, initialCache);
|
|
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
|
+
*/
|
|
1116
|
+
function subscribe(queryRefOrSerializedResult, observerOrOnNext, onError, onComplete) {
|
|
1117
|
+
let ref;
|
|
1118
|
+
let initialCache;
|
|
1119
|
+
if ('refInfo' in queryRefOrSerializedResult) {
|
|
1120
|
+
const serializedRef = queryRefOrSerializedResult;
|
|
1121
|
+
const { data, source, fetchTime } = serializedRef;
|
|
1122
|
+
initialCache = {
|
|
1123
|
+
data,
|
|
1124
|
+
source,
|
|
1125
|
+
fetchTime
|
|
1126
|
+
};
|
|
1127
|
+
ref = toQueryRef(serializedRef);
|
|
1128
|
+
}
|
|
1129
|
+
else {
|
|
1130
|
+
ref = queryRefOrSerializedResult;
|
|
1131
|
+
}
|
|
1132
|
+
let onResult = undefined;
|
|
1133
|
+
if (typeof observerOrOnNext === 'function') {
|
|
1134
|
+
onResult = observerOrOnNext;
|
|
1135
|
+
}
|
|
1136
|
+
else {
|
|
1137
|
+
onResult = observerOrOnNext.onNext;
|
|
1138
|
+
onError = observerOrOnNext.onErr;
|
|
1139
|
+
observerOrOnNext.onComplete;
|
|
1140
|
+
}
|
|
1141
|
+
if (!onResult) {
|
|
1142
|
+
throw new DataConnectError(Code.INVALID_ARGUMENT, 'Must provide onNext');
|
|
1143
|
+
}
|
|
1144
|
+
return ref.dataConnect._queryManager.addSubscription(ref, onResult, onError, initialCache);
|
|
1145
1145
|
}
|
|
1146
1146
|
|
|
1147
|
-
/**
|
|
1148
|
-
* Firebase Data Connect
|
|
1149
|
-
*
|
|
1150
|
-
* @packageDocumentation
|
|
1151
|
-
*/
|
|
1147
|
+
/**
|
|
1148
|
+
* Firebase Data Connect
|
|
1149
|
+
*
|
|
1150
|
+
* @packageDocumentation
|
|
1151
|
+
*/
|
|
1152
1152
|
registerDataConnect();
|
|
1153
1153
|
|
|
1154
1154
|
export { DataConnect, MUTATION_STR, MutationManager, QUERY_STR, SOURCE_CACHE, SOURCE_SERVER, connectDataConnectEmulator, executeMutation, executeQuery, getDataConnect, mutationRef, parseOptions, queryRef, setLogLevel, subscribe, terminate, toQueryRef, validateArgs, validateDCOptions };
|