@fluidframework/routerlicious-driver 0.54.2 → 0.56.0-49831
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/.eslintrc.js +1 -1
- package/dist/documentServiceFactory.js +1 -1
- package/dist/documentServiceFactory.js.map +1 -1
- package/dist/errorUtils.js +3 -3
- package/dist/errorUtils.js.map +1 -1
- package/dist/nullBlobStorageService.d.ts +1 -1
- package/dist/nullBlobStorageService.d.ts.map +1 -1
- package/dist/nullBlobStorageService.js.map +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/policies.d.ts +1 -1
- package/dist/policies.js.map +1 -1
- package/dist/restWrapper.d.ts +3 -2
- package/dist/restWrapper.d.ts.map +1 -1
- package/dist/restWrapper.js +48 -36
- package/dist/restWrapper.js.map +1 -1
- package/dist/shreddedSummaryDocumentStorageService.d.ts +1 -1
- package/dist/shreddedSummaryDocumentStorageService.d.ts.map +1 -1
- package/dist/shreddedSummaryDocumentStorageService.js.map +1 -1
- package/lib/documentServiceFactory.js +1 -1
- package/lib/documentServiceFactory.js.map +1 -1
- package/lib/errorUtils.js +3 -3
- package/lib/errorUtils.js.map +1 -1
- package/lib/nullBlobStorageService.d.ts +1 -1
- package/lib/nullBlobStorageService.d.ts.map +1 -1
- package/lib/nullBlobStorageService.js.map +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/policies.d.ts +1 -1
- package/lib/policies.js.map +1 -1
- package/lib/restWrapper.d.ts +3 -2
- package/lib/restWrapper.d.ts.map +1 -1
- package/lib/restWrapper.js +46 -35
- package/lib/restWrapper.js.map +1 -1
- package/lib/shreddedSummaryDocumentStorageService.d.ts +1 -1
- package/lib/shreddedSummaryDocumentStorageService.d.ts.map +1 -1
- package/lib/shreddedSummaryDocumentStorageService.js.map +1 -1
- package/package.json +22 -17
- package/src/documentServiceFactory.ts +1 -1
- package/src/errorUtils.ts +3 -3
- package/src/nullBlobStorageService.ts +1 -1
- package/src/packageVersion.ts +1 -1
- package/src/policies.ts +1 -1
- package/src/restWrapper.ts +66 -41
- package/src/shreddedSummaryDocumentStorageService.ts +1 -1
package/src/restWrapper.ts
CHANGED
|
@@ -11,7 +11,12 @@ import {
|
|
|
11
11
|
RestLessClient,
|
|
12
12
|
RestWrapper,
|
|
13
13
|
} from "@fluidframework/server-services-client";
|
|
14
|
-
import
|
|
14
|
+
import {
|
|
15
|
+
default as nodeFetch,
|
|
16
|
+
RequestInfo as FetchRequestInfo,
|
|
17
|
+
RequestInit as FetchRequestInit,
|
|
18
|
+
} from "node-fetch";
|
|
19
|
+
import type { AxiosRequestConfig } from "axios";
|
|
15
20
|
import safeStringify from "json-stringify-safe";
|
|
16
21
|
import { v4 as uuid } from "uuid";
|
|
17
22
|
import { throwR11sNetworkError } from "./errorUtils";
|
|
@@ -19,12 +24,31 @@ import { ITokenProvider } from "./tokens";
|
|
|
19
24
|
|
|
20
25
|
type AuthorizationHeaderGetter = (refresh?: boolean) => Promise<string | undefined>;
|
|
21
26
|
|
|
27
|
+
// Borrowed from @fluidframework/odsp-driver's fetch.ts
|
|
28
|
+
// The only purpose of this helper is to work around the slight misalignments between the
|
|
29
|
+
// Browser's fetch API and the 'node-fetch' package by wrapping the call to the 'node-fetch' API
|
|
30
|
+
// in the browser's types from 'lib.dom.d.ts'.
|
|
31
|
+
export const fetch = async (request: RequestInfo, config?: RequestInit): Promise<Response> =>
|
|
32
|
+
nodeFetch(request as FetchRequestInfo, config as FetchRequestInit) as unknown as Response;
|
|
33
|
+
|
|
34
|
+
const axiosRequestConfigToFetchRequestConfig = (requestConfig: AxiosRequestConfig): [RequestInfo, RequestInit] => {
|
|
35
|
+
const requestInfo: string = requestConfig.baseURL !== undefined
|
|
36
|
+
? `${requestConfig.baseURL}${requestConfig.url ?? ""}`
|
|
37
|
+
: requestConfig.url ?? "";
|
|
38
|
+
const requestInit: RequestInit = {
|
|
39
|
+
method: requestConfig.method,
|
|
40
|
+
headers: requestConfig.headers,
|
|
41
|
+
body: requestConfig.data,
|
|
42
|
+
};
|
|
43
|
+
return [requestInfo, requestInit];
|
|
44
|
+
};
|
|
45
|
+
|
|
22
46
|
export class RouterliciousRestWrapper extends RestWrapper {
|
|
23
47
|
private authorizationHeader: string | undefined;
|
|
24
48
|
private readonly restLess = new RestLessClient();
|
|
25
49
|
|
|
26
50
|
constructor(
|
|
27
|
-
|
|
51
|
+
logger: ITelemetryLogger,
|
|
28
52
|
private readonly rateLimiter: RateLimiter,
|
|
29
53
|
private readonly getAuthorizationHeader: AuthorizationHeaderGetter,
|
|
30
54
|
private readonly useRestLess: boolean,
|
|
@@ -45,46 +69,47 @@ export class RouterliciousRestWrapper extends RestWrapper {
|
|
|
45
69
|
};
|
|
46
70
|
|
|
47
71
|
const translatedConfig = this.useRestLess ? this.restLess.translate(config) : config;
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
// Refresh Authorization header and retry once
|
|
72
|
-
this.authorizationHeader = await this.getAuthorizationHeader(true);
|
|
73
|
-
return this.request<T>(config, statusCode, false);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
if (axiosError.response?.status === 429 && axiosError.response.data?.retryAfter > 0) {
|
|
77
|
-
// Retry based on retryAfter[Seconds]
|
|
78
|
-
return new Promise<T>((resolve, reject) => setTimeout(() => {
|
|
79
|
-
this.request<T>(config, statusCode)
|
|
80
|
-
.then(resolve)
|
|
81
|
-
.catch(reject);
|
|
82
|
-
}, axiosError.response!.data.retryAfter * 1000));
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// Allow anything else to be handled upstream
|
|
86
|
-
throwR11sNetworkError("r11sAxiosError", axiosError.message, axiosError.response?.status);
|
|
72
|
+
const fetchRequestConfig = axiosRequestConfigToFetchRequestConfig(translatedConfig);
|
|
73
|
+
|
|
74
|
+
const response: Response = await this.rateLimiter.schedule(async () => fetch(...fetchRequestConfig)
|
|
75
|
+
.catch(async (error) => {
|
|
76
|
+
// Fetch throws a TypeError on network error
|
|
77
|
+
const isNetworkError = error instanceof TypeError;
|
|
78
|
+
throwR11sNetworkError(
|
|
79
|
+
"r11sFetchError",
|
|
80
|
+
isNetworkError ? `NetworkError: ${error.message}` : safeStringify(error));
|
|
81
|
+
}));
|
|
82
|
+
|
|
83
|
+
const responseBody: any = await response.clone().json().catch(async () => response.text());
|
|
84
|
+
|
|
85
|
+
// Success
|
|
86
|
+
if (response.ok || response.status === statusCode) {
|
|
87
|
+
const result: T = responseBody;
|
|
88
|
+
return result;
|
|
89
|
+
}
|
|
90
|
+
// Failure
|
|
91
|
+
if (response.status === 401 && canRetry) {
|
|
92
|
+
// Refresh Authorization header and retry once
|
|
93
|
+
this.authorizationHeader = await this.getAuthorizationHeader(true);
|
|
94
|
+
return this.request<T>(config, statusCode, false);
|
|
87
95
|
}
|
|
96
|
+
if (response.status === 429 && responseBody?.retryAfter > 0) {
|
|
97
|
+
// Retry based on retryAfter[Seconds]
|
|
98
|
+
return new Promise<T>((resolve, reject) => setTimeout(() => {
|
|
99
|
+
this.request<T>(config, statusCode)
|
|
100
|
+
.then(resolve)
|
|
101
|
+
.catch(reject);
|
|
102
|
+
}, responseBody.retryAfter * 1000));
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
throwR11sNetworkError(
|
|
106
|
+
"r11sFetchError",
|
|
107
|
+
responseBody !== undefined
|
|
108
|
+
? typeof responseBody === "string" ? responseBody : safeStringify(responseBody)
|
|
109
|
+
: response.statusText,
|
|
110
|
+
response.status,
|
|
111
|
+
responseBody?.retryAfter,
|
|
112
|
+
);
|
|
88
113
|
}
|
|
89
114
|
|
|
90
115
|
private generateHeaders(requestHeaders?: Record<string, unknown>): Record<string, unknown> {
|
|
@@ -72,7 +72,7 @@ export class ShreddedSummaryDocumentStorageService implements IDocumentStorageSe
|
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
public async getVersions(versionId: string, count: number): Promise<IVersion[]> {
|
|
75
|
+
public async getVersions(versionId: string | null, count: number): Promise<IVersion[]> {
|
|
76
76
|
const id = versionId ? versionId : this.id;
|
|
77
77
|
const commits = await PerformanceEvent.timedExecAsync(
|
|
78
78
|
this.logger,
|