@fluidframework/routerlicious-driver 2.1.0-276985 → 2.1.0
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/CHANGELOG.md +4 -0
- package/README.md +93 -2
- package/api-extractor/{api-extractor-lint-beta.cjs.json → api-extractor.current.json} +2 -2
- package/api-extractor/api-extractor.legacy.json +1 -1
- package/api-extractor.json +1 -1
- package/api-report/routerlicious-driver.legacy.public.api.md +22 -0
- package/dist/createNewUtils.d.ts.map +1 -1
- package/dist/createNewUtils.js +1 -3
- package/dist/createNewUtils.js.map +1 -1
- package/dist/deltaStorageService.js +1 -1
- package/dist/deltaStorageService.js.map +1 -1
- package/dist/documentService.d.ts.map +1 -1
- package/dist/documentService.js +5 -2
- package/dist/documentService.js.map +1 -1
- package/dist/documentServiceFactory.d.ts.map +1 -1
- package/dist/documentServiceFactory.js +6 -3
- package/dist/documentServiceFactory.js.map +1 -1
- package/dist/historian.d.ts.map +1 -1
- package/dist/historian.js.map +1 -1
- package/dist/legacy.d.ts +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.d.ts.map +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/public.d.ts +1 -1
- package/dist/queryStringUtils.d.ts +12 -0
- package/dist/queryStringUtils.d.ts.map +1 -0
- package/dist/queryStringUtils.js +25 -0
- package/dist/queryStringUtils.js.map +1 -0
- package/dist/r11sSnapshotParser.d.ts.map +1 -1
- package/dist/r11sSnapshotParser.js +4 -2
- package/dist/r11sSnapshotParser.js.map +1 -1
- package/dist/restWrapper.d.ts +9 -2
- package/dist/restWrapper.d.ts.map +1 -1
- package/dist/restWrapper.js +44 -13
- package/dist/restWrapper.js.map +1 -1
- package/dist/restWrapperBase.d.ts +27 -7
- package/dist/restWrapperBase.d.ts.map +1 -1
- package/dist/restWrapperBase.js +35 -27
- package/dist/restWrapperBase.js.map +1 -1
- package/dist/shreddedSummaryDocumentStorageService.d.ts.map +1 -1
- package/dist/shreddedSummaryDocumentStorageService.js +4 -3
- package/dist/shreddedSummaryDocumentStorageService.js.map +1 -1
- package/dist/summaryTreeUploadManager.d.ts.map +1 -1
- package/dist/summaryTreeUploadManager.js +3 -3
- package/dist/summaryTreeUploadManager.js.map +1 -1
- package/dist/urlUtils.d.ts.map +1 -1
- package/dist/urlUtils.js +2 -0
- package/dist/urlUtils.js.map +1 -1
- package/dist/wholeSummaryDocumentStorageService.d.ts.map +1 -1
- package/dist/wholeSummaryDocumentStorageService.js +4 -3
- package/dist/wholeSummaryDocumentStorageService.js.map +1 -1
- package/internal.d.ts +1 -1
- package/legacy.d.ts +1 -1
- package/lib/createNewUtils.d.ts.map +1 -1
- package/lib/createNewUtils.js +1 -3
- package/lib/createNewUtils.js.map +1 -1
- package/lib/deltaStorageService.js +1 -1
- package/lib/deltaStorageService.js.map +1 -1
- package/lib/documentService.d.ts.map +1 -1
- package/lib/documentService.js +5 -2
- package/lib/documentService.js.map +1 -1
- package/lib/documentServiceFactory.d.ts.map +1 -1
- package/lib/documentServiceFactory.js +6 -3
- package/lib/documentServiceFactory.js.map +1 -1
- package/lib/historian.d.ts.map +1 -1
- package/lib/historian.js.map +1 -1
- package/lib/legacy.d.ts +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.d.ts.map +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/public.d.ts +1 -1
- package/lib/queryStringUtils.d.ts +12 -0
- package/lib/queryStringUtils.d.ts.map +1 -0
- package/lib/queryStringUtils.js +21 -0
- package/lib/queryStringUtils.js.map +1 -0
- package/lib/r11sSnapshotParser.d.ts.map +1 -1
- package/lib/r11sSnapshotParser.js +4 -2
- package/lib/r11sSnapshotParser.js.map +1 -1
- package/lib/restWrapper.d.ts +9 -2
- package/lib/restWrapper.d.ts.map +1 -1
- package/lib/restWrapper.js +44 -12
- package/lib/restWrapper.js.map +1 -1
- package/lib/restWrapperBase.d.ts +27 -7
- package/lib/restWrapperBase.d.ts.map +1 -1
- package/lib/restWrapperBase.js +34 -25
- package/lib/restWrapperBase.js.map +1 -1
- package/lib/shreddedSummaryDocumentStorageService.d.ts.map +1 -1
- package/lib/shreddedSummaryDocumentStorageService.js +4 -3
- package/lib/shreddedSummaryDocumentStorageService.js.map +1 -1
- package/lib/summaryTreeUploadManager.d.ts.map +1 -1
- package/lib/summaryTreeUploadManager.js +3 -3
- package/lib/summaryTreeUploadManager.js.map +1 -1
- package/lib/urlUtils.d.ts.map +1 -1
- package/lib/urlUtils.js +2 -0
- package/lib/urlUtils.js.map +1 -1
- package/lib/wholeSummaryDocumentStorageService.d.ts.map +1 -1
- package/lib/wholeSummaryDocumentStorageService.js +4 -3
- package/lib/wholeSummaryDocumentStorageService.js.map +1 -1
- package/package.json +23 -33
- package/src/createNewUtils.ts +1 -4
- package/src/deltaStorageService.ts +1 -1
- package/src/documentService.ts +8 -5
- package/src/documentServiceFactory.ts +8 -5
- package/src/historian.ts +2 -1
- package/src/packageVersion.ts +1 -1
- package/src/queryStringUtils.ts +23 -0
- package/src/r11sSnapshotParser.ts +5 -3
- package/src/restWrapper.ts +78 -35
- package/src/restWrapperBase.ts +35 -32
- package/src/shreddedSummaryDocumentStorageService.ts +4 -3
- package/src/summaryTreeUploadManager.ts +4 -4
- package/src/urlUtils.ts +4 -2
- package/src/wholeSummaryDocumentStorageService.ts +4 -3
- package/tsconfig.json +0 -1
- package/api-extractor/api-extractor-lint-beta.esm.json +0 -5
- package/beta.d.ts +0 -11
- package/dist/beta.d.ts +0 -15
- package/lib/beta.d.ts +0 -15
package/src/restWrapper.ts
CHANGED
|
@@ -28,19 +28,19 @@ import safeStringify from "json-stringify-safe";
|
|
|
28
28
|
import type { AxiosRequestConfig, RawAxiosRequestHeaders } from "./axios.cjs";
|
|
29
29
|
import { RouterliciousErrorTypes, throwR11sNetworkError } from "./errorUtils.js";
|
|
30
30
|
import { pkgVersion as driverVersion } from "./packageVersion.js";
|
|
31
|
-
import {
|
|
31
|
+
import { addOrUpdateQueryParams, type QueryStringType } from "./queryStringUtils.js";
|
|
32
|
+
import { RestWrapper } from "./restWrapperBase.js";
|
|
32
33
|
import { ITokenProvider, ITokenResponse } from "./tokens.js";
|
|
33
34
|
|
|
34
35
|
type AuthorizationHeaderGetter = (token: ITokenResponse) => string;
|
|
35
36
|
export type TokenFetcher = (refresh?: boolean) => Promise<ITokenResponse>;
|
|
36
37
|
|
|
37
|
-
const
|
|
38
|
-
requestConfig
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
: requestConfig.url ?? "";
|
|
38
|
+
const buildRequestUrl = (requestConfig: AxiosRequestConfig) =>
|
|
39
|
+
requestConfig.baseURL !== undefined
|
|
40
|
+
? `${requestConfig.baseURL ?? ""}${requestConfig.url ?? ""}`
|
|
41
|
+
: requestConfig.url ?? "";
|
|
42
|
+
|
|
43
|
+
const axiosBuildRequestInitConfig = (requestConfig: AxiosRequestConfig): RequestInit => {
|
|
44
44
|
const requestInit: RequestInit = {
|
|
45
45
|
method: requestConfig.method,
|
|
46
46
|
// NOTE: I believe that although the Axios type permits non-string values in the header, here we are
|
|
@@ -48,7 +48,7 @@ const axiosRequestConfigToFetchRequestConfig = (
|
|
|
48
48
|
headers: requestConfig.headers as Record<string, string>,
|
|
49
49
|
body: requestConfig.data,
|
|
50
50
|
};
|
|
51
|
-
return
|
|
51
|
+
return requestInit;
|
|
52
52
|
};
|
|
53
53
|
|
|
54
54
|
export interface IR11sResponse<T> {
|
|
@@ -109,10 +109,17 @@ export function getPropsToLogFromResponse(headers: {
|
|
|
109
109
|
return additionalProps;
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
-
|
|
112
|
+
class RouterliciousRestWrapper extends RestWrapper {
|
|
113
113
|
private readonly restLess = new RestLessClient();
|
|
114
114
|
private token: ITokenResponse | undefined;
|
|
115
115
|
|
|
116
|
+
/**
|
|
117
|
+
* A locally maintained map which saves the number of retries for any REST api call made through restWrapper.
|
|
118
|
+
* It uses the href of the request url as a key against which it saves the retry counts. Retries are only counted in case of failures.
|
|
119
|
+
* This feature is added to enable FRS to have more telemetry insights into whether the requests are being retried from same client or multiple.
|
|
120
|
+
*/
|
|
121
|
+
private readonly retryCounter = new Map<string, number>();
|
|
122
|
+
|
|
116
123
|
constructor(
|
|
117
124
|
logger: ITelemetryLoggerExt,
|
|
118
125
|
private readonly rateLimiter: RateLimiter,
|
|
@@ -131,36 +138,64 @@ export class RouterliciousRestWrapper extends RestWrapper {
|
|
|
131
138
|
statusCode: number,
|
|
132
139
|
canRetry = true,
|
|
133
140
|
): Promise<IR11sResponse<T>> {
|
|
141
|
+
if (requestConfig.params) {
|
|
142
|
+
// delete the retry param, if any. We do this to ensure there is no retry added by any of callers, which would conflict with the one we maintain here in the retryCounter map.
|
|
143
|
+
delete requestConfig.params.retry;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Build the complete request url including baseUrl, url and query params. (all except 'retry' query param)
|
|
147
|
+
let completeRequestUrl = addOrUpdateQueryParams(
|
|
148
|
+
buildRequestUrl(requestConfig),
|
|
149
|
+
requestConfig.params,
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
// Check whether this request has been made before or if it is a retry.
|
|
153
|
+
// requestKey is built using the HTTP method appended with the complete URL ommitting the 'retry' param
|
|
154
|
+
const requestKey = `${requestConfig.method ?? ""}|${completeRequestUrl.href}`;
|
|
155
|
+
const requestRetryCount = this.retryCounter.get(requestKey);
|
|
156
|
+
if (requestRetryCount) {
|
|
157
|
+
completeRequestUrl = addOrUpdateQueryParams(completeRequestUrl, {
|
|
158
|
+
retry: requestRetryCount,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
|
|
134
162
|
const config = {
|
|
135
163
|
...requestConfig,
|
|
136
164
|
headers: await this.generateHeaders(requestConfig.headers),
|
|
137
165
|
};
|
|
138
166
|
|
|
139
167
|
const translatedConfig = this.useRestLess ? this.restLess.translate(config) : config;
|
|
140
|
-
const fetchRequestConfig =
|
|
168
|
+
const fetchRequestConfig = axiosBuildRequestInitConfig(translatedConfig);
|
|
141
169
|
|
|
142
170
|
const res = await this.rateLimiter.schedule(async () => {
|
|
143
171
|
const perfStart = performance.now();
|
|
144
|
-
const result = await fetch(
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
172
|
+
const result = await fetch(completeRequestUrl, fetchRequestConfig).catch(
|
|
173
|
+
async (error) => {
|
|
174
|
+
// on failure, add the request entry into the retryCounter map to count the subsequent retries, if any
|
|
175
|
+
this.retryCounter.set(requestKey, requestRetryCount ? requestRetryCount + 1 : 1);
|
|
176
|
+
|
|
177
|
+
// Browser Fetch throws a TypeError on network error, `node-fetch` throws a FetchError
|
|
178
|
+
const isNetworkError = ["TypeError", "FetchError"].includes(error?.name);
|
|
179
|
+
const errorMessage = isNetworkError
|
|
180
|
+
? `NetworkError: ${error.message}`
|
|
181
|
+
: safeStringify(error);
|
|
182
|
+
// If a service is temporarily down or a browser resource limit is reached, RestWrapper will throw
|
|
183
|
+
// a network error with no status code (e.g. err:ERR_CONN_REFUSED or err:ERR_FAILED) and
|
|
184
|
+
// the error message will start with NetworkError as defined in restWrapper.ts
|
|
185
|
+
// If there exists a self-signed SSL certificates error, throw a NonRetryableError
|
|
186
|
+
// TODO: instead of relying on string matching, filter error based on the error code like we do for websocket connections
|
|
187
|
+
const err = errorMessage.includes("failed, reason: self signed certificate")
|
|
188
|
+
? new NonRetryableError(errorMessage, RouterliciousErrorTypes.sslCertError, {
|
|
189
|
+
driverVersion,
|
|
190
|
+
retryCount: requestRetryCount,
|
|
191
|
+
})
|
|
192
|
+
: new GenericNetworkError(errorMessage, errorMessage.startsWith("NetworkError"), {
|
|
193
|
+
driverVersion,
|
|
194
|
+
retryCount: requestRetryCount,
|
|
195
|
+
});
|
|
196
|
+
throw err;
|
|
197
|
+
},
|
|
198
|
+
);
|
|
164
199
|
return {
|
|
165
200
|
response: result,
|
|
166
201
|
duration: performance.now() - perfStart,
|
|
@@ -184,13 +219,14 @@ export class RouterliciousRestWrapper extends RestWrapper {
|
|
|
184
219
|
|
|
185
220
|
// Success
|
|
186
221
|
if (response.ok || response.status === statusCode) {
|
|
222
|
+
// on successful response, remove the entry from the retryCounter map
|
|
223
|
+
this.retryCounter.delete(requestKey);
|
|
187
224
|
const result = responseBody as T;
|
|
188
225
|
const headers = headersToMap(response.headers);
|
|
189
226
|
return {
|
|
190
227
|
content: result,
|
|
191
228
|
headers,
|
|
192
|
-
|
|
193
|
-
requestUrl: fetchRequestConfig[0].toString(),
|
|
229
|
+
requestUrl: completeRequestUrl.href,
|
|
194
230
|
propsToLog: {
|
|
195
231
|
...getPropsToLogFromResponse(headers),
|
|
196
232
|
bodySize,
|
|
@@ -200,17 +236,24 @@ export class RouterliciousRestWrapper extends RestWrapper {
|
|
|
200
236
|
},
|
|
201
237
|
};
|
|
202
238
|
}
|
|
239
|
+
|
|
203
240
|
// Failure
|
|
241
|
+
// on failure, add the request entry into the retryCounter map to count the subsequent retries
|
|
242
|
+
this.retryCounter.set(requestKey, requestRetryCount ? requestRetryCount + 1 : 1);
|
|
243
|
+
|
|
204
244
|
if (response.status === 401 && canRetry) {
|
|
205
245
|
// Refresh Authorization header and retry once
|
|
206
246
|
this.token = await this.fetchRefreshedToken(true /* refreshToken */);
|
|
207
|
-
return this.request<T>(config, statusCode, false);
|
|
247
|
+
return this.request<T>({ ...config }, statusCode, false);
|
|
208
248
|
}
|
|
209
249
|
if (response.status === 429 && responseBody?.retryAfter > 0) {
|
|
210
250
|
// Retry based on retryAfter[Seconds]
|
|
211
251
|
return new Promise<IR11sResponse<T>>((resolve, reject) =>
|
|
212
252
|
setTimeout(() => {
|
|
213
|
-
|
|
253
|
+
// use the original request URL without the retryCount appended
|
|
254
|
+
this.request<T>({ ...config }, statusCode)
|
|
255
|
+
.then(resolve)
|
|
256
|
+
.catch(reject);
|
|
214
257
|
}, responseBody.retryAfter * 1000),
|
|
215
258
|
);
|
|
216
259
|
}
|
package/src/restWrapperBase.ts
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import type { AxiosRequestConfig, AxiosRequestHeaders } from "./axios.cjs";
|
|
7
|
+
import { type QueryStringType } from "./queryStringUtils.js";
|
|
7
8
|
import { IR11sResponse } from "./restWrapper.js";
|
|
8
9
|
|
|
9
10
|
export abstract class RestWrapper {
|
|
@@ -14,6 +15,12 @@ export abstract class RestWrapper {
|
|
|
14
15
|
protected readonly maxContentLength = 1000 * 1024 * 1024,
|
|
15
16
|
) {}
|
|
16
17
|
|
|
18
|
+
/**
|
|
19
|
+
* @param url - Relative or absolute request url.(should not contain any query params)
|
|
20
|
+
* @param queryString - query params to be appended to the request url
|
|
21
|
+
* @param headers - headers
|
|
22
|
+
* @param additionalOptions - additionalOptions
|
|
23
|
+
*/
|
|
17
24
|
public async get<T>(
|
|
18
25
|
url: string,
|
|
19
26
|
queryString?: QueryStringType,
|
|
@@ -32,11 +39,19 @@ export abstract class RestWrapper {
|
|
|
32
39
|
maxBodyLength: this.maxBodyLength,
|
|
33
40
|
maxContentLength: this.maxContentLength,
|
|
34
41
|
method: "GET",
|
|
35
|
-
url
|
|
42
|
+
url,
|
|
43
|
+
params: { ...this.defaultQueryString, ...queryString },
|
|
36
44
|
};
|
|
37
45
|
return this.request<T>(options, 200);
|
|
38
46
|
}
|
|
39
47
|
|
|
48
|
+
/**
|
|
49
|
+
* @param url - Relative or absolute request url.(should not contain any query params)
|
|
50
|
+
* @param requestBody - requestBody
|
|
51
|
+
* @param queryString - query params to be appended to the request url
|
|
52
|
+
* @param headers - headers
|
|
53
|
+
* @param additionalOptions - additionalOptions
|
|
54
|
+
*/
|
|
40
55
|
public async post<T>(
|
|
41
56
|
url: string,
|
|
42
57
|
requestBody: any,
|
|
@@ -57,11 +72,18 @@ export abstract class RestWrapper {
|
|
|
57
72
|
maxBodyLength: this.maxBodyLength,
|
|
58
73
|
maxContentLength: this.maxContentLength,
|
|
59
74
|
method: "POST",
|
|
60
|
-
url
|
|
75
|
+
url,
|
|
76
|
+
params: { ...this.defaultQueryString, ...queryString },
|
|
61
77
|
};
|
|
62
78
|
return this.request<T>(options, 201);
|
|
63
79
|
}
|
|
64
80
|
|
|
81
|
+
/**
|
|
82
|
+
* @param url - Relative or absolute request url.(should not contain any query params)
|
|
83
|
+
* @param queryString - query params to be appended to the request url
|
|
84
|
+
* @param headers - headers
|
|
85
|
+
* @param additionalOptions - additionalOptions
|
|
86
|
+
*/
|
|
65
87
|
public async delete<T>(
|
|
66
88
|
url: string,
|
|
67
89
|
queryString?: QueryStringType,
|
|
@@ -80,11 +102,19 @@ export abstract class RestWrapper {
|
|
|
80
102
|
maxBodyLength: this.maxBodyLength,
|
|
81
103
|
maxContentLength: this.maxContentLength,
|
|
82
104
|
method: "DELETE",
|
|
83
|
-
url
|
|
105
|
+
url,
|
|
106
|
+
params: { ...this.defaultQueryString, ...queryString },
|
|
84
107
|
};
|
|
85
108
|
return this.request<T>(options, 204);
|
|
86
109
|
}
|
|
87
110
|
|
|
111
|
+
/**
|
|
112
|
+
* @param url - Relative or absolute request url.(should not contain any query params)
|
|
113
|
+
* @param requestBody - requestBody
|
|
114
|
+
* @param queryString - query params to be appended to the request url
|
|
115
|
+
* @param headers - headers
|
|
116
|
+
* @param additionalOptions - additionalOptions
|
|
117
|
+
*/
|
|
88
118
|
public async patch<T>(
|
|
89
119
|
url: string,
|
|
90
120
|
requestBody: any,
|
|
@@ -105,7 +135,8 @@ export abstract class RestWrapper {
|
|
|
105
135
|
maxBodyLength: this.maxBodyLength,
|
|
106
136
|
maxContentLength: this.maxContentLength,
|
|
107
137
|
method: "PATCH",
|
|
108
|
-
url
|
|
138
|
+
url,
|
|
139
|
+
params: { ...this.defaultQueryString, ...queryString },
|
|
109
140
|
};
|
|
110
141
|
return this.request<T>(options, 200);
|
|
111
142
|
}
|
|
@@ -115,32 +146,4 @@ export abstract class RestWrapper {
|
|
|
115
146
|
statusCode: number,
|
|
116
147
|
addNetworkCallProps?: boolean,
|
|
117
148
|
): Promise<IR11sResponse<T>>;
|
|
118
|
-
|
|
119
|
-
protected generateQueryString(queryStringValues?: QueryStringType) {
|
|
120
|
-
if (this.defaultQueryString || queryStringValues) {
|
|
121
|
-
const queryStringMap = { ...this.defaultQueryString, ...queryStringValues };
|
|
122
|
-
|
|
123
|
-
return getQueryString(queryStringMap);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
return "";
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* Generates query string from the given query parameters.
|
|
132
|
-
* @param queryParams - Query parameters from which to create a query.
|
|
133
|
-
*/
|
|
134
|
-
export function getQueryString(queryParams: QueryStringType): string {
|
|
135
|
-
let queryString = "";
|
|
136
|
-
for (const key of Object.keys(queryParams)) {
|
|
137
|
-
if (queryParams[key] !== undefined) {
|
|
138
|
-
const startChar = queryString === "" ? "?" : "&";
|
|
139
|
-
queryString += `${startChar}${key}=${encodeURIComponent(queryParams[key])}`;
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
return queryString;
|
|
144
149
|
}
|
|
145
|
-
|
|
146
|
-
export type QueryStringType = Record<string, string | number | boolean>;
|
|
@@ -98,13 +98,14 @@ export class ShreddedSummaryDocumentStorageService implements IDocumentStorageSe
|
|
|
98
98
|
|
|
99
99
|
public async getSnapshotTree(version?: IVersion): Promise<ISnapshotTreeEx | null> {
|
|
100
100
|
let requestVersion = version;
|
|
101
|
-
if (
|
|
101
|
+
if (requestVersion === undefined) {
|
|
102
102
|
const versions = await this.getVersions(this.id, 1);
|
|
103
|
-
|
|
103
|
+
const firstVersion = versions[0];
|
|
104
|
+
if (firstVersion === undefined) {
|
|
104
105
|
return null;
|
|
105
106
|
}
|
|
106
107
|
|
|
107
|
-
requestVersion =
|
|
108
|
+
requestVersion = firstVersion;
|
|
108
109
|
}
|
|
109
110
|
|
|
110
111
|
const cachedSnapshotTree = await this.snapshotTreeCache?.get(
|
|
@@ -41,8 +41,7 @@ export class SummaryTreeUploadManager implements ISummaryUploadManager {
|
|
|
41
41
|
previousFullSnapshot: ISnapshotTreeEx | undefined,
|
|
42
42
|
): Promise<string> {
|
|
43
43
|
const entries = await Promise.all(
|
|
44
|
-
Object.
|
|
45
|
-
const entry = summaryTree.tree[key];
|
|
44
|
+
Object.entries(summaryTree.tree).map(async ([key, entry]) => {
|
|
46
45
|
const pathHandle = await this.writeSummaryTreeObject(entry, previousFullSnapshot);
|
|
47
46
|
const treeEntry: IGitCreateTreeEntry = {
|
|
48
47
|
mode: getGitMode(entry),
|
|
@@ -123,8 +122,8 @@ export class SummaryTreeUploadManager implements ISummaryUploadManager {
|
|
|
123
122
|
/** Previous snapshot, subtree relative to this path part */
|
|
124
123
|
previousSnapshot: ISnapshotTreeEx,
|
|
125
124
|
): string {
|
|
126
|
-
assert(path.length > 0, 0x0b3 /* "Expected at least 1 path part" */);
|
|
127
125
|
const key = path[0];
|
|
126
|
+
assert(path.length > 0 && key !== undefined, 0x0b3 /* "Expected at least 1 path part" */);
|
|
128
127
|
if (path.length === 1) {
|
|
129
128
|
switch (handleType) {
|
|
130
129
|
case SummaryType.Blob: {
|
|
@@ -147,6 +146,7 @@ export class SummaryTreeUploadManager implements ISummaryUploadManager {
|
|
|
147
146
|
throw Error(`Unexpected handle summary object type: "${handleType}".`);
|
|
148
147
|
}
|
|
149
148
|
}
|
|
150
|
-
|
|
149
|
+
// TODO why are we non null asserting here?
|
|
150
|
+
return this.getIdFromPathCore(handleType, path.slice(1), previousSnapshot.trees[key]!);
|
|
151
151
|
}
|
|
152
152
|
}
|
package/src/urlUtils.ts
CHANGED
|
@@ -20,11 +20,13 @@ export const getDiscoveredFluidResolvedUrl = (
|
|
|
20
20
|
session: ISession,
|
|
21
21
|
): IResolvedUrl => {
|
|
22
22
|
const discoveredOrdererUrl = new URL(session.ordererUrl);
|
|
23
|
-
|
|
23
|
+
// TODO why are we non null asserting here?
|
|
24
|
+
const deltaStorageUrl = new URL(resolvedUrl.endpoints.deltaStorageUrl!);
|
|
24
25
|
deltaStorageUrl.host = discoveredOrdererUrl.host;
|
|
25
26
|
|
|
26
27
|
const discoveredStorageUrl = new URL(session.historianUrl);
|
|
27
|
-
|
|
28
|
+
// TODO why are we non null asserting here?
|
|
29
|
+
const storageUrl = new URL(resolvedUrl.endpoints.storageUrl!);
|
|
28
30
|
storageUrl.host = discoveredStorageUrl.host;
|
|
29
31
|
|
|
30
32
|
const parsedUrl = new URL(resolvedUrl.url);
|
|
@@ -161,13 +161,14 @@ export class WholeSummaryDocumentStorageService implements IDocumentStorageServi
|
|
|
161
161
|
// eslint-disable-next-line @rushstack/no-new-null
|
|
162
162
|
public async getSnapshotTree(version?: IVersion): Promise<ISnapshotTree | null> {
|
|
163
163
|
let requestVersion = version;
|
|
164
|
-
if (
|
|
164
|
+
if (requestVersion === undefined) {
|
|
165
165
|
const versions = await this.getVersions(this.id, 1);
|
|
166
|
-
|
|
166
|
+
const firstVersion = versions[0];
|
|
167
|
+
if (firstVersion === undefined) {
|
|
167
168
|
return null;
|
|
168
169
|
}
|
|
169
170
|
|
|
170
|
-
requestVersion =
|
|
171
|
+
requestVersion = firstVersion;
|
|
171
172
|
}
|
|
172
173
|
|
|
173
174
|
let normalizedWholeSnapshot = await this.snapshotTreeCache.get(
|
package/tsconfig.json
CHANGED
package/beta.d.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
-
* Licensed under the MIT License.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
/*
|
|
7
|
-
* THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
|
8
|
-
* Generated by "flub generate entrypoints" in @fluidframework/build-tools.
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
export * from "./lib/beta.js";
|
package/dist/beta.d.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
-
* Licensed under the MIT License.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
/*
|
|
7
|
-
* THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
|
8
|
-
* Generated by "flub generate entrypoints" in @fluidframework/build-tools.
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
export {
|
|
12
|
-
// @public APIs
|
|
13
|
-
ITokenProvider,
|
|
14
|
-
ITokenResponse
|
|
15
|
-
} from "./index.js";
|
package/lib/beta.d.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
-
* Licensed under the MIT License.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
/*
|
|
7
|
-
* THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
|
8
|
-
* Generated by "flub generate entrypoints" in @fluidframework/build-tools.
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
export {
|
|
12
|
-
// @public APIs
|
|
13
|
-
ITokenProvider,
|
|
14
|
-
ITokenResponse
|
|
15
|
-
} from "./index.js";
|