@fluidframework/odsp-driver 0.51.3 → 0.53.0-46105
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/contractsPublic.d.ts +0 -4
- package/dist/contractsPublic.d.ts.map +1 -1
- package/dist/contractsPublic.js.map +1 -1
- package/dist/createFile.d.ts.map +1 -1
- package/dist/createFile.js +11 -9
- package/dist/createFile.js.map +1 -1
- package/dist/createNewUtils.js +5 -4
- package/dist/createNewUtils.js.map +1 -1
- package/dist/epochTracker.d.ts +2 -1
- package/dist/epochTracker.d.ts.map +1 -1
- package/dist/epochTracker.js +51 -25
- package/dist/epochTracker.js.map +1 -1
- package/dist/fetchSnapshot.d.ts.map +1 -1
- package/dist/fetchSnapshot.js +1 -1
- package/dist/fetchSnapshot.js.map +1 -1
- package/dist/getFileLink.d.ts +1 -1
- package/dist/getFileLink.d.ts.map +1 -1
- package/dist/getFileLink.js +32 -22
- package/dist/getFileLink.js.map +1 -1
- package/dist/odspDeltaStorageService.d.ts +3 -3
- package/dist/odspDeltaStorageService.d.ts.map +1 -1
- package/dist/odspDeltaStorageService.js +7 -4
- package/dist/odspDeltaStorageService.js.map +1 -1
- package/dist/odspDocumentDeltaConnection.d.ts.map +1 -1
- package/dist/odspDocumentDeltaConnection.js +2 -0
- package/dist/odspDocumentDeltaConnection.js.map +1 -1
- package/dist/odspDocumentService.d.ts.map +1 -1
- package/dist/odspDocumentService.js +3 -3
- package/dist/odspDocumentService.js.map +1 -1
- package/dist/odspDocumentStorageManager.d.ts.map +1 -1
- package/dist/odspDocumentStorageManager.js +30 -34
- package/dist/odspDocumentStorageManager.js.map +1 -1
- package/dist/odspDriverUrlResolver.d.ts +0 -4
- package/dist/odspDriverUrlResolver.d.ts.map +1 -1
- package/dist/odspDriverUrlResolver.js +0 -7
- package/dist/odspDriverUrlResolver.js.map +1 -1
- package/dist/odspDriverUrlResolverForShareLink.d.ts +2 -6
- package/dist/odspDriverUrlResolverForShareLink.d.ts.map +1 -1
- package/dist/odspDriverUrlResolverForShareLink.js +4 -15
- package/dist/odspDriverUrlResolverForShareLink.js.map +1 -1
- package/dist/odspError.d.ts.map +1 -1
- package/dist/odspError.js +3 -1
- package/dist/odspError.js.map +1 -1
- package/dist/odspSummaryUploadManager.js +24 -4
- package/dist/odspSummaryUploadManager.js.map +1 -1
- package/dist/odspUtils.d.ts.map +1 -1
- package/dist/odspUtils.js +31 -23
- 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/dist/zipItDataRepresentationUtils.d.ts.map +1 -1
- package/dist/zipItDataRepresentationUtils.js +3 -4
- package/dist/zipItDataRepresentationUtils.js.map +1 -1
- package/lib/contractsPublic.d.ts +0 -4
- package/lib/contractsPublic.d.ts.map +1 -1
- package/lib/contractsPublic.js.map +1 -1
- package/lib/createFile.d.ts.map +1 -1
- package/lib/createFile.js +12 -10
- package/lib/createFile.js.map +1 -1
- package/lib/createNewUtils.js +5 -4
- package/lib/createNewUtils.js.map +1 -1
- package/lib/epochTracker.d.ts +2 -1
- package/lib/epochTracker.d.ts.map +1 -1
- package/lib/epochTracker.js +52 -26
- package/lib/epochTracker.js.map +1 -1
- package/lib/fetchSnapshot.d.ts.map +1 -1
- package/lib/fetchSnapshot.js +1 -1
- package/lib/fetchSnapshot.js.map +1 -1
- package/lib/getFileLink.d.ts +1 -1
- package/lib/getFileLink.d.ts.map +1 -1
- package/lib/getFileLink.js +34 -24
- package/lib/getFileLink.js.map +1 -1
- package/lib/odspDeltaStorageService.d.ts +3 -3
- package/lib/odspDeltaStorageService.d.ts.map +1 -1
- package/lib/odspDeltaStorageService.js +7 -4
- package/lib/odspDeltaStorageService.js.map +1 -1
- package/lib/odspDocumentDeltaConnection.d.ts.map +1 -1
- package/lib/odspDocumentDeltaConnection.js +2 -0
- package/lib/odspDocumentDeltaConnection.js.map +1 -1
- package/lib/odspDocumentService.d.ts.map +1 -1
- package/lib/odspDocumentService.js +4 -4
- package/lib/odspDocumentService.js.map +1 -1
- package/lib/odspDocumentStorageManager.d.ts.map +1 -1
- package/lib/odspDocumentStorageManager.js +33 -37
- package/lib/odspDocumentStorageManager.js.map +1 -1
- package/lib/odspDriverUrlResolver.d.ts +0 -4
- package/lib/odspDriverUrlResolver.d.ts.map +1 -1
- package/lib/odspDriverUrlResolver.js +0 -7
- package/lib/odspDriverUrlResolver.js.map +1 -1
- package/lib/odspDriverUrlResolverForShareLink.d.ts +2 -6
- package/lib/odspDriverUrlResolverForShareLink.d.ts.map +1 -1
- package/lib/odspDriverUrlResolverForShareLink.js +5 -16
- package/lib/odspDriverUrlResolverForShareLink.js.map +1 -1
- package/lib/odspError.d.ts.map +1 -1
- package/lib/odspError.js +3 -1
- package/lib/odspError.js.map +1 -1
- package/lib/odspSummaryUploadManager.js +5 -4
- package/lib/odspSummaryUploadManager.js.map +1 -1
- package/lib/odspUtils.d.ts.map +1 -1
- package/lib/odspUtils.js +33 -25
- 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/lib/zipItDataRepresentationUtils.d.ts.map +1 -1
- package/lib/zipItDataRepresentationUtils.js +3 -4
- package/lib/zipItDataRepresentationUtils.js.map +1 -1
- package/package.json +12 -12
- package/src/contractsPublic.ts +0 -5
- package/src/createFile.ts +13 -9
- package/src/epochTracker.ts +52 -25
- package/src/fetchSnapshot.ts +2 -1
- package/src/getFileLink.ts +47 -27
- package/src/odspDeltaStorageService.ts +10 -3
- package/src/odspDocumentDeltaConnection.ts +2 -0
- package/src/odspDocumentService.ts +8 -4
- package/src/odspDocumentStorageManager.ts +49 -38
- package/src/odspDriverUrlResolver.ts +0 -13
- package/src/odspDriverUrlResolverForShareLink.ts +10 -23
- package/src/odspError.ts +5 -1
- package/src/odspUtils.ts +43 -35
- package/src/packageVersion.ts +1 -1
- package/src/zipItDataRepresentationUtils.ts +4 -8
|
@@ -3,10 +3,6 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
import { IOdspUrlParts } from "@fluidframework/odsp-driver-definitions";
|
|
6
|
-
/**
|
|
7
|
-
* @deprecated - use OdspFluidDataStoreLocator
|
|
8
|
-
*/
|
|
9
|
-
export declare type OdspDocumentInfo = OdspFluidDataStoreLocator;
|
|
10
6
|
export interface OdspFluidDataStoreLocator extends IOdspUrlParts {
|
|
11
7
|
dataStorePath: string;
|
|
12
8
|
appName?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contractsPublic.d.ts","sourceRoot":"","sources":["../src/contractsPublic.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AAExE
|
|
1
|
+
{"version":3,"file":"contractsPublic.d.ts","sourceRoot":"","sources":["../src/contractsPublic.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AAExE,MAAM,WAAW,yBAA0B,SAAQ,aAAa;IAC5D,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,oBAAY,iBAAiB;IAGzB,qBAAqB,0BAA0B;CAClD;AAED,MAAM,WAAW,kBAAkB;IAC/B,CAAC,iBAAiB,CAAC,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACtD;AAED,OAAO,QAAQ,iCAAiC,CAAC;IAE7C,UAAiB,cAAe,SAAQ,OAAO,CAAC,kBAAkB,CAAC;KAAI;CAC1E"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contractsPublic.js","sourceRoot":"","sources":["../src/contractsPublic.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;
|
|
1
|
+
{"version":3,"file":"contractsPublic.js","sourceRoot":"","sources":["../src/contractsPublic.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAWH,IAAY,iBAIX;AAJD,WAAY,iBAAiB;IACzB,yGAAyG;IACzG,sDAAsD;IACtD,oEAA+C,CAAA;AACnD,CAAC,EAJW,iBAAiB,GAAjB,yBAAiB,KAAjB,yBAAiB,QAI5B","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IOdspUrlParts } from \"@fluidframework/odsp-driver-definitions\";\n\nexport interface OdspFluidDataStoreLocator extends IOdspUrlParts {\n dataStorePath: string;\n appName?: string;\n containerPackageName?: string;\n fileVersion?: string;\n}\n\nexport enum SharingLinkHeader {\n // Can be used in request made to resolver, to tell the resolver that the passed in URL is a sharing link\n // which can be redeemed at server to get permissions.\n isSharingLinkToRedeem = \"isSharingLinkToRedeem\",\n}\n\nexport interface ISharingLinkHeader {\n [SharingLinkHeader.isSharingLinkToRedeem]: boolean;\n}\n\ndeclare module \"@fluidframework/core-interfaces\" {\n // eslint-disable-next-line @typescript-eslint/no-empty-interface\n export interface IRequestHeader extends Partial<ISharingLinkHeader> { }\n}\n"]}
|
package/dist/createFile.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createFile.d.ts","sourceRoot":"","sources":["../src/createFile.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"createFile.d.ts","sourceRoot":"","sources":["../src/createFile.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAe,YAAY,EAAgB,MAAM,sCAAsC,CAAC;AAC/F,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAEtE,OAAO,EACH,UAAU,EACV,+BAA+B,EAC/B,gBAAgB,EAEnB,MAAM,yCAAyC,CAAC;AAEjD,OAAO,EACH,gBAAgB,EAGhB,mBAAmB,EAEtB,MAAM,aAAa,CAAC;AAErB,OAAO,EAGH,YAAY,EAGf,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAU9C;;;GAGG;AACH,wBAAsB,kBAAkB,CACpC,eAAe,EAAE,+BAA+B,EAChD,WAAW,EAAE,YAAY,EACzB,MAAM,EAAE,gBAAgB,EACxB,gBAAgB,EAAE,YAAY,GAAG,SAAS,EAC1C,YAAY,EAAE,YAAY,EAC1B,SAAS,EAAE,UAAU,EACrB,gBAAgB,EAAE,OAAO,GAC1B,OAAO,CAAC,gBAAgB,CAAC,CA8C3B;AAED,wBAAsB,uBAAuB,CACzC,eAAe,EAAE,+BAA+B,EAChD,WAAW,EAAE,YAAY,EACzB,MAAM,EAAE,gBAAgB,EACxB,YAAY,EAAE,YAAY,GAC3B,OAAO,CAAC,MAAM,CAAC,CA+CjB;AAED,wBAAsB,6BAA6B,CAC/C,eAAe,EAAE,+BAA+B,EAChD,WAAW,EAAE,YAAY,EACzB,MAAM,EAAE,gBAAgB,EACxB,gBAAgB,EAAE,YAAY,EAC9B,YAAY,EAAE,YAAY,GAC3B,OAAO,CAAC,mBAAmB,CAAC,CAmD9B;AA+BD;;GAEG;AACH,wBAAgB,wCAAwC,CAAC,OAAO,EAAE,YAAY,GAAG,gBAAgB,CAoDhG"}
|
package/dist/createFile.js
CHANGED
|
@@ -7,9 +7,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
7
7
|
exports.convertSummaryToSnapshotTreeForCreateNew = exports.createNewFluidFileFromSummary = exports.createNewEmptyFluidFile = exports.createNewFluidFile = void 0;
|
|
8
8
|
const common_utils_1 = require("@fluidframework/common-utils");
|
|
9
9
|
const driver_utils_1 = require("@fluidframework/driver-utils");
|
|
10
|
-
const odsp_doclib_utils_1 = require("@fluidframework/odsp-doclib-utils");
|
|
11
10
|
const protocol_base_1 = require("@fluidframework/protocol-base");
|
|
11
|
+
const protocol_definitions_1 = require("@fluidframework/protocol-definitions");
|
|
12
12
|
const telemetry_utils_1 = require("@fluidframework/telemetry-utils");
|
|
13
|
+
const odsp_driver_definitions_1 = require("@fluidframework/odsp-driver-definitions");
|
|
14
|
+
const driver_definitions_1 = require("@fluidframework/driver-definitions");
|
|
13
15
|
const getUrlAndHeadersWithAuth_1 = require("./getUrlAndHeadersWithAuth");
|
|
14
16
|
const odspUtils_1 = require("./odspUtils");
|
|
15
17
|
const createOdspUrl_1 = require("./createOdspUrl");
|
|
@@ -28,7 +30,7 @@ const isInvalidFileName = (fileName) => {
|
|
|
28
30
|
async function createNewFluidFile(getStorageToken, newFileInfo, logger, createNewSummary, epochTracker, fileEntry, createNewCaching) {
|
|
29
31
|
// Check for valid filename before the request to create file is actually made.
|
|
30
32
|
if (isInvalidFileName(newFileInfo.filename)) {
|
|
31
|
-
|
|
33
|
+
throw new driver_utils_1.NonRetryableError("createNewInvalidFilename", "Invalid filename", odsp_driver_definitions_1.OdspErrorType.invalidFileNameError);
|
|
32
34
|
}
|
|
33
35
|
let itemId;
|
|
34
36
|
let summaryHandle = "";
|
|
@@ -85,7 +87,7 @@ async function createNewEmptyFluidFile(getStorageToken, newFileInfo, logger, epo
|
|
|
85
87
|
}, "createFile"), "createFile", logger);
|
|
86
88
|
const content = fetchResponse.content;
|
|
87
89
|
if (!content || !content.id) {
|
|
88
|
-
|
|
90
|
+
throw new driver_utils_1.NonRetryableError("createEmptyFileNoItemId", "ODSP CreateFile call returned no item ID", driver_definitions_1.DriverErrorType.incorrectServerResponse);
|
|
89
91
|
}
|
|
90
92
|
event.end(Object.assign({ headers: Object.keys(headers).length !== 0 ? true : undefined }, fetchResponse.commonSpoHeaders));
|
|
91
93
|
return content.id;
|
|
@@ -113,7 +115,7 @@ async function createNewFluidFileFromSummary(getStorageToken, newFileInfo, logge
|
|
|
113
115
|
}, "createFile"), "createFile", logger);
|
|
114
116
|
const content = fetchResponse.content;
|
|
115
117
|
if (!content || !content.itemId) {
|
|
116
|
-
|
|
118
|
+
throw new driver_utils_1.NonRetryableError("createFileNoItemId", "ODSP CreateFile call returned no item ID", driver_definitions_1.DriverErrorType.incorrectServerResponse);
|
|
117
119
|
}
|
|
118
120
|
event.end(Object.assign({ headers: Object.keys(headers).length !== 0 ? true : undefined, attempts: options.refresh ? 2 : 1 }, fetchResponse.commonSpoHeaders));
|
|
119
121
|
return content;
|
|
@@ -130,12 +132,12 @@ function convertSummaryIntoContainerSnapshot(createNewSummary) {
|
|
|
130
132
|
}
|
|
131
133
|
const documentAttributes = driver_utils_1.getDocAttributesFromProtocolSummary(protocolSummary);
|
|
132
134
|
const attributesSummaryBlob = {
|
|
133
|
-
type:
|
|
135
|
+
type: protocol_definitions_1.SummaryType.Blob,
|
|
134
136
|
content: JSON.stringify(documentAttributes),
|
|
135
137
|
};
|
|
136
138
|
protocolSummary.tree.attributes = attributesSummaryBlob;
|
|
137
139
|
const convertedCreateNewSummary = {
|
|
138
|
-
type:
|
|
140
|
+
type: protocol_definitions_1.SummaryType.Tree,
|
|
139
141
|
tree: {
|
|
140
142
|
".protocol": protocolSummary,
|
|
141
143
|
".app": appSummary,
|
|
@@ -168,12 +170,12 @@ function convertSummaryToSnapshotTreeForCreateNew(summary) {
|
|
|
168
170
|
// the tree entry is considered unreferenced.
|
|
169
171
|
let unreferenced;
|
|
170
172
|
switch (summaryObject.type) {
|
|
171
|
-
case
|
|
173
|
+
case protocol_definitions_1.SummaryType.Tree: {
|
|
172
174
|
value = convertSummaryToSnapshotTreeForCreateNew(summaryObject);
|
|
173
175
|
unreferenced = summaryObject.unreferenced;
|
|
174
176
|
break;
|
|
175
177
|
}
|
|
176
|
-
case
|
|
178
|
+
case protocol_definitions_1.SummaryType.Blob: {
|
|
177
179
|
const content = typeof summaryObject.content === "string" ?
|
|
178
180
|
summaryObject.content : common_utils_1.Uint8ArrayToString(summaryObject.content, "base64");
|
|
179
181
|
const encoding = typeof summaryObject.content === "string" ? "utf-8" : "base64";
|
|
@@ -184,7 +186,7 @@ function convertSummaryToSnapshotTreeForCreateNew(summary) {
|
|
|
184
186
|
};
|
|
185
187
|
break;
|
|
186
188
|
}
|
|
187
|
-
case
|
|
189
|
+
case protocol_definitions_1.SummaryType.Handle: {
|
|
188
190
|
throw new Error("No handle should be present for first summary!!");
|
|
189
191
|
}
|
|
190
192
|
default: {
|
package/dist/createFile.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createFile.js","sourceRoot":"","sources":["../src/createFile.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert, Uint8ArrayToString } from \"@fluidframework/common-utils\";\nimport { getDocAttributesFromProtocolSummary } from \"@fluidframework/driver-utils\";\nimport {\n fetchIncorrectResponse,\n invalidFileNameStatusCode,\n throwOdspNetworkError,\n} from \"@fluidframework/odsp-doclib-utils\";\nimport { getGitType } from \"@fluidframework/protocol-base\";\nimport { SummaryType, ISummaryTree, ISummaryBlob } from \"@fluidframework/protocol-definitions\";\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { PerformanceEvent } from \"@fluidframework/telemetry-utils\";\nimport {\n IFileEntry,\n InstrumentedStorageTokenFetcher,\n IOdspResolvedUrl,\n} from \"@fluidframework/odsp-driver-definitions\";\nimport {\n IOdspSummaryTree,\n OdspSummaryTreeValue,\n OdspSummaryTreeEntry,\n ICreateFileResponse,\n IOdspSummaryPayload,\n} from \"./contracts\";\nimport { getUrlAndHeadersWithAuth } from \"./getUrlAndHeadersWithAuth\";\nimport {\n createCacheSnapshotKey,\n getWithRetryForTokenRefresh,\n INewFileInfo,\n getOrigin,\n ISnapshotContents,\n} from \"./odspUtils\";\nimport { createOdspUrl } from \"./createOdspUrl\";\nimport { getApiRoot } from \"./odspUrlHelper\";\nimport { EpochTracker } from \"./epochTracker\";\nimport { OdspDriverUrlResolver } from \"./odspDriverUrlResolver\";\nimport { convertCreateNewSummaryTreeToTreeAndBlobs } from \"./createNewUtils\";\nimport { runWithRetry } from \"./retryUtils\";\n\nconst isInvalidFileName = (fileName: string): boolean => {\n const invalidCharsRegex = /[\"*/:<>?\\\\|]+/g;\n return !!fileName.match(invalidCharsRegex);\n};\n\n/**\n * Creates a new Fluid file.\n * Returns resolved url\n */\nexport async function createNewFluidFile(\n getStorageToken: InstrumentedStorageTokenFetcher,\n newFileInfo: INewFileInfo,\n logger: ITelemetryLogger,\n createNewSummary: ISummaryTree | undefined,\n epochTracker: EpochTracker,\n fileEntry: IFileEntry,\n createNewCaching: boolean,\n): Promise<IOdspResolvedUrl> {\n // Check for valid filename before the request to create file is actually made.\n if (isInvalidFileName(newFileInfo.filename)) {\n throwOdspNetworkError(\"invalidFilename\", invalidFileNameStatusCode);\n }\n\n let itemId: string;\n let summaryHandle: string = \"\";\n let sharingLink: string | undefined;\n let sharingLinkErrorReason: string | undefined;\n if (createNewSummary === undefined) {\n itemId = await createNewEmptyFluidFile(getStorageToken, newFileInfo, logger, epochTracker);\n } else {\n const content = await createNewFluidFileFromSummary(\n getStorageToken, newFileInfo, logger, createNewSummary, epochTracker);\n itemId = content.itemId;\n summaryHandle = content.id;\n sharingLink = content.sharingLink;\n sharingLinkErrorReason = content.sharingLinkErrorReason;\n }\n\n const odspUrl = createOdspUrl({... newFileInfo, itemId, dataStorePath: \"/\"});\n const resolver = new OdspDriverUrlResolver();\n const odspResolvedUrl = await resolver.resolve({ url: odspUrl });\n fileEntry.docId = odspResolvedUrl.hashedDocumentId;\n fileEntry.resolvedUrl = odspResolvedUrl;\n\n if(sharingLink || sharingLinkErrorReason) {\n odspResolvedUrl.shareLinkInfo = {\n createLink: {\n type: newFileInfo.createLinkType,\n link: sharingLink,\n error: sharingLinkErrorReason,\n },\n };\n }\n\n if (createNewSummary !== undefined && createNewCaching) {\n assert(summaryHandle !== undefined, 0x203 /* \"Summary handle is undefined\" */);\n // converting summary and getting sequence number\n const snapshot: ISnapshotContents = convertCreateNewSummaryTreeToTreeAndBlobs(createNewSummary, summaryHandle);\n // caching the converted summary\n await epochTracker.put(createCacheSnapshotKey(odspResolvedUrl), snapshot);\n }\n return odspResolvedUrl;\n}\n\nexport async function createNewEmptyFluidFile(\n getStorageToken: InstrumentedStorageTokenFetcher,\n newFileInfo: INewFileInfo,\n logger: ITelemetryLogger,\n epochTracker: EpochTracker,\n): Promise<string> {\n const filePath = newFileInfo.filePath ? encodeURIComponent(`/${newFileInfo.filePath}`) : \"\";\n // add .tmp extension to empty file (host is expected to rename)\n const encodedFilename = encodeURIComponent(`${newFileInfo.filename}.tmp`);\n const initialUrl =\n `${getApiRoot(getOrigin(newFileInfo.siteUrl))}/drives/${newFileInfo.driveId}/items/root:/${filePath\n }/${encodedFilename}:/content?@name.conflictBehavior=rename&select=id,name,parentReference`;\n\n return getWithRetryForTokenRefresh(async (options) => {\n const storageToken = await getStorageToken(options, \"CreateNewFile\");\n\n return PerformanceEvent.timedExecAsync(\n logger,\n { eventName: \"createNewEmptyFile\" },\n async (event) => {\n const { url, headers } = getUrlAndHeadersWithAuth(initialUrl, storageToken);\n headers[\"Content-Type\"] = \"application/json\";\n\n const fetchResponse = await runWithRetry(\n async () => epochTracker.fetchAndParseAsJSON<ICreateFileResponse>(\n url,\n {\n body: undefined,\n headers,\n method: \"PUT\",\n },\n \"createFile\",\n ),\n \"createFile\",\n logger,\n );\n\n const content = fetchResponse.content;\n if (!content || !content.id) {\n throwOdspNetworkError(\"couldNotParseItemFromVroomResponse\", fetchIncorrectResponse);\n }\n event.end({\n headers: Object.keys(headers).length !== 0 ? true : undefined,\n ...fetchResponse.commonSpoHeaders,\n });\n return content.id;\n },\n { end: true, cancel: \"error\" });\n });\n}\n\nexport async function createNewFluidFileFromSummary(\n getStorageToken: InstrumentedStorageTokenFetcher,\n newFileInfo: INewFileInfo,\n logger: ITelemetryLogger,\n createNewSummary: ISummaryTree,\n epochTracker: EpochTracker,\n): Promise<ICreateFileResponse> {\n const filePath = newFileInfo.filePath ? encodeURIComponent(`/${newFileInfo.filePath}`) : \"\";\n const encodedFilename = encodeURIComponent(newFileInfo.filename);\n const baseUrl =\n `${getApiRoot(getOrigin(newFileInfo.siteUrl))}/drives/${newFileInfo.driveId}/items/root:` +\n `${filePath}/${encodedFilename}`;\n\n const containerSnapshot = convertSummaryIntoContainerSnapshot(createNewSummary);\n const initialUrl = `${baseUrl}:/opStream/snapshots/snapshot${newFileInfo.createLinkType ?\n `?createLinkType=${newFileInfo.createLinkType}` : \"\"}`;\n\n return getWithRetryForTokenRefresh(async (options) => {\n const storageToken = await getStorageToken(options, \"CreateNewFile\");\n\n return PerformanceEvent.timedExecAsync(\n logger,\n { eventName: \"createNewFile\" },\n async (event) => {\n const { url, headers } = getUrlAndHeadersWithAuth(initialUrl, storageToken);\n headers[\"Content-Type\"] = \"application/json\";\n\n const fetchResponse = await runWithRetry(\n async () => epochTracker.fetchAndParseAsJSON<ICreateFileResponse>(\n url,\n {\n body: JSON.stringify(containerSnapshot),\n headers,\n method: \"POST\",\n },\n \"createFile\",\n ),\n \"createFile\",\n logger,\n );\n\n const content = fetchResponse.content;\n if (!content || !content.itemId) {\n throwOdspNetworkError(\"couldNotParseItemFromVroomResponse\", fetchIncorrectResponse);\n }\n event.end({\n headers: Object.keys(headers).length !== 0 ? true : undefined,\n attempts: options.refresh ? 2 : 1,\n ...fetchResponse.commonSpoHeaders,\n });\n return content;\n },\n );\n });\n}\n\nfunction convertSummaryIntoContainerSnapshot(createNewSummary: ISummaryTree) {\n const appSummary = createNewSummary.tree[\".app\"] as ISummaryTree;\n const protocolSummary = createNewSummary.tree[\".protocol\"] as ISummaryTree;\n if (!(appSummary && protocolSummary)) {\n throw new Error(\"App and protocol summary required for create new path!!\");\n }\n const documentAttributes = getDocAttributesFromProtocolSummary(protocolSummary);\n const attributesSummaryBlob: ISummaryBlob = {\n type: SummaryType.Blob,\n content: JSON.stringify(documentAttributes),\n };\n protocolSummary.tree.attributes = attributesSummaryBlob;\n const convertedCreateNewSummary: ISummaryTree = {\n type: SummaryType.Tree,\n tree: {\n \".protocol\": protocolSummary,\n \".app\": appSummary,\n },\n };\n const snapshotTree = convertSummaryToSnapshotTreeForCreateNew(convertedCreateNewSummary);\n const snapshot: IOdspSummaryPayload = {\n entries: snapshotTree.entries ?? [],\n message: \"app\",\n sequenceNumber: documentAttributes.sequenceNumber,\n type: \"container\",\n };\n return snapshot;\n}\n\n/**\n * Converts a summary tree to ODSP tree\n */\nexport function convertSummaryToSnapshotTreeForCreateNew(summary: ISummaryTree): IOdspSummaryTree {\n const snapshotTree: IOdspSummaryTree = {\n type: \"tree\",\n entries: [],\n };\n\n const keys = Object.keys(summary.tree);\n for (const key of keys) {\n const summaryObject = summary.tree[key];\n\n let value: OdspSummaryTreeValue;\n // Tracks if an entry is unreferenced. Currently, only tree entries can be marked as unreferenced. If the\n // property is not present, the tree entry is considered referenced. If the property is present and is true,\n // the tree entry is considered unreferenced.\n let unreferenced: true | undefined;\n\n switch (summaryObject.type) {\n case SummaryType.Tree: {\n value = convertSummaryToSnapshotTreeForCreateNew(summaryObject);\n unreferenced = summaryObject.unreferenced;\n break;\n }\n case SummaryType.Blob: {\n const content = typeof summaryObject.content === \"string\" ?\n summaryObject.content : Uint8ArrayToString(summaryObject.content, \"base64\");\n const encoding = typeof summaryObject.content === \"string\" ? \"utf-8\" : \"base64\";\n\n value = {\n type: \"blob\",\n content,\n encoding,\n };\n break;\n }\n case SummaryType.Handle: {\n throw new Error(\"No handle should be present for first summary!!\");\n }\n default: {\n throw new Error(`Unknown tree type ${summaryObject.type}`);\n }\n }\n\n const entry: OdspSummaryTreeEntry = {\n path: encodeURIComponent(key),\n type: getGitType(summaryObject),\n value,\n unreferenced,\n };\n snapshotTree.entries?.push(entry);\n }\n\n return snapshotTree;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"createFile.js","sourceRoot":"","sources":["../src/createFile.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert, Uint8ArrayToString } from \"@fluidframework/common-utils\";\nimport { getDocAttributesFromProtocolSummary, NonRetryableError } from \"@fluidframework/driver-utils\";\nimport { getGitType } from \"@fluidframework/protocol-base\";\nimport { SummaryType, ISummaryTree, ISummaryBlob } from \"@fluidframework/protocol-definitions\";\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { PerformanceEvent } from \"@fluidframework/telemetry-utils\";\nimport {\n IFileEntry,\n InstrumentedStorageTokenFetcher,\n IOdspResolvedUrl,\n OdspErrorType,\n} from \"@fluidframework/odsp-driver-definitions\";\nimport { DriverErrorType } from \"@fluidframework/driver-definitions\";\nimport {\n IOdspSummaryTree,\n OdspSummaryTreeValue,\n OdspSummaryTreeEntry,\n ICreateFileResponse,\n IOdspSummaryPayload,\n} from \"./contracts\";\nimport { getUrlAndHeadersWithAuth } from \"./getUrlAndHeadersWithAuth\";\nimport {\n createCacheSnapshotKey,\n getWithRetryForTokenRefresh,\n INewFileInfo,\n getOrigin,\n ISnapshotContents,\n} from \"./odspUtils\";\nimport { createOdspUrl } from \"./createOdspUrl\";\nimport { getApiRoot } from \"./odspUrlHelper\";\nimport { EpochTracker } from \"./epochTracker\";\nimport { OdspDriverUrlResolver } from \"./odspDriverUrlResolver\";\nimport { convertCreateNewSummaryTreeToTreeAndBlobs } from \"./createNewUtils\";\nimport { runWithRetry } from \"./retryUtils\";\n\nconst isInvalidFileName = (fileName: string): boolean => {\n const invalidCharsRegex = /[\"*/:<>?\\\\|]+/g;\n return !!fileName.match(invalidCharsRegex);\n};\n\n/**\n * Creates a new Fluid file.\n * Returns resolved url\n */\nexport async function createNewFluidFile(\n getStorageToken: InstrumentedStorageTokenFetcher,\n newFileInfo: INewFileInfo,\n logger: ITelemetryLogger,\n createNewSummary: ISummaryTree | undefined,\n epochTracker: EpochTracker,\n fileEntry: IFileEntry,\n createNewCaching: boolean,\n): Promise<IOdspResolvedUrl> {\n // Check for valid filename before the request to create file is actually made.\n if (isInvalidFileName(newFileInfo.filename)) {\n throw new NonRetryableError(\n \"createNewInvalidFilename\", \"Invalid filename\", OdspErrorType.invalidFileNameError);\n }\n\n let itemId: string;\n let summaryHandle: string = \"\";\n let sharingLink: string | undefined;\n let sharingLinkErrorReason: string | undefined;\n if (createNewSummary === undefined) {\n itemId = await createNewEmptyFluidFile(getStorageToken, newFileInfo, logger, epochTracker);\n } else {\n const content = await createNewFluidFileFromSummary(\n getStorageToken, newFileInfo, logger, createNewSummary, epochTracker);\n itemId = content.itemId;\n summaryHandle = content.id;\n sharingLink = content.sharingLink;\n sharingLinkErrorReason = content.sharingLinkErrorReason;\n }\n\n const odspUrl = createOdspUrl({... newFileInfo, itemId, dataStorePath: \"/\"});\n const resolver = new OdspDriverUrlResolver();\n const odspResolvedUrl = await resolver.resolve({ url: odspUrl });\n fileEntry.docId = odspResolvedUrl.hashedDocumentId;\n fileEntry.resolvedUrl = odspResolvedUrl;\n\n if(sharingLink || sharingLinkErrorReason) {\n odspResolvedUrl.shareLinkInfo = {\n createLink: {\n type: newFileInfo.createLinkType,\n link: sharingLink,\n error: sharingLinkErrorReason,\n },\n };\n }\n\n if (createNewSummary !== undefined && createNewCaching) {\n assert(summaryHandle !== undefined, 0x203 /* \"Summary handle is undefined\" */);\n // converting summary and getting sequence number\n const snapshot: ISnapshotContents = convertCreateNewSummaryTreeToTreeAndBlobs(createNewSummary, summaryHandle);\n // caching the converted summary\n await epochTracker.put(createCacheSnapshotKey(odspResolvedUrl), snapshot);\n }\n return odspResolvedUrl;\n}\n\nexport async function createNewEmptyFluidFile(\n getStorageToken: InstrumentedStorageTokenFetcher,\n newFileInfo: INewFileInfo,\n logger: ITelemetryLogger,\n epochTracker: EpochTracker,\n): Promise<string> {\n const filePath = newFileInfo.filePath ? encodeURIComponent(`/${newFileInfo.filePath}`) : \"\";\n // add .tmp extension to empty file (host is expected to rename)\n const encodedFilename = encodeURIComponent(`${newFileInfo.filename}.tmp`);\n const initialUrl =\n `${getApiRoot(getOrigin(newFileInfo.siteUrl))}/drives/${newFileInfo.driveId}/items/root:/${filePath\n }/${encodedFilename}:/content?@name.conflictBehavior=rename&select=id,name,parentReference`;\n\n return getWithRetryForTokenRefresh(async (options) => {\n const storageToken = await getStorageToken(options, \"CreateNewFile\");\n\n return PerformanceEvent.timedExecAsync(\n logger,\n { eventName: \"createNewEmptyFile\" },\n async (event) => {\n const { url, headers } = getUrlAndHeadersWithAuth(initialUrl, storageToken);\n headers[\"Content-Type\"] = \"application/json\";\n\n const fetchResponse = await runWithRetry(\n async () => epochTracker.fetchAndParseAsJSON<ICreateFileResponse>(\n url,\n {\n body: undefined,\n headers,\n method: \"PUT\",\n },\n \"createFile\",\n ),\n \"createFile\",\n logger,\n );\n\n const content = fetchResponse.content;\n if (!content || !content.id) {\n throw new NonRetryableError(\n \"createEmptyFileNoItemId\",\n \"ODSP CreateFile call returned no item ID\",\n DriverErrorType.incorrectServerResponse);\n }\n event.end({\n headers: Object.keys(headers).length !== 0 ? true : undefined,\n ...fetchResponse.commonSpoHeaders,\n });\n return content.id;\n },\n { end: true, cancel: \"error\" });\n });\n}\n\nexport async function createNewFluidFileFromSummary(\n getStorageToken: InstrumentedStorageTokenFetcher,\n newFileInfo: INewFileInfo,\n logger: ITelemetryLogger,\n createNewSummary: ISummaryTree,\n epochTracker: EpochTracker,\n): Promise<ICreateFileResponse> {\n const filePath = newFileInfo.filePath ? encodeURIComponent(`/${newFileInfo.filePath}`) : \"\";\n const encodedFilename = encodeURIComponent(newFileInfo.filename);\n const baseUrl =\n `${getApiRoot(getOrigin(newFileInfo.siteUrl))}/drives/${newFileInfo.driveId}/items/root:` +\n `${filePath}/${encodedFilename}`;\n\n const containerSnapshot = convertSummaryIntoContainerSnapshot(createNewSummary);\n const initialUrl = `${baseUrl}:/opStream/snapshots/snapshot${newFileInfo.createLinkType ?\n `?createLinkType=${newFileInfo.createLinkType}` : \"\"}`;\n\n return getWithRetryForTokenRefresh(async (options) => {\n const storageToken = await getStorageToken(options, \"CreateNewFile\");\n\n return PerformanceEvent.timedExecAsync(\n logger,\n { eventName: \"createNewFile\" },\n async (event) => {\n const { url, headers } = getUrlAndHeadersWithAuth(initialUrl, storageToken);\n headers[\"Content-Type\"] = \"application/json\";\n\n const fetchResponse = await runWithRetry(\n async () => epochTracker.fetchAndParseAsJSON<ICreateFileResponse>(\n url,\n {\n body: JSON.stringify(containerSnapshot),\n headers,\n method: \"POST\",\n },\n \"createFile\",\n ),\n \"createFile\",\n logger,\n );\n\n const content = fetchResponse.content;\n if (!content || !content.itemId) {\n throw new NonRetryableError(\n \"createFileNoItemId\",\n \"ODSP CreateFile call returned no item ID\",\n DriverErrorType.incorrectServerResponse);\n }\n event.end({\n headers: Object.keys(headers).length !== 0 ? true : undefined,\n attempts: options.refresh ? 2 : 1,\n ...fetchResponse.commonSpoHeaders,\n });\n return content;\n },\n );\n });\n}\n\nfunction convertSummaryIntoContainerSnapshot(createNewSummary: ISummaryTree) {\n const appSummary = createNewSummary.tree[\".app\"] as ISummaryTree;\n const protocolSummary = createNewSummary.tree[\".protocol\"] as ISummaryTree;\n if (!(appSummary && protocolSummary)) {\n throw new Error(\"App and protocol summary required for create new path!!\");\n }\n const documentAttributes = getDocAttributesFromProtocolSummary(protocolSummary);\n const attributesSummaryBlob: ISummaryBlob = {\n type: SummaryType.Blob,\n content: JSON.stringify(documentAttributes),\n };\n protocolSummary.tree.attributes = attributesSummaryBlob;\n const convertedCreateNewSummary: ISummaryTree = {\n type: SummaryType.Tree,\n tree: {\n \".protocol\": protocolSummary,\n \".app\": appSummary,\n },\n };\n const snapshotTree = convertSummaryToSnapshotTreeForCreateNew(convertedCreateNewSummary);\n const snapshot: IOdspSummaryPayload = {\n entries: snapshotTree.entries ?? [],\n message: \"app\",\n sequenceNumber: documentAttributes.sequenceNumber,\n type: \"container\",\n };\n return snapshot;\n}\n\n/**\n * Converts a summary tree to ODSP tree\n */\nexport function convertSummaryToSnapshotTreeForCreateNew(summary: ISummaryTree): IOdspSummaryTree {\n const snapshotTree: IOdspSummaryTree = {\n type: \"tree\",\n entries: [],\n };\n\n const keys = Object.keys(summary.tree);\n for (const key of keys) {\n const summaryObject = summary.tree[key];\n\n let value: OdspSummaryTreeValue;\n // Tracks if an entry is unreferenced. Currently, only tree entries can be marked as unreferenced. If the\n // property is not present, the tree entry is considered referenced. If the property is present and is true,\n // the tree entry is considered unreferenced.\n let unreferenced: true | undefined;\n\n switch (summaryObject.type) {\n case SummaryType.Tree: {\n value = convertSummaryToSnapshotTreeForCreateNew(summaryObject);\n unreferenced = summaryObject.unreferenced;\n break;\n }\n case SummaryType.Blob: {\n const content = typeof summaryObject.content === \"string\" ?\n summaryObject.content : Uint8ArrayToString(summaryObject.content, \"base64\");\n const encoding = typeof summaryObject.content === \"string\" ? \"utf-8\" : \"base64\";\n\n value = {\n type: \"blob\",\n content,\n encoding,\n };\n break;\n }\n case SummaryType.Handle: {\n throw new Error(\"No handle should be present for first summary!!\");\n }\n default: {\n throw new Error(`Unknown tree type ${summaryObject.type}`);\n }\n }\n\n const entry: OdspSummaryTreeEntry = {\n path: encodeURIComponent(key),\n type: getGitType(summaryObject),\n value,\n unreferenced,\n };\n snapshotTree.entries?.push(entry);\n }\n\n return snapshotTree;\n}\n"]}
|
package/dist/createNewUtils.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
7
|
exports.convertCreateNewSummaryTreeToTreeAndBlobs = void 0;
|
|
8
8
|
const uuid_1 = require("uuid");
|
|
9
|
+
const protocol_definitions_1 = require("@fluidframework/protocol-definitions");
|
|
9
10
|
const driver_utils_1 = require("@fluidframework/driver-utils");
|
|
10
11
|
const common_utils_1 = require("@fluidframework/common-utils");
|
|
11
12
|
/**
|
|
@@ -38,12 +39,12 @@ function convertCreateNewSummaryTreeToTreeAndBlobsCore(summary, blobs) {
|
|
|
38
39
|
for (const key of keys) {
|
|
39
40
|
const summaryObject = summary.tree[key];
|
|
40
41
|
switch (summaryObject.type) {
|
|
41
|
-
case
|
|
42
|
+
case protocol_definitions_1.SummaryType.Tree: {
|
|
42
43
|
treeNode.trees[key] =
|
|
43
44
|
convertCreateNewSummaryTreeToTreeAndBlobsCore(summaryObject, blobs);
|
|
44
45
|
break;
|
|
45
46
|
}
|
|
46
|
-
case
|
|
47
|
+
case protocol_definitions_1.SummaryType.Blob: {
|
|
47
48
|
const contentBuffer = typeof summaryObject.content === "string" ?
|
|
48
49
|
common_utils_1.stringToBuffer(summaryObject.content, "utf8") : summaryObject.content;
|
|
49
50
|
const blobId = uuid_1.v4();
|
|
@@ -51,8 +52,8 @@ function convertCreateNewSummaryTreeToTreeAndBlobsCore(summary, blobs) {
|
|
|
51
52
|
blobs.set(blobId, contentBuffer);
|
|
52
53
|
break;
|
|
53
54
|
}
|
|
54
|
-
case
|
|
55
|
-
case
|
|
55
|
+
case protocol_definitions_1.SummaryType.Handle:
|
|
56
|
+
case protocol_definitions_1.SummaryType.Attachment: {
|
|
56
57
|
throw new Error(`No ${summaryObject.type} should be present for detached summary!`);
|
|
57
58
|
}
|
|
58
59
|
default: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createNewUtils.js","sourceRoot":"","sources":["../src/createNewUtils.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,+BAAkC;
|
|
1
|
+
{"version":3,"file":"createNewUtils.js","sourceRoot":"","sources":["../src/createNewUtils.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,+BAAkC;AAClC,+EAAgG;AAChG,+DAAmF;AACnF,+DAA+E;AAG/E;;GAEG;AACH,SAAgB,yCAAyC,CAAC,OAAqB,EAAE,MAAc;IAC3F,MAAM,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,WAAW,CAAiB,CAAC;IAClE,MAAM,kBAAkB,GAAG,kDAAmC,CAAC,eAAe,CAAC,CAAC;IAChF,MAAM,cAAc,GAAG,kBAAkB,CAAC,cAAc,CAAC;IACzD,MAAM,KAAK,GAAG,IAAI,GAAG,EAAuB,CAAC;IAC7C,MAAM,YAAY,GAAG,6CAA6C,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IACnF,YAAY,CAAC,EAAE,GAAG,MAAM,CAAC;IACzB,MAAM,iBAAiB,GAAsB;QACzC,YAAY;QACZ,KAAK;QACL,GAAG,EAAE,EAAE;QACP,cAAc;KACjB,CAAC;IAEF,OAAO,iBAAiB,CAAC;AAC7B,CAAC;AAfD,8FAeC;AAED,SAAS,6CAA6C,CAClD,OAAqB,EACrB,KAA+B;IAE/B,MAAM,QAAQ,GAAkB;QAC5B,KAAK,EAAE,EAAE;QACT,KAAK,EAAE,EAAE;QACT,OAAO,EAAE,EAAE;QACX,YAAY,EAAE,OAAO,CAAC,YAAY;KACrC,CAAC;IACF,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE;QACpB,MAAM,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAExC,QAAQ,aAAa,CAAC,IAAI,EAAE;YACxB,KAAK,kCAAW,CAAC,IAAI,CAAC,CAAC;gBACnB,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC;oBACf,6CAA6C,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;gBACxE,MAAM;aACT;YACD,KAAK,kCAAW,CAAC,IAAI,CAAC,CAAC;gBACnB,MAAM,aAAa,GAAG,OAAO,aAAa,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC;oBAC7D,6BAAc,CAAC,aAAa,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC;gBAC1E,MAAM,MAAM,GAAG,SAAI,EAAE,CAAC;gBACtB,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC;gBAC7B,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;gBACjC,MAAM;aACT;YACD,KAAK,kCAAW,CAAC,MAAM,CAAC;YACxB,KAAK,kCAAW,CAAC,UAAU,CAAC,CAAC;gBACzB,MAAM,IAAI,KAAK,CAAC,MAAM,aAAa,CAAC,IAAI,0CAA0C,CAAC,CAAC;aACvF;YACD,OAAO,CAAC,CAAC;gBACL,8BAAe,CAAC,aAAa,EAAE,qBAAsB,aAAqB,CAAC,IAAI,EAAE,CAAC,CAAC;aACtF;SACJ;KACJ;IACD,OAAO,QAAQ,CAAC;AACpB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { v4 as uuid } from \"uuid\";\nimport { ISnapshotTree, ISummaryTree, SummaryType } from \"@fluidframework/protocol-definitions\";\nimport { getDocAttributesFromProtocolSummary } from \"@fluidframework/driver-utils\";\nimport { stringToBuffer, unreachableCase } from \"@fluidframework/common-utils\";\nimport { ISnapshotContents } from \"./odspUtils\";\n\n/**\n * Converts a summary(ISummaryTree) taken in detached container to snapshot tree and blobs\n */\nexport function convertCreateNewSummaryTreeToTreeAndBlobs(summary: ISummaryTree, treeId: string): ISnapshotContents {\n const protocolSummary = summary.tree[\".protocol\"] as ISummaryTree;\n const documentAttributes = getDocAttributesFromProtocolSummary(protocolSummary);\n const sequenceNumber = documentAttributes.sequenceNumber;\n const blobs = new Map<string, ArrayBuffer>();\n const snapshotTree = convertCreateNewSummaryTreeToTreeAndBlobsCore(summary, blobs);\n snapshotTree.id = treeId;\n const snapshotTreeValue: ISnapshotContents = {\n snapshotTree,\n blobs,\n ops: [],\n sequenceNumber,\n };\n\n return snapshotTreeValue;\n}\n\nfunction convertCreateNewSummaryTreeToTreeAndBlobsCore(\n summary: ISummaryTree,\n blobs: Map<string, ArrayBuffer>,\n) {\n const treeNode: ISnapshotTree = {\n blobs: {},\n trees: {},\n commits: {},\n unreferenced: summary.unreferenced,\n };\n const keys = Object.keys(summary.tree);\n for (const key of keys) {\n const summaryObject = summary.tree[key];\n\n switch (summaryObject.type) {\n case SummaryType.Tree: {\n treeNode.trees[key] =\n convertCreateNewSummaryTreeToTreeAndBlobsCore(summaryObject, blobs);\n break;\n }\n case SummaryType.Blob: {\n const contentBuffer = typeof summaryObject.content === \"string\" ?\n stringToBuffer(summaryObject.content, \"utf8\") : summaryObject.content;\n const blobId = uuid();\n treeNode.blobs[key] = blobId;\n blobs.set(blobId, contentBuffer);\n break;\n }\n case SummaryType.Handle:\n case SummaryType.Attachment: {\n throw new Error(`No ${summaryObject.type} should be present for detached summary!`);\n }\n default: {\n unreachableCase(summaryObject, `Unknown tree type ${(summaryObject as any).type}`);\n }\n }\n }\n return treeNode;\n}\n"]}
|
package/dist/epochTracker.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ import { IOdspCache, INonPersistentCache, IPersistedFileCache } from "./odspCach
|
|
|
11
11
|
export declare type FetchType = "blob" | "createBlob" | "createFile" | "joinSession" | "ops" | "test" | "snapshotTree" | "treesLatest" | "uploadSummary" | "push" | "versions";
|
|
12
12
|
export declare type FetchTypeInternal = FetchType | "cache";
|
|
13
13
|
export declare const Odsp409Error = "Odsp409Error";
|
|
14
|
+
export declare const defaultCacheExpiryTimeoutMs: number;
|
|
14
15
|
/**
|
|
15
16
|
* This class is a wrapper around fetch calls. It adds epoch to the request made so that the
|
|
16
17
|
* server can match it with its epoch value in order to match the version.
|
|
@@ -52,7 +53,7 @@ export declare class EpochTracker implements IPersistedFileCache {
|
|
|
52
53
|
}, fetchType: FetchType, addInBody?: boolean): Promise<IOdspResponse<ArrayBuffer>>;
|
|
53
54
|
private addEpochInRequest;
|
|
54
55
|
private addParamInBody;
|
|
55
|
-
private
|
|
56
|
+
private formatClientCorrelationId;
|
|
56
57
|
protected validateEpochFromResponse(epochFromResponse: string | undefined, fetchType: FetchTypeInternal, fromCache?: boolean): void;
|
|
57
58
|
private checkForEpochError;
|
|
58
59
|
private checkForEpochErrorCore;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"epochTracker.d.ts","sourceRoot":"","sources":["../src/epochTracker.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"epochTracker.d.ts","sourceRoot":"","sources":["../src/epochTracker.ts"],"names":[],"mappings":"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"}
|
package/dist/epochTracker.js
CHANGED
|
@@ -4,10 +4,9 @@
|
|
|
4
4
|
* Licensed under the MIT License.
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.createOdspCacheAndTracker = exports.EpochTrackerWithRedemption = exports.EpochTracker = exports.Odsp409Error = void 0;
|
|
7
|
+
exports.createOdspCacheAndTracker = exports.EpochTrackerWithRedemption = exports.EpochTracker = exports.defaultCacheExpiryTimeoutMs = exports.Odsp409Error = void 0;
|
|
8
8
|
const uuid_1 = require("uuid");
|
|
9
9
|
const common_utils_1 = require("@fluidframework/common-utils");
|
|
10
|
-
const odsp_doclib_utils_1 = require("@fluidframework/odsp-doclib-utils");
|
|
11
10
|
const driver_utils_1 = require("@fluidframework/driver-utils");
|
|
12
11
|
const odsp_driver_definitions_1 = require("@fluidframework/odsp-driver-definitions");
|
|
13
12
|
const driver_definitions_1 = require("@fluidframework/driver-definitions");
|
|
@@ -15,6 +14,7 @@ const telemetry_utils_1 = require("@fluidframework/telemetry-utils");
|
|
|
15
14
|
const odspUtils_1 = require("./odspUtils");
|
|
16
15
|
const contracts_1 = require("./contracts");
|
|
17
16
|
exports.Odsp409Error = "Odsp409Error";
|
|
17
|
+
exports.defaultCacheExpiryTimeoutMs = 2 * 24 * 60 * 60 * 1000;
|
|
18
18
|
/**
|
|
19
19
|
* This class is a wrapper around fetch calls. It adds epoch to the request made so that the
|
|
20
20
|
* server can match it with its epoch value in order to match the version.
|
|
@@ -44,18 +44,39 @@ class EpochTracker {
|
|
|
44
44
|
});
|
|
45
45
|
}
|
|
46
46
|
async get(entry) {
|
|
47
|
+
var _a;
|
|
47
48
|
try {
|
|
49
|
+
// Return undefined so that the ops/snapshots are grabbed from the server instead of the cache
|
|
48
50
|
const value = await this.cache.get(this.fileEntryFromEntry(entry));
|
|
51
|
+
// Version mismatch between what the runtime expects and what it recieved.
|
|
52
|
+
// The cached value should not be used
|
|
49
53
|
if (value === undefined || value.version !== contracts_1.persistedCacheValueVersion) {
|
|
50
54
|
return undefined;
|
|
51
55
|
}
|
|
52
56
|
common_utils_1.assert(value.fluidEpoch !== undefined, 0x1dc /* "all entries have to have epoch" */);
|
|
53
57
|
if (this._fluidEpoch === undefined) {
|
|
54
58
|
this.setEpoch(value.fluidEpoch, true, "cache");
|
|
59
|
+
// Epoch mismatch, the cached value is considerably different from what the current state of
|
|
60
|
+
// the runtime and should not be used
|
|
55
61
|
}
|
|
56
62
|
else if (this._fluidEpoch !== value.fluidEpoch) {
|
|
57
63
|
return undefined;
|
|
58
64
|
}
|
|
65
|
+
// Expire the cached snapshot if it's older than the defaultCacheExpiryTimeoutMs and immediately
|
|
66
|
+
// expire all old caches that do not have cacheEntryTime
|
|
67
|
+
if (entry.type === odsp_driver_definitions_1.snapshotKey) {
|
|
68
|
+
const cacheTime = (_a = value.value) === null || _a === void 0 ? void 0 : _a.cacheEntryTime;
|
|
69
|
+
const currentTime = Date.now();
|
|
70
|
+
if (cacheTime === undefined || currentTime - cacheTime >= exports.defaultCacheExpiryTimeoutMs) {
|
|
71
|
+
this.logger.sendTelemetryEvent({
|
|
72
|
+
eventName: "odspVersionsCacheExpired",
|
|
73
|
+
duration: currentTime - cacheTime,
|
|
74
|
+
maxCacheAgeMs: exports.defaultCacheExpiryTimeoutMs,
|
|
75
|
+
});
|
|
76
|
+
await this.removeEntries();
|
|
77
|
+
return undefined;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
59
80
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
60
81
|
return value.value;
|
|
61
82
|
}
|
|
@@ -65,7 +86,13 @@ class EpochTracker {
|
|
|
65
86
|
}
|
|
66
87
|
}
|
|
67
88
|
async put(entry, value) {
|
|
89
|
+
var _a;
|
|
68
90
|
common_utils_1.assert(this._fluidEpoch !== undefined, 0x1dd /* "no epoch" */);
|
|
91
|
+
// For snapshots, the value should have the cacheEntryTime. This will be used to expire snapshots older
|
|
92
|
+
// than the defaultCacheExpiryTimeoutMs.
|
|
93
|
+
if (entry.type === odsp_driver_definitions_1.snapshotKey) {
|
|
94
|
+
value.cacheEntryTime = (_a = value.cacheEntryTime) !== null && _a !== void 0 ? _a : Date.now();
|
|
95
|
+
}
|
|
69
96
|
const data = {
|
|
70
97
|
value,
|
|
71
98
|
version: contracts_1.persistedCacheValueVersion,
|
|
@@ -107,14 +134,14 @@ class EpochTracker {
|
|
|
107
134
|
* @param addInBody - Pass True if caller wants to add epoch in post body.
|
|
108
135
|
*/
|
|
109
136
|
async fetchAndParseAsJSON(url, fetchOptions, fetchType, addInBody = false) {
|
|
110
|
-
const
|
|
137
|
+
const clientCorrelationId = this.formatClientCorrelationId();
|
|
111
138
|
// Add epoch in fetch request.
|
|
112
|
-
this.addEpochInRequest(fetchOptions, addInBody,
|
|
139
|
+
this.addEpochInRequest(fetchOptions, addInBody, clientCorrelationId);
|
|
113
140
|
let epochFromResponse;
|
|
114
141
|
return this.rateLimiter.schedule(async () => odspUtils_1.fetchAndParseAsJSONHelper(url, fetchOptions)).then((response) => {
|
|
115
142
|
epochFromResponse = response.headers.get("x-fluid-epoch");
|
|
116
143
|
this.validateEpochFromResponse(epochFromResponse, fetchType);
|
|
117
|
-
response.commonSpoHeaders = Object.assign(Object.assign({}, response.commonSpoHeaders), { "X-RequestStats":
|
|
144
|
+
response.commonSpoHeaders = Object.assign(Object.assign({}, response.commonSpoHeaders), { "X-RequestStats": clientCorrelationId });
|
|
118
145
|
return response;
|
|
119
146
|
}).catch(async (error) => {
|
|
120
147
|
// Get the server epoch from error in case we don't have it as if undefined we won't be able
|
|
@@ -125,8 +152,7 @@ class EpochTracker {
|
|
|
125
152
|
await this.checkForEpochError(error, epochFromResponse, fetchType);
|
|
126
153
|
throw error;
|
|
127
154
|
}).catch((error) => {
|
|
128
|
-
const fluidError = telemetry_utils_1.normalizeError(error, { props: {
|
|
129
|
-
// eslint-disable-next-line @typescript-eslint/no-throw-literal
|
|
155
|
+
const fluidError = telemetry_utils_1.normalizeError(error, { props: { XRequestStatsHeader: clientCorrelationId } });
|
|
130
156
|
throw fluidError;
|
|
131
157
|
});
|
|
132
158
|
}
|
|
@@ -138,14 +164,14 @@ class EpochTracker {
|
|
|
138
164
|
* @param addInBody - Pass True if caller wants to add epoch in post body.
|
|
139
165
|
*/
|
|
140
166
|
async fetchArray(url, fetchOptions, fetchType, addInBody = false) {
|
|
141
|
-
const
|
|
167
|
+
const clientCorrelationId = this.formatClientCorrelationId();
|
|
142
168
|
// Add epoch in fetch request.
|
|
143
|
-
this.addEpochInRequest(fetchOptions, addInBody,
|
|
169
|
+
this.addEpochInRequest(fetchOptions, addInBody, clientCorrelationId);
|
|
144
170
|
let epochFromResponse;
|
|
145
171
|
return this.rateLimiter.schedule(async () => odspUtils_1.fetchArray(url, fetchOptions)).then((response) => {
|
|
146
172
|
epochFromResponse = response.headers.get("x-fluid-epoch");
|
|
147
173
|
this.validateEpochFromResponse(epochFromResponse, fetchType);
|
|
148
|
-
response.commonSpoHeaders = Object.assign(Object.assign({}, response.commonSpoHeaders), { "X-RequestStats":
|
|
174
|
+
response.commonSpoHeaders = Object.assign(Object.assign({}, response.commonSpoHeaders), { "X-RequestStats": clientCorrelationId });
|
|
149
175
|
return response;
|
|
150
176
|
}).catch(async (error) => {
|
|
151
177
|
// Get the server epoch from error in case we don't have it as if undefined we won't be able
|
|
@@ -156,15 +182,14 @@ class EpochTracker {
|
|
|
156
182
|
await this.checkForEpochError(error, epochFromResponse, fetchType);
|
|
157
183
|
throw error;
|
|
158
184
|
}).catch((error) => {
|
|
159
|
-
const fluidError = telemetry_utils_1.normalizeError(error, { props: {
|
|
160
|
-
// eslint-disable-next-line @typescript-eslint/no-throw-literal
|
|
185
|
+
const fluidError = telemetry_utils_1.normalizeError(error, { props: { XRequestStatsHeader: clientCorrelationId } });
|
|
161
186
|
throw fluidError;
|
|
162
187
|
});
|
|
163
188
|
}
|
|
164
|
-
addEpochInRequest(fetchOptions, addInBody,
|
|
189
|
+
addEpochInRequest(fetchOptions, addInBody, clientCorrelationId) {
|
|
165
190
|
if (addInBody) {
|
|
166
191
|
const headers = {};
|
|
167
|
-
headers["X-RequestStats"] =
|
|
192
|
+
headers["X-RequestStats"] = clientCorrelationId;
|
|
168
193
|
if (this.fluidEpoch !== undefined) {
|
|
169
194
|
headers["x-fluid-epoch"] = this.fluidEpoch;
|
|
170
195
|
}
|
|
@@ -176,7 +201,7 @@ class EpochTracker {
|
|
|
176
201
|
common_utils_1.assert(fetchOptions.headers !== undefined, 0x282 /* "Headers should be present now" */);
|
|
177
202
|
fetchOptions.headers[key] = val;
|
|
178
203
|
};
|
|
179
|
-
addHeader("X-RequestStats",
|
|
204
|
+
addHeader("X-RequestStats", clientCorrelationId);
|
|
180
205
|
if (this.fluidEpoch !== undefined) {
|
|
181
206
|
addHeader("x-fluid-epoch", this.fluidEpoch);
|
|
182
207
|
}
|
|
@@ -199,11 +224,14 @@ class EpochTracker {
|
|
|
199
224
|
});
|
|
200
225
|
fetchOptions.body = formParams.join("\r\n");
|
|
201
226
|
}
|
|
202
|
-
|
|
227
|
+
formatClientCorrelationId() {
|
|
203
228
|
return `driverId=${this.driverId}, RequestNumber=${this.networkCallNumber++}`;
|
|
204
229
|
}
|
|
205
230
|
validateEpochFromResponse(epochFromResponse, fetchType, fromCache = false) {
|
|
206
|
-
this.checkForEpochErrorCore(epochFromResponse);
|
|
231
|
+
const error = this.checkForEpochErrorCore(epochFromResponse);
|
|
232
|
+
if (error !== undefined) {
|
|
233
|
+
throw error;
|
|
234
|
+
}
|
|
207
235
|
if (epochFromResponse !== undefined) {
|
|
208
236
|
if (this._fluidEpoch === undefined) {
|
|
209
237
|
this.setEpoch(epochFromResponse, fromCache, fetchType);
|
|
@@ -212,12 +240,9 @@ class EpochTracker {
|
|
|
212
240
|
}
|
|
213
241
|
async checkForEpochError(error, epochFromResponse, fetchType, fromCache = false) {
|
|
214
242
|
if (telemetry_utils_1.isFluidError(error) && error.errorType === driver_definitions_1.DriverErrorType.fileOverwrittenInStorage) {
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
}
|
|
219
|
-
catch (epochError) {
|
|
220
|
-
common_utils_1.assert(telemetry_utils_1.isValidLegacyError(epochError), 0x21f /* "epochError expected to be thrown by throwOdspNetworkError and of known type" */);
|
|
243
|
+
const epochError = this.checkForEpochErrorCore(epochFromResponse);
|
|
244
|
+
if (epochError !== undefined) {
|
|
245
|
+
common_utils_1.assert(telemetry_utils_1.isFluidError(epochError), 0x21f /* "epochError expected to be thrown by throwOdspNetworkError and of known type" */);
|
|
221
246
|
epochError.addTelemetryProperties({
|
|
222
247
|
fromCache,
|
|
223
248
|
clientEpoch: this.fluidEpoch,
|
|
@@ -226,7 +251,6 @@ class EpochTracker {
|
|
|
226
251
|
this.logger.sendErrorEvent({ eventName: "fileOverwrittenInStorage" }, epochError);
|
|
227
252
|
// If the epoch mismatches, then clear all entries for such file entry from cache.
|
|
228
253
|
await this.removeEntries();
|
|
229
|
-
// eslint-disable-next-line @typescript-eslint/no-throw-literal
|
|
230
254
|
throw epochError;
|
|
231
255
|
}
|
|
232
256
|
// If it was categorized as epoch error but the epoch returned in response matches with the client epoch
|
|
@@ -240,7 +264,9 @@ class EpochTracker {
|
|
|
240
264
|
// initializes this value. Sometimes response does not contain epoch as it is still in
|
|
241
265
|
// implementation phase at server side. In that case also, don't compare it with our epoch value.
|
|
242
266
|
if (this.fluidEpoch && epochFromResponse && (this.fluidEpoch !== epochFromResponse)) {
|
|
243
|
-
|
|
267
|
+
// This is similar in nature to how fluidEpochMismatchError (409) is handled.
|
|
268
|
+
// Difference - client detected mismatch, instead of server detecting it.
|
|
269
|
+
return new driver_utils_1.NonRetryableError("epochMismatch", "Epoch mismatch", driver_definitions_1.DriverErrorType.fileOverwrittenInStorage);
|
|
244
270
|
}
|
|
245
271
|
}
|
|
246
272
|
fileEntryFromEntry(entry) {
|