@fluidframework/odsp-driver 2.0.0-internal.1.0.0.83139 → 2.0.0-internal.1.1.1
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/.mocharc.js +12 -0
- package/README.md +19 -0
- package/dist/contracts.d.ts +1 -0
- package/dist/contracts.d.ts.map +1 -1
- package/dist/contracts.js.map +1 -1
- package/dist/createFile.d.ts +1 -1
- package/dist/createFile.d.ts.map +1 -1
- package/dist/createFile.js +53 -16
- package/dist/createFile.js.map +1 -1
- package/dist/createOdspCreateContainerRequest.d.ts +4 -3
- package/dist/createOdspCreateContainerRequest.d.ts.map +1 -1
- package/dist/createOdspCreateContainerRequest.js +6 -3
- package/dist/createOdspCreateContainerRequest.js.map +1 -1
- package/dist/fetchSnapshot.d.ts +1 -2
- package/dist/fetchSnapshot.d.ts.map +1 -1
- package/dist/fetchSnapshot.js +14 -16
- package/dist/fetchSnapshot.js.map +1 -1
- package/dist/odspDeltaStorageService.d.ts +1 -1
- package/dist/odspDeltaStorageService.js +1 -1
- package/dist/odspDeltaStorageService.js.map +1 -1
- package/dist/odspDocumentService.d.ts.map +1 -1
- package/dist/odspDocumentService.js +2 -2
- package/dist/odspDocumentService.js.map +1 -1
- package/dist/odspDocumentServiceFactoryCore.d.ts.map +1 -1
- package/dist/odspDocumentServiceFactoryCore.js +29 -6
- package/dist/odspDocumentServiceFactoryCore.js.map +1 -1
- package/dist/odspDocumentStorageManager.d.ts +1 -2
- package/dist/odspDocumentStorageManager.d.ts.map +1 -1
- package/dist/odspDocumentStorageManager.js +22 -11
- package/dist/odspDocumentStorageManager.js.map +1 -1
- package/dist/odspDocumentStorageServiceBase.d.ts +1 -1
- package/dist/odspDocumentStorageServiceBase.d.ts.map +1 -1
- package/dist/odspDocumentStorageServiceBase.js +4 -2
- package/dist/odspDocumentStorageServiceBase.js.map +1 -1
- package/dist/odspUtils.d.ts +11 -2
- package/dist/odspUtils.d.ts.map +1 -1
- package/dist/odspUtils.js +21 -1
- package/dist/odspUtils.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/lib/contracts.d.ts +1 -0
- package/lib/contracts.d.ts.map +1 -1
- package/lib/contracts.js.map +1 -1
- package/lib/createFile.d.ts +1 -1
- package/lib/createFile.d.ts.map +1 -1
- package/lib/createFile.js +54 -17
- package/lib/createFile.js.map +1 -1
- package/lib/createOdspCreateContainerRequest.d.ts +4 -3
- package/lib/createOdspCreateContainerRequest.d.ts.map +1 -1
- package/lib/createOdspCreateContainerRequest.js +6 -3
- package/lib/createOdspCreateContainerRequest.js.map +1 -1
- package/lib/fetchSnapshot.d.ts +1 -2
- package/lib/fetchSnapshot.d.ts.map +1 -1
- package/lib/fetchSnapshot.js +14 -16
- package/lib/fetchSnapshot.js.map +1 -1
- package/lib/odspDeltaStorageService.d.ts +1 -1
- package/lib/odspDeltaStorageService.js +1 -1
- package/lib/odspDeltaStorageService.js.map +1 -1
- package/lib/odspDocumentService.d.ts.map +1 -1
- package/lib/odspDocumentService.js +2 -2
- package/lib/odspDocumentService.js.map +1 -1
- package/lib/odspDocumentServiceFactoryCore.d.ts.map +1 -1
- package/lib/odspDocumentServiceFactoryCore.js +29 -6
- package/lib/odspDocumentServiceFactoryCore.js.map +1 -1
- package/lib/odspDocumentStorageManager.d.ts +1 -2
- package/lib/odspDocumentStorageManager.d.ts.map +1 -1
- package/lib/odspDocumentStorageManager.js +22 -11
- package/lib/odspDocumentStorageManager.js.map +1 -1
- package/lib/odspDocumentStorageServiceBase.d.ts +1 -1
- package/lib/odspDocumentStorageServiceBase.d.ts.map +1 -1
- package/lib/odspDocumentStorageServiceBase.js +4 -2
- package/lib/odspDocumentStorageServiceBase.js.map +1 -1
- package/lib/odspUtils.d.ts +11 -2
- package/lib/odspUtils.d.ts.map +1 -1
- package/lib/odspUtils.js +19 -0
- package/lib/odspUtils.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/package.json +15 -15
- package/src/contracts.ts +2 -0
- package/src/createFile.ts +75 -15
- package/src/createOdspCreateContainerRequest.ts +7 -4
- package/src/fetchSnapshot.ts +12 -17
- package/src/odspDeltaStorageService.ts +1 -1
- package/src/odspDocumentService.ts +1 -2
- package/src/odspDocumentServiceFactoryCore.ts +40 -4
- package/src/odspDocumentStorageManager.ts +19 -13
- package/src/odspDocumentStorageServiceBase.ts +4 -2
- package/src/odspUtils.ts +24 -1
- package/src/packageVersion.ts +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluidframework/odsp-driver",
|
|
3
|
-
"version": "2.0.0-internal.1.
|
|
3
|
+
"version": "2.0.0-internal.1.1.1",
|
|
4
4
|
"description": "Socket storage implementation for SPO and ODC",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
6
|
"repository": {
|
|
@@ -61,17 +61,17 @@
|
|
|
61
61
|
},
|
|
62
62
|
"dependencies": {
|
|
63
63
|
"@fluidframework/common-definitions": "^0.20.1",
|
|
64
|
-
"@fluidframework/common-utils": "^0.
|
|
65
|
-
"@fluidframework/core-interfaces": "2.0.0-internal.1.
|
|
66
|
-
"@fluidframework/driver-base": "2.0.0-internal.1.
|
|
67
|
-
"@fluidframework/driver-definitions": "2.0.0-internal.1.
|
|
68
|
-
"@fluidframework/driver-utils": "2.0.0-internal.1.
|
|
69
|
-
"@fluidframework/gitresources": "^0.1037.1000
|
|
70
|
-
"@fluidframework/odsp-doclib-utils": "2.0.0-internal.1.
|
|
71
|
-
"@fluidframework/odsp-driver-definitions": "2.0.0-internal.1.
|
|
72
|
-
"@fluidframework/protocol-base": "^0.1037.1000
|
|
73
|
-
"@fluidframework/protocol-definitions": "^0.
|
|
74
|
-
"@fluidframework/telemetry-utils": "2.0.0-internal.1.
|
|
64
|
+
"@fluidframework/common-utils": "^1.0.0",
|
|
65
|
+
"@fluidframework/core-interfaces": "^2.0.0-internal.1.1.1",
|
|
66
|
+
"@fluidframework/driver-base": "^2.0.0-internal.1.1.1",
|
|
67
|
+
"@fluidframework/driver-definitions": "^2.0.0-internal.1.1.1",
|
|
68
|
+
"@fluidframework/driver-utils": "^2.0.0-internal.1.1.1",
|
|
69
|
+
"@fluidframework/gitresources": "^0.1037.1000",
|
|
70
|
+
"@fluidframework/odsp-doclib-utils": "^2.0.0-internal.1.1.1",
|
|
71
|
+
"@fluidframework/odsp-driver-definitions": "^2.0.0-internal.1.1.1",
|
|
72
|
+
"@fluidframework/protocol-base": "^0.1037.1000",
|
|
73
|
+
"@fluidframework/protocol-definitions": "^1.0.0",
|
|
74
|
+
"@fluidframework/telemetry-utils": "^2.0.0-internal.1.1.1",
|
|
75
75
|
"abort-controller": "^3.0.0",
|
|
76
76
|
"node-fetch": "^2.6.1",
|
|
77
77
|
"socket.io-client": "^4.4.1",
|
|
@@ -79,9 +79,9 @@
|
|
|
79
79
|
},
|
|
80
80
|
"devDependencies": {
|
|
81
81
|
"@fluidframework/build-common": "^0.24.0",
|
|
82
|
-
"@fluidframework/build-tools": "^0.3.
|
|
82
|
+
"@fluidframework/build-tools": "^0.3.1000",
|
|
83
83
|
"@fluidframework/eslint-config-fluid": "^0.28.2000",
|
|
84
|
-
"@fluidframework/mocha-test-setup": "2.0.0-internal.1.
|
|
84
|
+
"@fluidframework/mocha-test-setup": "^2.0.0-internal.1.1.1",
|
|
85
85
|
"@fluidframework/odsp-driver-previous": "npm:@fluidframework/odsp-driver@^1.0.0",
|
|
86
86
|
"@microsoft/api-extractor": "^7.22.2",
|
|
87
87
|
"@rushstack/eslint-config": "^2.5.1",
|
|
@@ -89,7 +89,7 @@
|
|
|
89
89
|
"@types/node-fetch": "^2.5.10",
|
|
90
90
|
"@types/sha.js": "^2.4.0",
|
|
91
91
|
"concurrently": "^6.2.0",
|
|
92
|
-
"copyfiles": "^2.1
|
|
92
|
+
"copyfiles": "^2.4.1",
|
|
93
93
|
"cross-env": "^7.0.2",
|
|
94
94
|
"eslint": "~8.6.0",
|
|
95
95
|
"mocha": "^10.0.0",
|
package/src/contracts.ts
CHANGED
|
@@ -216,6 +216,8 @@ export interface ICreateFileResponse {
|
|
|
216
216
|
itemId: string;
|
|
217
217
|
itemUrl: string;
|
|
218
218
|
sequenceNumber: number;
|
|
219
|
+
// sharing object contains shareId, sharingLink data or error in the response
|
|
220
|
+
sharing?: any;
|
|
219
221
|
sharingLink?: string;
|
|
220
222
|
sharingLinkErrorReason?: string;
|
|
221
223
|
}
|
package/src/createFile.ts
CHANGED
|
@@ -15,6 +15,9 @@ import {
|
|
|
15
15
|
InstrumentedStorageTokenFetcher,
|
|
16
16
|
IOdspResolvedUrl,
|
|
17
17
|
OdspErrorType,
|
|
18
|
+
ShareLinkInfoType,
|
|
19
|
+
ISharingLinkKind,
|
|
20
|
+
ShareLinkTypes,
|
|
18
21
|
} from "@fluidframework/odsp-driver-definitions";
|
|
19
22
|
import { DriverErrorType } from "@fluidframework/driver-definitions";
|
|
20
23
|
import {
|
|
@@ -26,6 +29,7 @@ import {
|
|
|
26
29
|
} from "./contracts";
|
|
27
30
|
import { getUrlAndHeadersWithAuth } from "./getUrlAndHeadersWithAuth";
|
|
28
31
|
import {
|
|
32
|
+
buildOdspShareLinkReqParams,
|
|
29
33
|
createCacheSnapshotKey,
|
|
30
34
|
getWithRetryForTokenRefresh,
|
|
31
35
|
INewFileInfo,
|
|
@@ -61,6 +65,8 @@ export async function createNewFluidFile(
|
|
|
61
65
|
createNewCaching: boolean,
|
|
62
66
|
forceAccessTokenViaAuthorizationHeader: boolean,
|
|
63
67
|
isClpCompliantApp?: boolean,
|
|
68
|
+
enableSingleRequestForShareLinkWithCreate?: boolean,
|
|
69
|
+
enableShareLinkWithCreate?: boolean,
|
|
64
70
|
): Promise<IOdspResolvedUrl> {
|
|
65
71
|
// Check for valid filename before the request to create file is actually made.
|
|
66
72
|
if (isInvalidFileName(newFileInfo.filename)) {
|
|
@@ -71,8 +77,7 @@ export async function createNewFluidFile(
|
|
|
71
77
|
|
|
72
78
|
let itemId: string;
|
|
73
79
|
let summaryHandle: string = "";
|
|
74
|
-
let
|
|
75
|
-
let sharingLinkErrorReason: string | undefined;
|
|
80
|
+
let shareLinkInfo: ShareLinkInfoType | undefined;
|
|
76
81
|
if (createNewSummary === undefined) {
|
|
77
82
|
itemId = await createNewEmptyFluidFile(
|
|
78
83
|
getStorageToken, newFileInfo, logger, epochTracker, forceAccessTokenViaAuthorizationHeader);
|
|
@@ -87,8 +92,12 @@ export async function createNewFluidFile(
|
|
|
87
92
|
);
|
|
88
93
|
itemId = content.itemId;
|
|
89
94
|
summaryHandle = content.id;
|
|
90
|
-
|
|
91
|
-
|
|
95
|
+
|
|
96
|
+
shareLinkInfo = extractShareLinkData(
|
|
97
|
+
newFileInfo.createLinkType,
|
|
98
|
+
content,
|
|
99
|
+
enableSingleRequestForShareLinkWithCreate,
|
|
100
|
+
enableShareLinkWithCreate);
|
|
92
101
|
}
|
|
93
102
|
|
|
94
103
|
const odspUrl = createOdspUrl({ ...newFileInfo, itemId, dataStorePath: "/" });
|
|
@@ -100,15 +109,7 @@ export async function createNewFluidFile(
|
|
|
100
109
|
fileEntry.docId = odspResolvedUrl.hashedDocumentId;
|
|
101
110
|
fileEntry.resolvedUrl = odspResolvedUrl;
|
|
102
111
|
|
|
103
|
-
|
|
104
|
-
odspResolvedUrl.shareLinkInfo = {
|
|
105
|
-
createLink: {
|
|
106
|
-
type: newFileInfo.createLinkType,
|
|
107
|
-
link: sharingLink,
|
|
108
|
-
error: sharingLinkErrorReason,
|
|
109
|
-
},
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
+
odspResolvedUrl.shareLinkInfo = shareLinkInfo;
|
|
112
113
|
|
|
113
114
|
if (createNewSummary !== undefined && createNewCaching) {
|
|
114
115
|
assert(summaryHandle !== undefined, 0x203 /* "Summary handle is undefined" */);
|
|
@@ -120,6 +121,61 @@ export async function createNewFluidFile(
|
|
|
120
121
|
return odspResolvedUrl;
|
|
121
122
|
}
|
|
122
123
|
|
|
124
|
+
/**
|
|
125
|
+
* If user requested creation of a sharing link along with the creation of the file by providing either
|
|
126
|
+
* createLinkType (now deprecated) or createLinkScope in the request parameters, extract and save
|
|
127
|
+
* sharing link information from the response if it is available.
|
|
128
|
+
* In case there was an error in creation of the sharing link, error is provided back in the response,
|
|
129
|
+
* and does not impact the creation of file in ODSP.
|
|
130
|
+
* @param requestedSharingLinkKind - Kind of sharing link requested to be created along with the creation of file.
|
|
131
|
+
* @param response - Response object received from the /snapshot api call
|
|
132
|
+
* @returns Sharing link information received in the response from a successful creation of a file.
|
|
133
|
+
*/
|
|
134
|
+
function extractShareLinkData(
|
|
135
|
+
requestedSharingLinkKind: ShareLinkTypes | ISharingLinkKind | undefined,
|
|
136
|
+
response: ICreateFileResponse,
|
|
137
|
+
enableSingleRequestForShareLinkWithCreate?: boolean,
|
|
138
|
+
enableShareLinkWithCreate?: boolean,
|
|
139
|
+
): ShareLinkInfoType | undefined {
|
|
140
|
+
if (!requestedSharingLinkKind) {
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
let shareLinkInfo: ShareLinkInfoType | undefined;
|
|
144
|
+
if (enableSingleRequestForShareLinkWithCreate) {
|
|
145
|
+
const { sharing } = response;
|
|
146
|
+
if (!sharing) {
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
shareLinkInfo = {
|
|
150
|
+
createLink: {
|
|
151
|
+
type: requestedSharingLinkKind,
|
|
152
|
+
link: sharing.sharingLink ? {
|
|
153
|
+
scope: sharing.sharingLink.scope,
|
|
154
|
+
role: sharing.sharingLink.type,
|
|
155
|
+
webUrl: sharing.sharingLink.webUrl,
|
|
156
|
+
...sharing.sharingLink,
|
|
157
|
+
} : undefined,
|
|
158
|
+
error: sharing.error,
|
|
159
|
+
shareId: sharing.shareId,
|
|
160
|
+
},
|
|
161
|
+
};
|
|
162
|
+
} else if (enableShareLinkWithCreate) {
|
|
163
|
+
const { sharing, sharingLink, sharingLinkErrorReason } = response;
|
|
164
|
+
if (!sharingLink && !sharingLinkErrorReason) {
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
shareLinkInfo = {
|
|
168
|
+
createLink: {
|
|
169
|
+
type: requestedSharingLinkKind,
|
|
170
|
+
link: sharingLink,
|
|
171
|
+
error: sharingLinkErrorReason,
|
|
172
|
+
shareId: sharing?.shareId,
|
|
173
|
+
},
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
return shareLinkInfo;
|
|
177
|
+
}
|
|
178
|
+
|
|
123
179
|
export async function createNewEmptyFluidFile(
|
|
124
180
|
getStorageToken: InstrumentedStorageTokenFetcher,
|
|
125
181
|
newFileInfo: INewFileInfo,
|
|
@@ -192,8 +248,12 @@ export async function createNewFluidFileFromSummary(
|
|
|
192
248
|
`${filePath}/${encodedFilename}`;
|
|
193
249
|
|
|
194
250
|
const containerSnapshot = convertSummaryIntoContainerSnapshot(createNewSummary);
|
|
195
|
-
|
|
196
|
-
|
|
251
|
+
|
|
252
|
+
// Build share link parameter based on the createLinkType provided so that the
|
|
253
|
+
// snapshot api can create and return the share link along with creation of file in the response.
|
|
254
|
+
const createShareLinkParam = buildOdspShareLinkReqParams(newFileInfo.createLinkType);
|
|
255
|
+
const initialUrl =
|
|
256
|
+
`${baseUrl}:/opStream/snapshots/snapshot${createShareLinkParam ? `?${createShareLinkParam}` : ""}`;
|
|
197
257
|
|
|
198
258
|
return getWithRetryForTokenRefresh(async (options) => {
|
|
199
259
|
const storageToken = await getStorageToken(options, "CreateNewFile");
|
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { IRequest } from "@fluidframework/core-interfaces";
|
|
6
6
|
import { DriverHeader } from "@fluidframework/driver-definitions";
|
|
7
|
-
import { ShareLinkTypes } from "@fluidframework/odsp-driver-definitions";
|
|
7
|
+
import { ShareLinkTypes, ISharingLinkKind } from "@fluidframework/odsp-driver-definitions";
|
|
8
|
+
import { buildOdspShareLinkReqParams } from "./odspUtils";
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* Create the request object with url and headers for creating a new file on OneDrive Sharepoint
|
|
@@ -12,19 +13,21 @@ import { ShareLinkTypes } from "@fluidframework/odsp-driver-definitions";
|
|
|
12
13
|
* @param driveId - drive identifier
|
|
13
14
|
* @param filePath - path where file needs to be created
|
|
14
15
|
* @param fileName - name of the new file to be created
|
|
15
|
-
* @param
|
|
16
|
+
* @param createShareLinkType - type of sharing link you would like to create for this file. ShareLinkTypes
|
|
17
|
+
* will be deprecated soon, so for any new implementation please provide createShareLinkType of type ShareLink
|
|
16
18
|
*/
|
|
17
19
|
export function createOdspCreateContainerRequest(
|
|
18
20
|
siteUrl: string,
|
|
19
21
|
driveId: string,
|
|
20
22
|
filePath: string,
|
|
21
23
|
fileName: string,
|
|
22
|
-
|
|
24
|
+
createShareLinkType?: ShareLinkTypes | ISharingLinkKind,
|
|
23
25
|
): IRequest {
|
|
26
|
+
const shareLinkRequestParams = buildOdspShareLinkReqParams(createShareLinkType);
|
|
24
27
|
const createNewRequest: IRequest = {
|
|
25
28
|
url: `${siteUrl}?driveId=${encodeURIComponent(
|
|
26
29
|
driveId,
|
|
27
|
-
)}&path=${encodeURIComponent(filePath)}${
|
|
30
|
+
)}&path=${encodeURIComponent(filePath)}${shareLinkRequestParams ? `&${shareLinkRequestParams}` : ""}`,
|
|
28
31
|
headers: {
|
|
29
32
|
[DriverHeader.createNew]: {
|
|
30
33
|
fileName,
|
package/src/fetchSnapshot.ts
CHANGED
|
@@ -49,7 +49,6 @@ export enum SnapshotFormatSupportType {
|
|
|
49
49
|
* @param token - token used for authorization in the request
|
|
50
50
|
* @param storageFetchWrapper - Implementation of the get/post methods used to fetch the snapshot
|
|
51
51
|
* @param versionId - id of specific snapshot to be fetched
|
|
52
|
-
* @param fetchFullSnapshot - whether we want to fetch full snapshot(with blobs)
|
|
53
52
|
* @param forceAccessTokenViaAuthorizationHeader - whether to force passing given token via authorization header
|
|
54
53
|
* @returns A promise of the snapshot and the status code of the response
|
|
55
54
|
*/
|
|
@@ -57,22 +56,14 @@ export async function fetchSnapshot(
|
|
|
57
56
|
snapshotUrl: string,
|
|
58
57
|
token: string | null,
|
|
59
58
|
versionId: string,
|
|
60
|
-
fetchFullSnapshot: boolean,
|
|
61
59
|
forceAccessTokenViaAuthorizationHeader: boolean,
|
|
62
60
|
logger: ITelemetryLogger,
|
|
63
61
|
snapshotDownloader: (url: string, fetchOptions: { [index: string]: any; }) => Promise<IOdspResponse<unknown>>,
|
|
64
62
|
): Promise<ISnapshotContents> {
|
|
65
63
|
const path = `/trees/${versionId}`;
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
if (versionId !== "latest") {
|
|
70
|
-
queryParams = { channels: 1, blobs: 2 };
|
|
71
|
-
} else {
|
|
72
|
-
queryParams = { deltas: 1, channels: 1, blobs: 2 };
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
64
|
+
// We just want to fetch tree here. So explicitly set to not fetch blobs and deltas
|
|
65
|
+
// as by default server will send that.
|
|
66
|
+
const queryParams: ISnapshotOptions = { deltas: 0, blobs: 0 };
|
|
76
67
|
const queryString = getQueryString(queryParams);
|
|
77
68
|
const { url, headers } = getUrlAndHeadersWithAuth(
|
|
78
69
|
`${snapshotUrl}${path}${queryString}`, token, forceAccessTokenViaAuthorizationHeader);
|
|
@@ -252,9 +243,15 @@ async function fetchLatestSnapshotCore(
|
|
|
252
243
|
});
|
|
253
244
|
|
|
254
245
|
let parsedSnapshotContents: IOdspResponse<ISnapshotContents> | undefined;
|
|
246
|
+
let contentTypeToRead: string | undefined;
|
|
247
|
+
if (contentType?.indexOf("application/ms-fluid") !== -1) {
|
|
248
|
+
contentTypeToRead = "application/ms-fluid";
|
|
249
|
+
} else if (contentType?.indexOf("application/json") !== -1) {
|
|
250
|
+
contentTypeToRead = "application/json";
|
|
251
|
+
}
|
|
255
252
|
|
|
256
253
|
try {
|
|
257
|
-
switch (
|
|
254
|
+
switch (contentTypeToRead) {
|
|
258
255
|
case "application/json": {
|
|
259
256
|
const text = await odspResponse.content.text();
|
|
260
257
|
propsToLog.bodySize = text.length;
|
|
@@ -549,14 +546,12 @@ export async function downloadSnapshot(
|
|
|
549
546
|
};
|
|
550
547
|
// Decide what snapshot format to fetch as per the feature gate.
|
|
551
548
|
switch (snapshotFormatFetchType) {
|
|
552
|
-
case SnapshotFormatSupportType.JsonAndBinary:
|
|
553
|
-
headers.accept = `application/json, application/ms-fluid; v=${currentReadVersion}`;
|
|
554
|
-
break;
|
|
555
549
|
case SnapshotFormatSupportType.Binary:
|
|
556
550
|
headers.accept = `application/ms-fluid; v=${currentReadVersion}`;
|
|
557
551
|
break;
|
|
558
552
|
default:
|
|
559
|
-
|
|
553
|
+
// By default ask both versions and let the server decide the format.
|
|
554
|
+
headers.accept = `application/json, application/ms-fluid; v=${currentReadVersion}`;
|
|
560
555
|
}
|
|
561
556
|
|
|
562
557
|
const odspResponse = await (epochTracker?.fetch(url, fetchOptions, "treesLatest", true, scenarioName) ??
|
|
@@ -176,7 +176,6 @@ export class OdspDocumentService implements IDocumentService {
|
|
|
176
176
|
this.odspResolvedUrl,
|
|
177
177
|
this.getStorageToken,
|
|
178
178
|
this.mc.logger,
|
|
179
|
-
true,
|
|
180
179
|
this.cache,
|
|
181
180
|
this.hostPolicy,
|
|
182
181
|
this.epochTracker,
|
|
@@ -189,7 +188,7 @@ export class OdspDocumentService implements IDocumentService {
|
|
|
189
188
|
},
|
|
190
189
|
() => {
|
|
191
190
|
assert(this.relayServiceTenantAndSessionId !== undefined,
|
|
192
|
-
|
|
191
|
+
0x37b /* relayServiceTenantAndSessionId should be present */);
|
|
193
192
|
return this.relayServiceTenantAndSessionId;
|
|
194
193
|
},
|
|
195
194
|
this.mc.config.getNumber("Fluid.Driver.Odsp.snapshotFormatFetchType"),
|
|
@@ -26,6 +26,10 @@ import {
|
|
|
26
26
|
HostStoragePolicy,
|
|
27
27
|
IFileEntry,
|
|
28
28
|
IOdspUrlParts,
|
|
29
|
+
SharingLinkScope,
|
|
30
|
+
SharingLinkRole,
|
|
31
|
+
ShareLinkTypes,
|
|
32
|
+
ISharingLinkKind,
|
|
29
33
|
} from "@fluidframework/odsp-driver-definitions";
|
|
30
34
|
import type { io as SocketIOClientStatic } from "socket.io-client";
|
|
31
35
|
import { v4 as uuid } from "uuid";
|
|
@@ -84,15 +88,13 @@ export class OdspDocumentServiceFactoryCore implements IDocumentServiceFactory {
|
|
|
84
88
|
}
|
|
85
89
|
}
|
|
86
90
|
|
|
91
|
+
const createShareLinkParam = getSharingLinkParams(this.hostPolicy, searchParams);
|
|
87
92
|
const newFileInfo: INewFileInfo = {
|
|
88
93
|
driveId: odspResolvedUrl.driveId,
|
|
89
94
|
siteUrl: odspResolvedUrl.siteUrl,
|
|
90
95
|
filePath,
|
|
91
96
|
filename: odspResolvedUrl.fileName,
|
|
92
|
-
|
|
93
|
-
// so that share link creation with create file can be enabled
|
|
94
|
-
createLinkType: this.hostPolicy.enableShareLinkWithCreate ?
|
|
95
|
-
odspResolvedUrl.shareLinkInfo?.createLink?.type : undefined,
|
|
97
|
+
createLinkType: createShareLinkParam,
|
|
96
98
|
};
|
|
97
99
|
|
|
98
100
|
const odspLogger = createOdspLogger(logger);
|
|
@@ -110,6 +112,10 @@ export class OdspDocumentServiceFactoryCore implements IDocumentServiceFactory {
|
|
|
110
112
|
{
|
|
111
113
|
eventName: "CreateNew",
|
|
112
114
|
isWithSummaryUpload: true,
|
|
115
|
+
createShareLinkParam: JSON.stringify(createShareLinkParam),
|
|
116
|
+
enableShareLinkWithCreate: this.hostPolicy.enableShareLinkWithCreate,
|
|
117
|
+
enableSingleRequestForShareLinkWithCreate:
|
|
118
|
+
this.hostPolicy.enableSingleRequestForShareLinkWithCreate,
|
|
113
119
|
},
|
|
114
120
|
async (event) => {
|
|
115
121
|
odspResolvedUrl = await createNewFluidFile(
|
|
@@ -127,6 +133,8 @@ export class OdspDocumentServiceFactoryCore implements IDocumentServiceFactory {
|
|
|
127
133
|
this.hostPolicy.cacheCreateNewSummary ?? true,
|
|
128
134
|
!!this.hostPolicy.sessionOptions?.forceAccessTokenViaAuthorizationHeader,
|
|
129
135
|
odspResolvedUrl.isClpCompliantApp,
|
|
136
|
+
this.hostPolicy.enableSingleRequestForShareLinkWithCreate,
|
|
137
|
+
this.hostPolicy.enableShareLinkWithCreate,
|
|
130
138
|
);
|
|
131
139
|
const docService = this.createDocumentServiceCore(odspResolvedUrl, odspLogger,
|
|
132
140
|
cacheAndTracker, clientIsSummarizer);
|
|
@@ -223,3 +231,31 @@ export class OdspDocumentServiceFactoryCore implements IDocumentServiceFactory {
|
|
|
223
231
|
);
|
|
224
232
|
}
|
|
225
233
|
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Extract the sharing link kind from the resolved URL's query paramerters
|
|
237
|
+
*/
|
|
238
|
+
function getSharingLinkParams(
|
|
239
|
+
hostPolicy: HostStoragePolicy,
|
|
240
|
+
searchParams: URLSearchParams,
|
|
241
|
+
): ShareLinkTypes | ISharingLinkKind | undefined {
|
|
242
|
+
// extract request parameters for creation of sharing link (if provided) if the feature is enabled
|
|
243
|
+
let createShareLinkParam: ShareLinkTypes | ISharingLinkKind | undefined;
|
|
244
|
+
if (hostPolicy.enableSingleRequestForShareLinkWithCreate) {
|
|
245
|
+
const createLinkScope = searchParams.get("createLinkScope");
|
|
246
|
+
const createLinkRole = searchParams.get("createLinkRole");
|
|
247
|
+
if (createLinkScope && SharingLinkScope[createLinkScope]) {
|
|
248
|
+
createShareLinkParam = {
|
|
249
|
+
scope: SharingLinkScope[createLinkScope],
|
|
250
|
+
...(createLinkRole && SharingLinkRole[createLinkRole] ?
|
|
251
|
+
{ role: SharingLinkRole[createLinkRole] } : {}),
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
} else if (hostPolicy.enableShareLinkWithCreate) {
|
|
255
|
+
const createLinkType = searchParams.get("createLinkType");
|
|
256
|
+
if (createLinkType && ShareLinkTypes[createLinkType]) {
|
|
257
|
+
createShareLinkParam = ShareLinkTypes[createLinkType || ""];
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
return createShareLinkParam;
|
|
261
|
+
}
|
|
@@ -88,7 +88,6 @@ export class OdspDocumentStorageService extends OdspDocumentStorageServiceBase {
|
|
|
88
88
|
private readonly odspResolvedUrl: IOdspResolvedUrl,
|
|
89
89
|
private readonly getStorageToken: InstrumentedStorageTokenFetcher,
|
|
90
90
|
private readonly logger: ITelemetryLogger,
|
|
91
|
-
private readonly fetchFullSnapshot: boolean,
|
|
92
91
|
private readonly cache: IOdspCache,
|
|
93
92
|
private readonly hostPolicy: HostStoragePolicyInternal,
|
|
94
93
|
private readonly epochTracker: EpochTracker,
|
|
@@ -228,8 +227,7 @@ export class OdspDocumentStorageService extends OdspDocumentStorageServiceBase {
|
|
|
228
227
|
}
|
|
229
228
|
|
|
230
229
|
// If count is one, we can use the trees/latest API, which returns the latest version and trees in a single request for better performance
|
|
231
|
-
|
|
232
|
-
if (this.firstVersionCall && count === 1 && (blobid === null || blobid === this.documentId)) {
|
|
230
|
+
if (count === 1 && (blobid === null || blobid === this.documentId)) {
|
|
233
231
|
const hostSnapshotOptions = this.hostPolicy.snapshotOptions;
|
|
234
232
|
const odspSnapshotCacheValue: ISnapshotContents = await PerformanceEvent.timedExecAsync(
|
|
235
233
|
this.logger,
|
|
@@ -275,7 +273,10 @@ export class OdspDocumentStorageService extends OdspDocumentStorageServiceBase {
|
|
|
275
273
|
// Based on the concurrentSnapshotFetch policy:
|
|
276
274
|
// Either retrieve both the network and cache snapshots concurrently and pick the first to return,
|
|
277
275
|
// or grab the cache value and then the network value if the cache value returns undefined.
|
|
278
|
-
|
|
276
|
+
// For summarizer which could call this during refreshing of summary parent, always use the cache
|
|
277
|
+
// first. Also for other clients, if it is not critical path which is determined by firstVersionCall,
|
|
278
|
+
// then also check the cache first.
|
|
279
|
+
if (this.firstVersionCall && this.hostPolicy.concurrentSnapshotFetch && !this.hostPolicy.summarizerClient) {
|
|
279
280
|
const networkSnapshotP = this.fetchSnapshot(hostSnapshotOptions, scenarioName);
|
|
280
281
|
|
|
281
282
|
// Ensure that failures on both paths are ignored initially.
|
|
@@ -306,11 +307,18 @@ export class OdspDocumentStorageService extends OdspDocumentStorageServiceBase {
|
|
|
306
307
|
// while the first caller is awaiting later async code in this block.
|
|
307
308
|
|
|
308
309
|
retrievedSnapshot = await cachedSnapshotP;
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
310
|
+
if (retrievedSnapshot !== undefined) {
|
|
311
|
+
method = "cache";
|
|
312
|
+
} else {
|
|
313
|
+
method = "network";
|
|
314
|
+
const options: ISnapshotOptions = { ...hostSnapshotOptions };
|
|
315
|
+
// Don't fetch the blobs/deltas if it is not the first call. By default server will add
|
|
316
|
+
// blobs and deltas to the response.
|
|
317
|
+
if (!this.firstVersionCall) {
|
|
318
|
+
options.blobs = 0;
|
|
319
|
+
options.deltas = 0;
|
|
320
|
+
}
|
|
321
|
+
retrievedSnapshot = await this.fetchSnapshot(options, scenarioName);
|
|
314
322
|
}
|
|
315
323
|
}
|
|
316
324
|
}
|
|
@@ -322,10 +330,9 @@ export class OdspDocumentStorageService extends OdspDocumentStorageServiceBase {
|
|
|
322
330
|
},
|
|
323
331
|
);
|
|
324
332
|
|
|
325
|
-
//
|
|
333
|
+
// Don't override ops which were fetched during initial load, since we could still need them.
|
|
334
|
+
const id = this.initializeFromSnapshot(odspSnapshotCacheValue, this.firstVersionCall);
|
|
326
335
|
this.firstVersionCall = false;
|
|
327
|
-
const id = this.initializeFromSnapshot(odspSnapshotCacheValue);
|
|
328
|
-
|
|
329
336
|
return id ? [{ id, treeId: undefined! }] : [];
|
|
330
337
|
}
|
|
331
338
|
|
|
@@ -545,7 +552,6 @@ export class OdspDocumentStorageService extends OdspDocumentStorageServiceBase {
|
|
|
545
552
|
this.snapshotUrl!,
|
|
546
553
|
storageToken,
|
|
547
554
|
id,
|
|
548
|
-
this.fetchFullSnapshot,
|
|
549
555
|
!!this.hostPolicy.sessionOptions?.forceAccessTokenViaAuthorizationHeader,
|
|
550
556
|
this.logger,
|
|
551
557
|
snapshotDownloader,
|
|
@@ -244,7 +244,7 @@ export abstract class OdspDocumentStorageServiceBase implements IDocumentStorage
|
|
|
244
244
|
return summarySnapshotTree;
|
|
245
245
|
}
|
|
246
246
|
|
|
247
|
-
protected initializeFromSnapshot(odspSnapshotCacheValue: ISnapshotContents): string | undefined {
|
|
247
|
+
protected initializeFromSnapshot(odspSnapshotCacheValue: ISnapshotContents, cacheOps: boolean = true): string | undefined {
|
|
248
248
|
this._snapshotSequenceNumber = odspSnapshotCacheValue.sequenceNumber;
|
|
249
249
|
const { snapshotTree, blobs, ops } = odspSnapshotCacheValue;
|
|
250
250
|
|
|
@@ -260,7 +260,9 @@ export abstract class OdspDocumentStorageServiceBase implements IDocumentStorage
|
|
|
260
260
|
this.initBlobsCache(blobs);
|
|
261
261
|
}
|
|
262
262
|
|
|
263
|
-
|
|
263
|
+
if (cacheOps) {
|
|
264
|
+
this.ops = ops;
|
|
265
|
+
}
|
|
264
266
|
return id;
|
|
265
267
|
}
|
|
266
268
|
}
|
package/src/odspUtils.ts
CHANGED
|
@@ -27,6 +27,7 @@ import {
|
|
|
27
27
|
isTokenFromCache,
|
|
28
28
|
OdspResourceTokenFetchOptions,
|
|
29
29
|
ShareLinkTypes,
|
|
30
|
+
ISharingLinkKind,
|
|
30
31
|
TokenFetcher,
|
|
31
32
|
ICacheEntry,
|
|
32
33
|
snapshotKey,
|
|
@@ -233,8 +234,10 @@ export interface INewFileInfo {
|
|
|
233
234
|
* application can request creation of a share link along with the creation of a new file
|
|
234
235
|
* by passing in an optional param to specify the kind of sharing link
|
|
235
236
|
* (at the time of adding this comment Sept/2021), odsp only supports csl
|
|
237
|
+
* ShareLinkTypes will deprecated in future. Use ISharingLinkKind instead which specifies both
|
|
238
|
+
* share link type and the role type.
|
|
236
239
|
*/
|
|
237
|
-
createLinkType?: ShareLinkTypes;
|
|
240
|
+
createLinkType?: ShareLinkTypes | ISharingLinkKind;
|
|
238
241
|
}
|
|
239
242
|
|
|
240
243
|
export function getOdspResolvedUrl(resolvedUrl: IResolvedUrl): IOdspResolvedUrl {
|
|
@@ -348,3 +351,23 @@ export function createCacheSnapshotKey(odspResolvedUrl: IOdspResolvedUrl): ICach
|
|
|
348
351
|
// 80KB is the max body size that we can put in ump post body for server to be able to accept it.
|
|
349
352
|
// Keeping it 78KB to be a little cautious. As per the telemetry 99p is less than 78KB.
|
|
350
353
|
export const maxUmpPostBodySize = 79872;
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* Build request parameters to request for the creation of a sharing link along with the creation of the file
|
|
357
|
+
* through the /snapshot api call.
|
|
358
|
+
* @param shareLinkType - Kind of sharing link requested
|
|
359
|
+
* @returns A string of request parameters that can be concatenated with the base URI
|
|
360
|
+
*/
|
|
361
|
+
export function buildOdspShareLinkReqParams(shareLinkType: ShareLinkTypes | ISharingLinkKind | undefined) {
|
|
362
|
+
if (!shareLinkType) {
|
|
363
|
+
return;
|
|
364
|
+
}
|
|
365
|
+
const scope = (shareLinkType as ISharingLinkKind).scope;
|
|
366
|
+
if (!scope) {
|
|
367
|
+
return `createLinkType=${shareLinkType}`;
|
|
368
|
+
}
|
|
369
|
+
let shareLinkRequestParams = `createLinkScope=${scope}`;
|
|
370
|
+
const role = (shareLinkType as ISharingLinkKind).role;
|
|
371
|
+
shareLinkRequestParams = role ? `${shareLinkRequestParams}&createLinkRole=${role}` : shareLinkRequestParams;
|
|
372
|
+
return shareLinkRequestParams;
|
|
373
|
+
}
|
package/src/packageVersion.ts
CHANGED