@fluidframework/odsp-driver 2.3.0-288113 → 2.4.0-294316
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/dist/ReadBufferUtils.d.ts.map +1 -1
- package/dist/ReadBufferUtils.js +0 -1
- package/dist/ReadBufferUtils.js.map +1 -1
- package/dist/WriteBufferUtils.d.ts.map +1 -1
- package/dist/WriteBufferUtils.js +0 -2
- package/dist/WriteBufferUtils.js.map +1 -1
- package/dist/compactSnapshotParser.d.ts.map +1 -1
- package/dist/compactSnapshotParser.js +2 -18
- package/dist/compactSnapshotParser.js.map +1 -1
- package/dist/compactSnapshotWriter.d.ts.map +1 -1
- package/dist/compactSnapshotWriter.js +1 -3
- package/dist/compactSnapshotWriter.js.map +1 -1
- package/dist/createNewUtils.d.ts.map +1 -1
- package/dist/createNewUtils.js +0 -2
- package/dist/createNewUtils.js.map +1 -1
- package/dist/fetchSnapshot.d.ts.map +1 -1
- package/dist/fetchSnapshot.js +1 -2
- package/dist/fetchSnapshot.js.map +1 -1
- package/dist/getFileLink.d.ts +2 -2
- package/dist/getFileLink.d.ts.map +1 -1
- package/dist/getFileLink.js +54 -28
- package/dist/getFileLink.js.map +1 -1
- package/dist/localOdspDriver/localOdspDeltaStorageService.d.ts.map +1 -1
- package/dist/localOdspDriver/localOdspDeltaStorageService.js +0 -1
- package/dist/localOdspDriver/localOdspDeltaStorageService.js.map +1 -1
- package/dist/odspDelayLoadedDeltaStream.d.ts.map +1 -1
- package/dist/odspDelayLoadedDeltaStream.js +0 -2
- package/dist/odspDelayLoadedDeltaStream.js.map +1 -1
- package/dist/odspDeltaStorageService.d.ts.map +1 -1
- package/dist/odspDeltaStorageService.js +1 -4
- package/dist/odspDeltaStorageService.js.map +1 -1
- package/dist/odspDocumentDeltaConnection.d.ts.map +1 -1
- package/dist/odspDocumentDeltaConnection.js +1 -6
- package/dist/odspDocumentDeltaConnection.js.map +1 -1
- package/dist/odspDocumentStorageServiceBase.d.ts.map +1 -1
- package/dist/odspDocumentStorageServiceBase.js +0 -2
- package/dist/odspDocumentStorageServiceBase.js.map +1 -1
- package/dist/odspDriverUrlResolver.d.ts.map +1 -1
- package/dist/odspDriverUrlResolver.js +1 -2
- package/dist/odspDriverUrlResolver.js.map +1 -1
- package/dist/odspSnapshotParser.d.ts.map +1 -1
- package/dist/odspSnapshotParser.js +1 -5
- package/dist/odspSnapshotParser.js.map +1 -1
- package/dist/odspSummaryUploadManager.d.ts.map +1 -1
- package/dist/odspSummaryUploadManager.js +0 -1
- package/dist/odspSummaryUploadManager.js.map +1 -1
- package/dist/odspUrlHelper.d.ts.map +1 -1
- package/dist/odspUrlHelper.js +1 -5
- package/dist/odspUrlHelper.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/zipItDataRepresentationUtils.d.ts.map +1 -1
- package/dist/zipItDataRepresentationUtils.js +0 -9
- package/dist/zipItDataRepresentationUtils.js.map +1 -1
- package/lib/ReadBufferUtils.d.ts.map +1 -1
- package/lib/ReadBufferUtils.js +0 -1
- package/lib/ReadBufferUtils.js.map +1 -1
- package/lib/WriteBufferUtils.d.ts.map +1 -1
- package/lib/WriteBufferUtils.js +0 -2
- package/lib/WriteBufferUtils.js.map +1 -1
- package/lib/compactSnapshotParser.d.ts.map +1 -1
- package/lib/compactSnapshotParser.js +2 -18
- package/lib/compactSnapshotParser.js.map +1 -1
- package/lib/compactSnapshotWriter.d.ts.map +1 -1
- package/lib/compactSnapshotWriter.js +1 -3
- package/lib/compactSnapshotWriter.js.map +1 -1
- package/lib/createNewUtils.d.ts.map +1 -1
- package/lib/createNewUtils.js +0 -2
- package/lib/createNewUtils.js.map +1 -1
- package/lib/fetchSnapshot.d.ts.map +1 -1
- package/lib/fetchSnapshot.js +1 -2
- package/lib/fetchSnapshot.js.map +1 -1
- package/lib/getFileLink.d.ts +2 -2
- package/lib/getFileLink.d.ts.map +1 -1
- package/lib/getFileLink.js +48 -22
- package/lib/getFileLink.js.map +1 -1
- package/lib/localOdspDriver/localOdspDeltaStorageService.d.ts.map +1 -1
- package/lib/localOdspDriver/localOdspDeltaStorageService.js +0 -1
- package/lib/localOdspDriver/localOdspDeltaStorageService.js.map +1 -1
- package/lib/odspDelayLoadedDeltaStream.d.ts.map +1 -1
- package/lib/odspDelayLoadedDeltaStream.js +0 -2
- package/lib/odspDelayLoadedDeltaStream.js.map +1 -1
- package/lib/odspDeltaStorageService.d.ts.map +1 -1
- package/lib/odspDeltaStorageService.js +1 -4
- package/lib/odspDeltaStorageService.js.map +1 -1
- package/lib/odspDocumentDeltaConnection.d.ts.map +1 -1
- package/lib/odspDocumentDeltaConnection.js +1 -6
- package/lib/odspDocumentDeltaConnection.js.map +1 -1
- package/lib/odspDocumentStorageServiceBase.d.ts.map +1 -1
- package/lib/odspDocumentStorageServiceBase.js +0 -2
- package/lib/odspDocumentStorageServiceBase.js.map +1 -1
- package/lib/odspDriverUrlResolver.d.ts.map +1 -1
- package/lib/odspDriverUrlResolver.js +1 -2
- package/lib/odspDriverUrlResolver.js.map +1 -1
- package/lib/odspSnapshotParser.d.ts.map +1 -1
- package/lib/odspSnapshotParser.js +1 -5
- package/lib/odspSnapshotParser.js.map +1 -1
- package/lib/odspSummaryUploadManager.d.ts.map +1 -1
- package/lib/odspSummaryUploadManager.js +0 -1
- package/lib/odspSummaryUploadManager.js.map +1 -1
- package/lib/odspUrlHelper.d.ts.map +1 -1
- package/lib/odspUrlHelper.js +1 -5
- package/lib/odspUrlHelper.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/tsdoc-metadata.json +1 -1
- package/lib/zipItDataRepresentationUtils.d.ts.map +1 -1
- package/lib/zipItDataRepresentationUtils.js +0 -9
- package/lib/zipItDataRepresentationUtils.js.map +1 -1
- package/package.json +18 -17
- package/src/ReadBufferUtils.ts +1 -2
- package/src/WriteBufferUtils.ts +2 -4
- package/src/compactSnapshotParser.ts +14 -28
- package/src/compactSnapshotWriter.ts +2 -4
- package/src/createNewUtils.ts +2 -4
- package/src/fetchSnapshot.ts +1 -2
- package/src/getFileLink.ts +54 -22
- package/src/localOdspDriver/localOdspDeltaStorageService.ts +1 -2
- package/src/odspDelayLoadedDeltaStream.ts +2 -4
- package/src/odspDeltaStorageService.ts +2 -4
- package/src/odspDocumentDeltaConnection.ts +3 -8
- package/src/odspDocumentStorageServiceBase.ts +2 -4
- package/src/odspDriverUrlResolver.ts +1 -2
- package/src/odspSnapshotParser.ts +4 -8
- package/src/odspSummaryUploadManager.ts +1 -2
- package/src/odspUrlHelper.ts +4 -8
- package/src/packageVersion.ts +1 -1
- package/src/zipItDataRepresentationUtils.ts +9 -18
- package/tsconfig.json +1 -0
|
@@ -70,10 +70,8 @@ function readBlobSection(node: NodeTypes): {
|
|
|
70
70
|
*/
|
|
71
71
|
slowBlobStructureCount += 1;
|
|
72
72
|
const records = getNodeProps(blob);
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
// TODO why are we non null asserting here?
|
|
76
|
-
const id = getStringInstance(records.id!, "blob id should be string");
|
|
73
|
+
assertBlobCoreInstance(records.data, "data should be of BlobCore type");
|
|
74
|
+
const id = getStringInstance(records.id, "blob id should be string");
|
|
77
75
|
blobContents.set(id, records.data.arrayBuffer);
|
|
78
76
|
}
|
|
79
77
|
}
|
|
@@ -88,10 +86,8 @@ function readOpsSection(node: NodeTypes): ISequencedDocumentMessage[] {
|
|
|
88
86
|
assertNodeCoreInstance(node, "Deltas should be of type NodeCore");
|
|
89
87
|
const ops: ISequencedDocumentMessage[] = [];
|
|
90
88
|
const records = getNodeProps(node);
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
// TODO Why are we non null asserting here?
|
|
94
|
-
assertNodeCoreInstance(records.deltas!, "Deltas should be a Node");
|
|
89
|
+
assertNumberInstance(records.firstSequenceNumber, "Seq number should be a number");
|
|
90
|
+
assertNodeCoreInstance(records.deltas, "Deltas should be a Node");
|
|
95
91
|
for (let i = 0; i < records.deltas.length; ++i) {
|
|
96
92
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
97
93
|
ops.push(JSON.parse(records.deltas.getString(i)));
|
|
@@ -100,8 +96,7 @@ function readOpsSection(node: NodeTypes): ISequencedDocumentMessage[] {
|
|
|
100
96
|
// when there are no ops. So just make the code resilient to that bug. Service has also
|
|
101
97
|
// fixed that bug.
|
|
102
98
|
assert(
|
|
103
|
-
|
|
104
|
-
ops.length === 0 || records.firstSequenceNumber.valueOf() === ops[0]!.sequenceNumber,
|
|
99
|
+
ops.length === 0 || records.firstSequenceNumber.valueOf() === ops[0].sequenceNumber,
|
|
105
100
|
0x280 /* "Validate first op seq number" */,
|
|
106
101
|
);
|
|
107
102
|
return ops;
|
|
@@ -206,8 +201,7 @@ function readTreeSection(node: NodeCore): {
|
|
|
206
201
|
snapshotTree.unreferenced = true;
|
|
207
202
|
}
|
|
208
203
|
|
|
209
|
-
|
|
210
|
-
const path = getStringInstance(records.name!, "Path name should be string");
|
|
204
|
+
const path = getStringInstance(records.name, "Path name should be string");
|
|
211
205
|
if (records.value !== undefined) {
|
|
212
206
|
snapshotTree.blobs[path] = getStringInstance(
|
|
213
207
|
records.value,
|
|
@@ -220,8 +214,7 @@ function readTreeSection(node: NodeCore): {
|
|
|
220
214
|
trees[path] = result.snapshotTree;
|
|
221
215
|
if (records.groupId !== undefined) {
|
|
222
216
|
const groupId = getStringInstance(records.groupId, "groupId should be a string");
|
|
223
|
-
|
|
224
|
-
trees[path]!.groupId = groupId;
|
|
217
|
+
trees[path].groupId = groupId;
|
|
225
218
|
treeStructureCountWithGroupId++;
|
|
226
219
|
}
|
|
227
220
|
slowTreeStructureCount += result.slowTreeStructureCount;
|
|
@@ -246,14 +239,11 @@ function readSnapshotSection(node: NodeTypes): {
|
|
|
246
239
|
assertNodeCoreInstance(node, "Snapshot should be of type NodeCore");
|
|
247
240
|
const records = getNodeProps(node);
|
|
248
241
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
// TODO Why are we non null asserting here?
|
|
252
|
-
assertNumberInstance(records.sequenceNumber!, "sequenceNumber should be of type number");
|
|
242
|
+
assertNodeCoreInstance(records.treeNodes, "TreeNodes should be of type NodeCore");
|
|
243
|
+
assertNumberInstance(records.sequenceNumber, "sequenceNumber should be of type number");
|
|
253
244
|
const { snapshotTree, slowTreeStructureCount, treeStructureCountWithGroupId } =
|
|
254
245
|
readTreeSection(records.treeNodes);
|
|
255
|
-
|
|
256
|
-
snapshotTree.id = getStringInstance(records.id!, "snapshotId should be string");
|
|
246
|
+
snapshotTree.id = getStringInstance(records.id, "snapshotId should be string");
|
|
257
247
|
const sequenceNumber = records.sequenceNumber.valueOf();
|
|
258
248
|
return {
|
|
259
249
|
sequenceNumber,
|
|
@@ -279,10 +269,8 @@ export function parseCompactSnapshotResponse(
|
|
|
279
269
|
|
|
280
270
|
const records = getNodeProps(root);
|
|
281
271
|
|
|
282
|
-
|
|
283
|
-
const
|
|
284
|
-
// TODO Why are we non null asserting here?
|
|
285
|
-
const cv = getStringInstance(records.cv!, "createVersion should be string");
|
|
272
|
+
const mrv = getStringInstance(records.mrv, "minReadVersion should be string");
|
|
273
|
+
const cv = getStringInstance(records.cv, "createVersion should be string");
|
|
286
274
|
if (records.lsn !== undefined) {
|
|
287
275
|
assertNumberInstance(records.lsn, "lsn should be a number");
|
|
288
276
|
}
|
|
@@ -301,11 +289,9 @@ export function parseCompactSnapshotResponse(
|
|
|
301
289
|
);
|
|
302
290
|
|
|
303
291
|
const [snapshot, durationSnapshotTree] = measure(() =>
|
|
304
|
-
|
|
305
|
-
readSnapshotSection(records.snapshot!),
|
|
292
|
+
readSnapshotSection(records.snapshot),
|
|
306
293
|
);
|
|
307
|
-
|
|
308
|
-
const [blobContents, durationBlobs] = measure(() => readBlobSection(records.blobs!));
|
|
294
|
+
const [blobContents, durationBlobs] = measure(() => readBlobSection(records.blobs));
|
|
309
295
|
|
|
310
296
|
return {
|
|
311
297
|
...snapshot,
|
|
@@ -130,8 +130,7 @@ function writeSnapshotSection(
|
|
|
130
130
|
function writeOpsSection(rootNode: NodeCore, ops: ISequencedDocumentMessage[]): void {
|
|
131
131
|
let firstSequenceNumber: number | undefined;
|
|
132
132
|
if (ops.length > 0) {
|
|
133
|
-
|
|
134
|
-
firstSequenceNumber = ops[0]!.sequenceNumber;
|
|
133
|
+
firstSequenceNumber = ops[0].sequenceNumber;
|
|
135
134
|
}
|
|
136
135
|
if (firstSequenceNumber !== undefined) {
|
|
137
136
|
rootNode.addDictionaryString("deltas");
|
|
@@ -163,8 +162,7 @@ export function convertToCompactSnapshot(snapshotContents: ISnapshot): Uint8Arra
|
|
|
163
162
|
if (latestSequenceNumber === undefined) {
|
|
164
163
|
latestSequenceNumber =
|
|
165
164
|
snapshotContents.ops.length > 0
|
|
166
|
-
?
|
|
167
|
-
snapshotContents.ops[snapshotContents.ops.length - 1]!.sequenceNumber
|
|
165
|
+
? snapshotContents.ops[snapshotContents.ops.length - 1].sequenceNumber
|
|
168
166
|
: snapshotContents.sequenceNumber;
|
|
169
167
|
}
|
|
170
168
|
|
package/src/createNewUtils.ts
CHANGED
|
@@ -72,8 +72,7 @@ function convertCreateNewSummaryTreeToTreeAndBlobsCore(
|
|
|
72
72
|
};
|
|
73
73
|
const keys = Object.keys(summary.tree);
|
|
74
74
|
for (const key of keys) {
|
|
75
|
-
|
|
76
|
-
const summaryObject = summary.tree[key]!;
|
|
75
|
+
const summaryObject = summary.tree[key];
|
|
77
76
|
|
|
78
77
|
switch (summaryObject.type) {
|
|
79
78
|
case SummaryType.Tree: {
|
|
@@ -151,8 +150,7 @@ function convertSummaryToSnapshotTreeForCreateNew(summary: ISummaryTree): IOdspS
|
|
|
151
150
|
const keys = Object.keys(summary.tree);
|
|
152
151
|
for (const key of keys) {
|
|
153
152
|
assert(!key.includes("/"), 0x9cc /* id should not include slashes */);
|
|
154
|
-
|
|
155
|
-
const summaryObject = summary.tree[key]!;
|
|
153
|
+
const summaryObject = summary.tree[key];
|
|
156
154
|
|
|
157
155
|
let value: OdspSummaryTreeValue;
|
|
158
156
|
// Tracks if an entry is unreferenced. Currently, only tree entries can be marked as unreferenced. If the
|
package/src/fetchSnapshot.ts
CHANGED
|
@@ -505,8 +505,7 @@ async function fetchLatestSnapshotCore(
|
|
|
505
505
|
const sequenceNumber: number = snapshot.sequenceNumber ?? 0;
|
|
506
506
|
const seqNumberFromOps =
|
|
507
507
|
snapshot.ops && snapshot.ops.length > 0
|
|
508
|
-
?
|
|
509
|
-
snapshot.ops[0]!.sequenceNumber - 1
|
|
508
|
+
? snapshot.ops[0].sequenceNumber - 1
|
|
510
509
|
: undefined;
|
|
511
510
|
|
|
512
511
|
if (
|
package/src/getFileLink.ts
CHANGED
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
import type { ITelemetryBaseProperties } from "@fluidframework/core-interfaces";
|
|
7
7
|
import { assert } from "@fluidframework/core-utils/internal";
|
|
8
8
|
import { NonRetryableError, runWithRetry } from "@fluidframework/driver-utils/internal";
|
|
9
|
-
import { hasRedirectionLocation } from "@fluidframework/odsp-doclib-utils/internal";
|
|
10
9
|
import {
|
|
11
10
|
IOdspUrlParts,
|
|
12
11
|
OdspErrorTypes,
|
|
13
12
|
OdspResourceTokenFetchOptions,
|
|
14
13
|
TokenFetcher,
|
|
14
|
+
type IOdspResolvedUrl,
|
|
15
15
|
} from "@fluidframework/odsp-driver-definitions/internal";
|
|
16
16
|
import {
|
|
17
17
|
ITelemetryLoggerExt,
|
|
@@ -44,10 +44,10 @@ const fileLinkCache = new Map<string, Promise<string>>();
|
|
|
44
44
|
*/
|
|
45
45
|
export async function getFileLink(
|
|
46
46
|
getToken: TokenFetcher<OdspResourceTokenFetchOptions>,
|
|
47
|
-
|
|
47
|
+
resolvedUrl: IOdspResolvedUrl,
|
|
48
48
|
logger: ITelemetryLoggerExt,
|
|
49
49
|
): Promise<string> {
|
|
50
|
-
const cacheKey = `${
|
|
50
|
+
const cacheKey = `${resolvedUrl.siteUrl}_${resolvedUrl.driveId}_${resolvedUrl.itemId}`;
|
|
51
51
|
const maybeFileLinkCacheEntry = fileLinkCache.get(cacheKey);
|
|
52
52
|
if (maybeFileLinkCacheEntry !== undefined) {
|
|
53
53
|
return maybeFileLinkCacheEntry;
|
|
@@ -61,7 +61,7 @@ export async function getFileLink(
|
|
|
61
61
|
async () =>
|
|
62
62
|
runWithRetryForCoherencyAndServiceReadOnlyErrors(
|
|
63
63
|
async () =>
|
|
64
|
-
getFileLinkWithLocationRedirectionHandling(getToken,
|
|
64
|
+
getFileLinkWithLocationRedirectionHandling(getToken, resolvedUrl, logger),
|
|
65
65
|
"getFileLinkCore",
|
|
66
66
|
logger,
|
|
67
67
|
),
|
|
@@ -116,32 +116,41 @@ export async function getFileLink(
|
|
|
116
116
|
*/
|
|
117
117
|
async function getFileLinkWithLocationRedirectionHandling(
|
|
118
118
|
getToken: TokenFetcher<OdspResourceTokenFetchOptions>,
|
|
119
|
-
|
|
119
|
+
resolvedUrl: IOdspResolvedUrl,
|
|
120
120
|
logger: ITelemetryLoggerExt,
|
|
121
121
|
): Promise<string> {
|
|
122
122
|
// We can have chains of location redirection one after the other, so have a for loop
|
|
123
123
|
// so that we can keep handling the same type of error. Set max number of redirection to 5.
|
|
124
124
|
let lastError: unknown;
|
|
125
|
+
let locationRedirected = false;
|
|
125
126
|
for (let count = 1; count <= 5; count++) {
|
|
126
127
|
try {
|
|
127
|
-
|
|
128
|
+
const fileItem = await getFileItemLite(getToken, resolvedUrl, logger, true);
|
|
129
|
+
// Sometimes the siteUrl in the actual file is different from the siteUrl in the resolvedUrl due to location
|
|
130
|
+
// redirection. This creates issues in the getSharingInformation call. So we need to update the siteUrl in the
|
|
131
|
+
// resolvedUrl to the siteUrl in the fileItem which is the updated siteUrl.
|
|
132
|
+
const oldSiteDomain = new URL(resolvedUrl.siteUrl).origin;
|
|
133
|
+
const newSiteDomain = new URL(fileItem.sharepointIds.siteUrl).origin;
|
|
134
|
+
if (oldSiteDomain !== newSiteDomain) {
|
|
135
|
+
locationRedirected = true;
|
|
136
|
+
logger.sendTelemetryEvent({
|
|
137
|
+
eventName: "LocationRedirectionErrorForGetOdspFileLink",
|
|
138
|
+
retryCount: count,
|
|
139
|
+
});
|
|
140
|
+
renameTenantInOdspResolvedUrl(resolvedUrl, newSiteDomain);
|
|
141
|
+
}
|
|
142
|
+
return await getFileLinkCore(getToken, resolvedUrl, logger, fileItem);
|
|
128
143
|
} catch (error: unknown) {
|
|
129
144
|
lastError = error;
|
|
145
|
+
// If the getSharingLink call fails with the 401/403/404 error, then it could be due to that the file has moved
|
|
146
|
+
// to another location. This could occur in case we have more than 1 tenant rename. In that case, we should retry
|
|
147
|
+
// the getFileItemLite call to get the updated fileItem.
|
|
130
148
|
if (
|
|
131
149
|
isFluidError(error) &&
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
150
|
+
locationRedirected &&
|
|
151
|
+
(error.errorType === OdspErrorTypes.fileNotFoundOrAccessDeniedError ||
|
|
152
|
+
error.errorType === OdspErrorTypes.authorizationError)
|
|
135
153
|
) {
|
|
136
|
-
const redirectLocation = error.redirectLocation;
|
|
137
|
-
logger.sendTelemetryEvent({
|
|
138
|
-
eventName: "LocationRedirectionErrorForGetOdspFileLink",
|
|
139
|
-
retryCount: count,
|
|
140
|
-
});
|
|
141
|
-
// Generate the new SiteUrl from the redirection location.
|
|
142
|
-
const newSiteDomain = new URL(redirectLocation).origin;
|
|
143
|
-
const newSiteUrl = `${newSiteDomain}${new URL(odspUrlParts.siteUrl).pathname}`;
|
|
144
|
-
odspUrlParts.siteUrl = newSiteUrl;
|
|
145
154
|
continue;
|
|
146
155
|
}
|
|
147
156
|
throw error;
|
|
@@ -154,9 +163,8 @@ async function getFileLinkCore(
|
|
|
154
163
|
getToken: TokenFetcher<OdspResourceTokenFetchOptions>,
|
|
155
164
|
odspUrlParts: IOdspUrlParts,
|
|
156
165
|
logger: ITelemetryLoggerExt,
|
|
166
|
+
fileItem: FileItemLite,
|
|
157
167
|
): Promise<string> {
|
|
158
|
-
const fileItem = await getFileItemLite(getToken, odspUrlParts, logger, true);
|
|
159
|
-
|
|
160
168
|
// ODSP link requires extra call to return link that is resistant to file being renamed or moved to different folder
|
|
161
169
|
return PerformanceEvent.timedExecAsync(
|
|
162
170
|
logger,
|
|
@@ -194,7 +202,6 @@ async function getFileLinkCore(
|
|
|
194
202
|
headers: {
|
|
195
203
|
"Content-Type": "application/json;odata=verbose",
|
|
196
204
|
"Accept": "application/json;odata=verbose",
|
|
197
|
-
"redirect": "manual",
|
|
198
205
|
...headers,
|
|
199
206
|
},
|
|
200
207
|
};
|
|
@@ -281,7 +288,6 @@ async function getFileItemLite(
|
|
|
281
288
|
);
|
|
282
289
|
|
|
283
290
|
const headers = getHeadersWithAuth(authHeader);
|
|
284
|
-
headers.redirect = "manual";
|
|
285
291
|
const requestInit = { method, headers };
|
|
286
292
|
const response = await fetchHelper(url, requestInit);
|
|
287
293
|
additionalProps = response.propsToLog;
|
|
@@ -302,3 +308,29 @@ async function getFileItemLite(
|
|
|
302
308
|
},
|
|
303
309
|
);
|
|
304
310
|
}
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* It takes a resolved url with old siteUrl and patches resolved url with updated site url domain.
|
|
314
|
+
* @param odspResolvedUrl - Previous odsp resolved url with older site url.
|
|
315
|
+
* @param newSiteDomain - New site domain after the tenant rename.
|
|
316
|
+
*/
|
|
317
|
+
function renameTenantInOdspResolvedUrl(
|
|
318
|
+
odspResolvedUrl: IOdspResolvedUrl,
|
|
319
|
+
newSiteDomain: string,
|
|
320
|
+
): void {
|
|
321
|
+
const newSiteUrl = `${newSiteDomain}${new URL(odspResolvedUrl.siteUrl).pathname}`;
|
|
322
|
+
odspResolvedUrl.siteUrl = newSiteUrl;
|
|
323
|
+
|
|
324
|
+
if (odspResolvedUrl.endpoints.attachmentGETStorageUrl) {
|
|
325
|
+
odspResolvedUrl.endpoints.attachmentGETStorageUrl = `${newSiteDomain}${new URL(odspResolvedUrl.endpoints.attachmentGETStorageUrl).pathname}`;
|
|
326
|
+
}
|
|
327
|
+
if (odspResolvedUrl.endpoints.attachmentPOSTStorageUrl) {
|
|
328
|
+
odspResolvedUrl.endpoints.attachmentPOSTStorageUrl = `${newSiteDomain}${new URL(odspResolvedUrl.endpoints.attachmentPOSTStorageUrl).pathname}`;
|
|
329
|
+
}
|
|
330
|
+
if (odspResolvedUrl.endpoints.deltaStorageUrl) {
|
|
331
|
+
odspResolvedUrl.endpoints.deltaStorageUrl = `${newSiteDomain}${new URL(odspResolvedUrl.endpoints.deltaStorageUrl).pathname}`;
|
|
332
|
+
}
|
|
333
|
+
if (odspResolvedUrl.endpoints.snapshotStorageUrl) {
|
|
334
|
+
odspResolvedUrl.endpoints.snapshotStorageUrl = `${newSiteDomain}${new URL(odspResolvedUrl.endpoints.snapshotStorageUrl).pathname}`;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
@@ -38,8 +38,7 @@ export class LocalOdspDeltaStorageService implements IDocumentDeltaStorageServic
|
|
|
38
38
|
);
|
|
39
39
|
validateMessages("cached", messages, from, this.logger);
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
if (messages.length === 0 || messages[0]!.sequenceNumber !== from) {
|
|
41
|
+
if (messages.length === 0 || messages[0].sequenceNumber !== from) {
|
|
43
42
|
this.snapshotOps = [];
|
|
44
43
|
}
|
|
45
44
|
this.snapshotOps = this.snapshotOps.filter(
|
|
@@ -472,8 +472,7 @@ export class OdspDelayLoadedDeltaStream {
|
|
|
472
472
|
}
|
|
473
473
|
|
|
474
474
|
private emitMetaDataUpdateEvent(metadata: Record<string, string>): void {
|
|
475
|
-
|
|
476
|
-
const label = JSON.parse(metadata.sensitivityLabelsInfo!) as {
|
|
475
|
+
const label = JSON.parse(metadata.sensitivityLabelsInfo) as {
|
|
477
476
|
labels: unknown;
|
|
478
477
|
timestamp: number;
|
|
479
478
|
};
|
|
@@ -482,8 +481,7 @@ export class OdspDelayLoadedDeltaStream {
|
|
|
482
481
|
if (time > this.labelUpdateTimestamp) {
|
|
483
482
|
this.labelUpdateTimestamp = time;
|
|
484
483
|
this.metadataUpdateHandler({
|
|
485
|
-
|
|
486
|
-
sensitivityLabelsInfo: metadata.sensitivityLabelsInfo!,
|
|
484
|
+
sensitivityLabelsInfo: metadata.sensitivityLabelsInfo,
|
|
487
485
|
});
|
|
488
486
|
}
|
|
489
487
|
}
|
|
@@ -106,8 +106,7 @@ export class OdspDeltaStorageService {
|
|
|
106
106
|
clearTimeout(timer);
|
|
107
107
|
const deltaStorageResponse = response.content;
|
|
108
108
|
const messages =
|
|
109
|
-
|
|
110
|
-
deltaStorageResponse.value.length > 0 && "op" in deltaStorageResponse.value[0]!
|
|
109
|
+
deltaStorageResponse.value.length > 0 && "op" in deltaStorageResponse.value[0]
|
|
111
110
|
? (deltaStorageResponse.value as ISequencedDeltaOpMessage[]).map(
|
|
112
111
|
(operation) => operation.op,
|
|
113
112
|
)
|
|
@@ -188,8 +187,7 @@ export class OdspDeltaStorageWithCache implements IDocumentDeltaStorageService {
|
|
|
188
187
|
(op) => op.sequenceNumber >= from && op.sequenceNumber < to,
|
|
189
188
|
);
|
|
190
189
|
validateMessages("cached", messages, from, this.logger);
|
|
191
|
-
|
|
192
|
-
if (messages.length > 0 && messages[0]!.sequenceNumber === from) {
|
|
190
|
+
if (messages.length > 0 && messages[0].sequenceNumber === from) {
|
|
193
191
|
this.snapshotOps = this.snapshotOps.filter((op) => op.sequenceNumber >= to);
|
|
194
192
|
opsFromSnapshot += messages.length;
|
|
195
193
|
return { messages, partialResult: true };
|
|
@@ -36,7 +36,6 @@ import { SocketIOClientStatic } from "./socketModule.js";
|
|
|
36
36
|
const protocolVersions = ["^0.4.0", "^0.3.0", "^0.2.0", "^0.1.0"];
|
|
37
37
|
const feature_get_ops = "api_get_ops";
|
|
38
38
|
const feature_flush_ops = "api_flush_ops";
|
|
39
|
-
const feature_submit_signals_v2 = "submit_signals_v2";
|
|
40
39
|
|
|
41
40
|
export interface FlushResult {
|
|
42
41
|
lastPersistedSequenceNumber?: number;
|
|
@@ -296,9 +295,7 @@ export class OdspDocumentDeltaConnection extends DocumentDeltaConnection {
|
|
|
296
295
|
relayUserAgent: [client.details.environment, ` driverVersion:${pkgVersion}`].join(";"),
|
|
297
296
|
};
|
|
298
297
|
|
|
299
|
-
connectMessage.supportedFeatures = {
|
|
300
|
-
[feature_submit_signals_v2]: true,
|
|
301
|
-
};
|
|
298
|
+
connectMessage.supportedFeatures = {};
|
|
302
299
|
|
|
303
300
|
// Reference to this client supporting get_ops flow.
|
|
304
301
|
if (mc.config.getBoolean("Fluid.Driver.Odsp.GetOpsEnabled") !== false) {
|
|
@@ -591,10 +588,8 @@ export class OdspDocumentDeltaConnection extends DocumentDeltaConnection {
|
|
|
591
588
|
if (messages !== undefined && messages.length > 0) {
|
|
592
589
|
this.logger.sendPerformanceEvent({
|
|
593
590
|
...common,
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
// Non null asserting here because of the length check above
|
|
597
|
-
last: messages[messages.length - 1]!.sequenceNumber,
|
|
591
|
+
first: messages[0].sequenceNumber,
|
|
592
|
+
last: messages[messages.length - 1].sequenceNumber,
|
|
598
593
|
length: messages.length,
|
|
599
594
|
});
|
|
600
595
|
this.emit("op", this.documentId, messages);
|
|
@@ -198,8 +198,7 @@ export abstract class OdspDocumentStorageServiceBase implements IDocumentStorage
|
|
|
198
198
|
// eslint-disable-next-line unicorn/no-null
|
|
199
199
|
return null;
|
|
200
200
|
}
|
|
201
|
-
|
|
202
|
-
id = versions[0]!.id;
|
|
201
|
+
id = versions[0].id;
|
|
203
202
|
}
|
|
204
203
|
|
|
205
204
|
const snapshotTree = await this.readTree(id, scenarioName);
|
|
@@ -258,8 +257,7 @@ export abstract class OdspDocumentStorageServiceBase implements IDocumentStorage
|
|
|
258
257
|
protected combineProtocolAndAppSnapshotTree(snapshotTree: ISnapshotTree): ISnapshotTree {
|
|
259
258
|
// When we upload the container snapshot, we upload appTree in ".app" and protocol tree in ".protocol"
|
|
260
259
|
// So when we request the snapshot we get ".app" as tree and not as commit node as in the case just above.
|
|
261
|
-
|
|
262
|
-
const hierarchicalAppTree = snapshotTree.trees[".app"]!;
|
|
260
|
+
const hierarchicalAppTree = snapshotTree.trees[".app"];
|
|
263
261
|
const hierarchicalProtocolTree = snapshotTree.trees[".protocol"];
|
|
264
262
|
const summarySnapshotTree: ISnapshotTree = {
|
|
265
263
|
blobs: {
|
|
@@ -262,8 +262,7 @@ export function decodeOdspUrl(url: string): {
|
|
|
262
262
|
}
|
|
263
263
|
|
|
264
264
|
return {
|
|
265
|
-
|
|
266
|
-
siteUrl: siteUrl!,
|
|
265
|
+
siteUrl,
|
|
267
266
|
driveId: decodeURIComponent(driveId),
|
|
268
267
|
itemId: decodeURIComponent(itemId),
|
|
269
268
|
path: decodeURIComponent(path),
|
|
@@ -28,8 +28,7 @@ function buildHierarchy(flatTree: IOdspSnapshotCommit): ISnapshotTree {
|
|
|
28
28
|
const entryPathBase = entry.path.slice(lastIndex + 1);
|
|
29
29
|
|
|
30
30
|
// ODSP snapshots are created breadth-first so we can assume we see tree nodes prior to their contents
|
|
31
|
-
|
|
32
|
-
const node = lookup[entryPathDir]!;
|
|
31
|
+
const node = lookup[entryPathDir];
|
|
33
32
|
|
|
34
33
|
// Add in either the blob or tree
|
|
35
34
|
if (entry.type === "tree") {
|
|
@@ -70,19 +69,16 @@ export function convertOdspSnapshotToSnapshotTreeAndBlobs(
|
|
|
70
69
|
}
|
|
71
70
|
}
|
|
72
71
|
|
|
73
|
-
|
|
74
|
-
const sequenceNumber = odspSnapshot?.trees[0]!.sequenceNumber;
|
|
72
|
+
const sequenceNumber = odspSnapshot?.trees[0].sequenceNumber;
|
|
75
73
|
|
|
76
74
|
const val: ISnapshot = {
|
|
77
75
|
blobContents: blobsWithBufferContent,
|
|
78
76
|
ops: odspSnapshot.ops?.map((op) => op.op) ?? [],
|
|
79
77
|
sequenceNumber,
|
|
80
|
-
|
|
81
|
-
snapshotTree: buildHierarchy(odspSnapshot.trees[0]!),
|
|
78
|
+
snapshotTree: buildHierarchy(odspSnapshot.trees[0]),
|
|
82
79
|
latestSequenceNumber:
|
|
83
80
|
odspSnapshot.ops && odspSnapshot.ops.length > 0
|
|
84
|
-
?
|
|
85
|
-
odspSnapshot.ops[odspSnapshot.ops.length - 1]!.sequenceNumber
|
|
81
|
+
? odspSnapshot.ops[odspSnapshot.ops.length - 1].sequenceNumber
|
|
86
82
|
: sequenceNumber,
|
|
87
83
|
snapshotFormatV: 1,
|
|
88
84
|
};
|
|
@@ -180,8 +180,7 @@ export class OdspSummaryUploadManager {
|
|
|
180
180
|
const keys = Object.keys(tree.tree);
|
|
181
181
|
for (const key of keys) {
|
|
182
182
|
assert(!key.includes("/"), 0x9cd /* id should not include slashes */);
|
|
183
|
-
|
|
184
|
-
const summaryObject = tree.tree[key]!;
|
|
183
|
+
const summaryObject = tree.tree[key];
|
|
185
184
|
|
|
186
185
|
let id: string | undefined;
|
|
187
186
|
let value: OdspSummaryTreeValue | undefined;
|
package/src/odspUrlHelper.ts
CHANGED
|
@@ -110,10 +110,8 @@ export async function getOdspUrlParts(url: URL): Promise<IOdspUrlParts | undefin
|
|
|
110
110
|
}
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
|
|
114
|
-
const
|
|
115
|
-
// TODO Why are we non null asserting here?
|
|
116
|
-
const itemId = joinSessionMatch[4]!;
|
|
113
|
+
const driveId = joinSessionMatch[3] || joinSessionMatch[5];
|
|
114
|
+
const itemId = joinSessionMatch[4];
|
|
117
115
|
|
|
118
116
|
return { siteUrl: `${url.origin}${url.pathname}`, driveId, itemId };
|
|
119
117
|
} else {
|
|
@@ -122,10 +120,8 @@ export async function getOdspUrlParts(url: URL): Promise<IOdspUrlParts | undefin
|
|
|
122
120
|
if (joinSessionMatch === null) {
|
|
123
121
|
return undefined;
|
|
124
122
|
}
|
|
125
|
-
|
|
126
|
-
const
|
|
127
|
-
// TODO Why are we non null asserting here?
|
|
128
|
-
const itemId = joinSessionMatch[3]!;
|
|
123
|
+
const driveId = joinSessionMatch[2];
|
|
124
|
+
const itemId = joinSessionMatch[3];
|
|
129
125
|
|
|
130
126
|
return { siteUrl: `${url.origin}${url.pathname}`, driveId, itemId };
|
|
131
127
|
}
|
package/src/packageVersion.ts
CHANGED
|
@@ -301,46 +301,39 @@ export class NodeCore {
|
|
|
301
301
|
}
|
|
302
302
|
|
|
303
303
|
public get(index: number): NodeTypes {
|
|
304
|
-
|
|
305
|
-
return this.children[index]!;
|
|
304
|
+
return this.children[index];
|
|
306
305
|
}
|
|
307
306
|
|
|
308
307
|
public getString(index: number): string {
|
|
309
|
-
|
|
310
|
-
const node = this.children[index]!;
|
|
308
|
+
const node = this.children[index];
|
|
311
309
|
return getStringInstance(node, "getString should return string");
|
|
312
310
|
}
|
|
313
311
|
|
|
314
312
|
public getMaybeString(index: number): string | undefined {
|
|
315
|
-
|
|
316
|
-
const node = this.children[index]!;
|
|
313
|
+
const node = this.children[index];
|
|
317
314
|
return getMaybeStringInstance(node);
|
|
318
315
|
}
|
|
319
316
|
|
|
320
317
|
public getBlob(index: number): BlobCore {
|
|
321
|
-
|
|
322
|
-
const node = this.children[index]!;
|
|
318
|
+
const node = this.children[index];
|
|
323
319
|
assertBlobCoreInstance(node, "getBlob should return a blob");
|
|
324
320
|
return node;
|
|
325
321
|
}
|
|
326
322
|
|
|
327
323
|
public getNode(index: number): NodeCore {
|
|
328
|
-
|
|
329
|
-
const node = this.children[index]!;
|
|
324
|
+
const node = this.children[index];
|
|
330
325
|
assertNodeCoreInstance(node, "getNode should return a node");
|
|
331
326
|
return node;
|
|
332
327
|
}
|
|
333
328
|
|
|
334
329
|
public getNumber(index: number): number {
|
|
335
|
-
|
|
336
|
-
const node = this.children[index]!;
|
|
330
|
+
const node = this.children[index];
|
|
337
331
|
assertNumberInstance(node, "getNumber should return a number");
|
|
338
332
|
return node;
|
|
339
333
|
}
|
|
340
334
|
|
|
341
335
|
public getBool(index: number): boolean {
|
|
342
|
-
|
|
343
|
-
const node = this.children[index]!;
|
|
336
|
+
const node = this.children[index];
|
|
344
337
|
assertBoolInstance(node, "getBool should return a boolean");
|
|
345
338
|
return node;
|
|
346
339
|
}
|
|
@@ -556,8 +549,7 @@ export class NodeCore {
|
|
|
556
549
|
|
|
557
550
|
for (const el of stringsToResolve) {
|
|
558
551
|
for (let it = el.startPos; it < el.endPos; it++) {
|
|
559
|
-
|
|
560
|
-
stringBuffer[length] = input[it]!;
|
|
552
|
+
stringBuffer[length] = input[it];
|
|
561
553
|
length++;
|
|
562
554
|
}
|
|
563
555
|
stringBuffer[length] = 0;
|
|
@@ -569,8 +561,7 @@ export class NodeCore {
|
|
|
569
561
|
if (result.length === stringsToResolve.length + 1) {
|
|
570
562
|
// All is good, we expect all the cases to get here
|
|
571
563
|
for (let i = 0; i < stringsToResolve.length; i++) {
|
|
572
|
-
|
|
573
|
-
stringsToResolve[i]!.content = result[i];
|
|
564
|
+
stringsToResolve[i].content = result[i];
|
|
574
565
|
}
|
|
575
566
|
} else {
|
|
576
567
|
// String content has \0 chars!
|