@fluid-tools/fetch-tool 2.90.0-378676 → 2.91.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/dist/fluidFetchSharePoint.d.ts.map +1 -1
- package/dist/fluidFetchSharePoint.js +0 -1
- package/dist/fluidFetchSharePoint.js.map +1 -1
- package/dist/fluidFetchSnapshot.js +1 -1
- package/dist/fluidFetchSnapshot.js.map +1 -1
- package/lib/fluidFetchSharePoint.d.ts.map +1 -1
- package/lib/fluidFetchSharePoint.js +0 -1
- package/lib/fluidFetchSharePoint.js.map +1 -1
- package/lib/fluidFetchSnapshot.js +1 -1
- package/lib/fluidFetchSnapshot.js.map +1 -1
- package/package.json +19 -19
- package/src/fluidFetchSharePoint.ts +0 -1
- package/src/fluidFetchSnapshot.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fluidFetchSharePoint.d.ts","sourceRoot":"","sources":["../src/fluidFetchSharePoint.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,OAAO,EACN,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,cAAc,EAMnB,MAAM,4CAA4C,CAAC;AASpD,eAAO,MAAM,qBAAqB,EAAE,mBAUnC,CAAC;AAaF,wBAAsB,cAAc,CAAC,CAAC,EACrC,QAAQ,EAAE,CAAC,eAAe,EAAE,oBAAoB,KAAK,OAAO,CAAC,CAAC,CAAC,EAC/D,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,mBAAmB,EACjC,gBAAgB,UAAQ,GACtB,OAAO,CAAC,CAAC,CAAC,CAmDZ;AA6BD,wBAAsB,kBAAkB,CACvC,MAAM,EAAE,MAAM,EACd,kBAAkB,EAAE,MAAM,EAC1B,OAAO,EAAE,OAAO,GACd,OAAO,CAAC,cAAc,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"fluidFetchSharePoint.d.ts","sourceRoot":"","sources":["../src/fluidFetchSharePoint.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,OAAO,EACN,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,cAAc,EAMnB,MAAM,4CAA4C,CAAC;AASpD,eAAO,MAAM,qBAAqB,EAAE,mBAUnC,CAAC;AAaF,wBAAsB,cAAc,CAAC,CAAC,EACrC,QAAQ,EAAE,CAAC,eAAe,EAAE,oBAAoB,KAAK,OAAO,CAAC,CAAC,CAAC,EAC/D,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,mBAAmB,EACjC,gBAAgB,UAAQ,GACtB,OAAO,CAAC,CAAC,CAAC,CAmDZ;AA6BD,wBAAsB,kBAAkB,CACvC,MAAM,EAAE,MAAM,EACd,kBAAkB,EAAE,MAAM,EAC1B,OAAO,EAAE,OAAO,GACd,OAAO,CAAC,cAAc,EAAE,CAAC,CAkC3B;AAED,wBAAsB,uBAAuB,CAC5C,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,GACV,OAAO,CAAC,cAAc,CAAC,CAOzB"}
|
|
@@ -105,7 +105,6 @@ async function getSharepointFiles(server, serverRelativePath, recurse) {
|
|
|
105
105
|
else {
|
|
106
106
|
files.push(fileInfo);
|
|
107
107
|
}
|
|
108
|
-
// eslint-disable-next-line no-constant-condition
|
|
109
108
|
while (true) {
|
|
110
109
|
const folderInfo = pendingFolder.shift();
|
|
111
110
|
if (!folderInfo) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fluidFetchSharePoint.js","sourceRoot":"","sources":["../src/fluidFetchSharePoint.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 {\n\tInteractiveBrowserCredential,\n\tuseIdentityPlugin,\n\ttype AuthenticationRecord,\n} from \"@azure/identity\";\nimport { cachePersistencePlugin } from \"@azure/identity-cache-persistence\";\nimport { DriverErrorTypes } from \"@fluidframework/driver-definitions/internal\";\nimport {\n\ttype IPublicClientConfig,\n\ttype IOdspAuthRequestInfo,\n\ttype IOdspDriveItem,\n\tgetChildrenByDriveItem,\n\tgetDriveItemByServerRelativePath,\n\tgetDriveItemFromDriveAndItem,\n\tgetAadTenant,\n\tgetOdspScope,\n} from \"@fluidframework/odsp-doclib-utils/internal\";\n\nimport { loginHint } from \"./fluidFetchArgs.js\";\n\n// Note: the following page may be helpful for debugging auth issues:\n// https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/identity/identity/TROUBLESHOOTING.md\n// See e.g. the section on setting 'AZURE_LOG_LEVEL'.\nuseIdentityPlugin(cachePersistencePlugin);\n\nexport const fetchToolClientConfig: IPublicClientConfig = {\n\tget clientId(): string {\n\t\tconst clientId = process.env.fetch__tool__clientId;\n\t\tif (clientId === undefined) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Client ID environment variable not set: fetch__tool__clientId. Use the getkeys tool to populate it.\",\n\t\t\t);\n\t\t}\n\t\treturn clientId;\n\t},\n};\n\n// Local token cache for resolveWrapper.\n// @azure/identity-cache-persistence does not behave well in response to large numbers of parallel requests, which can happen for documents\n// with lots of blobs. We work around this for now by including a simple in-memory cache.\n// See more information here:\n// https://github.com/Azure/azure-sdk-for-js/issues/31307\nconst tokensByServer = new Map<string, string>();\n\n// If the persisted cache has multiple accounts, InteractiveBrowserCredential ignores it unless it is passed an explicit authentication record.\n// We keep the auth record around for a single run in memory, so that at worst we only have to authenticate once per server/user.\nconst authRecordPerServer = new Map<string, AuthenticationRecord | undefined>();\n\nexport async function resolveWrapper<T>(\n\tcallback: (authRequestInfo: IOdspAuthRequestInfo) => Promise<T>,\n\tserver: string,\n\tclientConfig: IPublicClientConfig,\n\tforceTokenReauth = false,\n): Promise<T> {\n\ttry {\n\t\tconst authenticationRecord = authRecordPerServer.get(server);\n\t\tconst credential = new InteractiveBrowserCredential({\n\t\t\tclientId: fetchToolClientConfig.clientId,\n\t\t\ttenantId: getAadTenant(server),\n\t\t\t// NOTE: fetch-tool flows using multiple sets of user credentials haven't been well-tested.\n\t\t\t// Some of the @azure/identity docs suggest we may need to manage authentication records and choose\n\t\t\t// which one to use explicitly here if we have such scenarios.\n\t\t\t// If we start doing this, it may be worth considering using disableAutomaticAuthentication here so we\n\t\t\t// have better control over when interactive auth may be triggered.\n\t\t\t// For now, fetch-tool doesn't work against personal accounts anyway so the only flow that might necessitate this\n\t\t\t// would be grabbing documents using several identities (e.g. test accounts we use for stress testing).\n\t\t\t// In that case, a simple workaround is to delete the cache that @azure/identity uses before running the tool.\n\t\t\t// See docs on `tokenCachePersistenceOptions.name` for information on where this cache is stored.\n\t\t\tloginHint,\n\t\t\tauthenticationRecord,\n\t\t\ttokenCachePersistenceOptions: {\n\t\t\t\tenabled: true,\n\t\t\t\tname: \"fetch-tool\",\n\t\t\t},\n\t\t});\n\n\t\tconst scope = getOdspScope(server);\n\t\tif (authenticationRecord === undefined) {\n\t\t\t// Cache this authentication record for subsequent token requests.\n\t\t\tauthRecordPerServer.set(server, await credential.authenticate(scope));\n\t\t}\n\t\tlet cachedToken = tokensByServer.get(server);\n\t\tif (cachedToken === undefined || forceTokenReauth) {\n\t\t\tconst result = await credential.getToken(scope);\n\t\t\tcachedToken = result.token;\n\t\t\ttokensByServer.set(server, cachedToken);\n\t\t}\n\n\t\treturn await callback({\n\t\t\taccessToken: cachedToken,\n\t\t\trefreshTokenFn: async () => {\n\t\t\t\tawait credential.authenticate(scope);\n\t\t\t\tconst { token } = await credential.getToken(scope);\n\t\t\t\ttokensByServer.set(server, token);\n\t\t\t\treturn token;\n\t\t\t},\n\t\t});\n\t} catch (e: any) {\n\t\tif (e.errorType === DriverErrorTypes.authorizationError && !forceTokenReauth) {\n\t\t\t// Re-auth\n\t\t\treturn resolveWrapper<T>(callback, server, clientConfig, true);\n\t\t}\n\t\tthrow e;\n\t}\n}\n\nasync function resolveDriveItemByServerRelativePath(\n\tserver: string,\n\tserverRelativePath: string,\n\tclientConfig: IPublicClientConfig,\n): Promise<IOdspDriveItem> {\n\treturn resolveWrapper<IOdspDriveItem>(\n\t\t// eslint-disable-next-line @typescript-eslint/promise-function-async\n\t\t(authRequestInfo) =>\n\t\t\tgetDriveItemByServerRelativePath(server, serverRelativePath, authRequestInfo, false),\n\t\tserver,\n\t\tclientConfig,\n\t);\n}\n\nasync function resolveChildrenByDriveItem(\n\tserver: string,\n\tfolderDriveItem: IOdspDriveItem,\n\tclientConfig: IPublicClientConfig,\n): Promise<IOdspDriveItem[]> {\n\treturn resolveWrapper<IOdspDriveItem[]>(\n\t\t// eslint-disable-next-line @typescript-eslint/promise-function-async\n\t\t(authRequestInfo) => getChildrenByDriveItem(folderDriveItem, server, authRequestInfo),\n\t\tserver,\n\t\tclientConfig,\n\t);\n}\n\nexport async function getSharepointFiles(\n\tserver: string,\n\tserverRelativePath: string,\n\trecurse: boolean,\n): Promise<IOdspDriveItem[]> {\n\tconst fileInfo = await resolveDriveItemByServerRelativePath(\n\t\tserver,\n\t\tserverRelativePath,\n\t\tfetchToolClientConfig,\n\t);\n\tconsole.log(fileInfo);\n\tconst pendingFolder: { path: string; folder: IOdspDriveItem }[] = [];\n\tconst files: IOdspDriveItem[] = [];\n\tif (fileInfo.isFolder) {\n\t\tpendingFolder.push({ path: serverRelativePath, folder: fileInfo });\n\t} else {\n\t\tfiles.push(fileInfo);\n\t}\n\n\t// eslint-disable-next-line no-constant-condition\n\twhile (true) {\n\t\tconst folderInfo = pendingFolder.shift();\n\t\tif (!folderInfo) {\n\t\t\tbreak;\n\t\t}\n\t\tconst { path, folder } = folderInfo;\n\t\tconst children = await resolveChildrenByDriveItem(server, folder, fetchToolClientConfig);\n\t\tfor (const child of children) {\n\t\t\tconst childPath = `${path}/${child.name}`;\n\t\t\tif (child.isFolder) {\n\t\t\t\tif (recurse) {\n\t\t\t\t\tpendingFolder.push({ path: childPath, folder: child });\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfiles.push(child);\n\t\t\t}\n\t\t}\n\t}\n\treturn files;\n}\n\nexport async function getSingleSharePointFile(\n\tserver: string,\n\tdrive: string,\n\titem: string,\n): Promise<IOdspDriveItem> {\n\treturn resolveWrapper<IOdspDriveItem>(\n\t\t// eslint-disable-next-line @typescript-eslint/promise-function-async\n\t\t(authRequestInfo) => getDriveItemFromDriveAndItem(server, drive, item, authRequestInfo),\n\t\tserver,\n\t\tfetchToolClientConfig,\n\t);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"fluidFetchSharePoint.js","sourceRoot":"","sources":["../src/fluidFetchSharePoint.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 {\n\tInteractiveBrowserCredential,\n\tuseIdentityPlugin,\n\ttype AuthenticationRecord,\n} from \"@azure/identity\";\nimport { cachePersistencePlugin } from \"@azure/identity-cache-persistence\";\nimport { DriverErrorTypes } from \"@fluidframework/driver-definitions/internal\";\nimport {\n\ttype IPublicClientConfig,\n\ttype IOdspAuthRequestInfo,\n\ttype IOdspDriveItem,\n\tgetChildrenByDriveItem,\n\tgetDriveItemByServerRelativePath,\n\tgetDriveItemFromDriveAndItem,\n\tgetAadTenant,\n\tgetOdspScope,\n} from \"@fluidframework/odsp-doclib-utils/internal\";\n\nimport { loginHint } from \"./fluidFetchArgs.js\";\n\n// Note: the following page may be helpful for debugging auth issues:\n// https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/identity/identity/TROUBLESHOOTING.md\n// See e.g. the section on setting 'AZURE_LOG_LEVEL'.\nuseIdentityPlugin(cachePersistencePlugin);\n\nexport const fetchToolClientConfig: IPublicClientConfig = {\n\tget clientId(): string {\n\t\tconst clientId = process.env.fetch__tool__clientId;\n\t\tif (clientId === undefined) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Client ID environment variable not set: fetch__tool__clientId. Use the getkeys tool to populate it.\",\n\t\t\t);\n\t\t}\n\t\treturn clientId;\n\t},\n};\n\n// Local token cache for resolveWrapper.\n// @azure/identity-cache-persistence does not behave well in response to large numbers of parallel requests, which can happen for documents\n// with lots of blobs. We work around this for now by including a simple in-memory cache.\n// See more information here:\n// https://github.com/Azure/azure-sdk-for-js/issues/31307\nconst tokensByServer = new Map<string, string>();\n\n// If the persisted cache has multiple accounts, InteractiveBrowserCredential ignores it unless it is passed an explicit authentication record.\n// We keep the auth record around for a single run in memory, so that at worst we only have to authenticate once per server/user.\nconst authRecordPerServer = new Map<string, AuthenticationRecord | undefined>();\n\nexport async function resolveWrapper<T>(\n\tcallback: (authRequestInfo: IOdspAuthRequestInfo) => Promise<T>,\n\tserver: string,\n\tclientConfig: IPublicClientConfig,\n\tforceTokenReauth = false,\n): Promise<T> {\n\ttry {\n\t\tconst authenticationRecord = authRecordPerServer.get(server);\n\t\tconst credential = new InteractiveBrowserCredential({\n\t\t\tclientId: fetchToolClientConfig.clientId,\n\t\t\ttenantId: getAadTenant(server),\n\t\t\t// NOTE: fetch-tool flows using multiple sets of user credentials haven't been well-tested.\n\t\t\t// Some of the @azure/identity docs suggest we may need to manage authentication records and choose\n\t\t\t// which one to use explicitly here if we have such scenarios.\n\t\t\t// If we start doing this, it may be worth considering using disableAutomaticAuthentication here so we\n\t\t\t// have better control over when interactive auth may be triggered.\n\t\t\t// For now, fetch-tool doesn't work against personal accounts anyway so the only flow that might necessitate this\n\t\t\t// would be grabbing documents using several identities (e.g. test accounts we use for stress testing).\n\t\t\t// In that case, a simple workaround is to delete the cache that @azure/identity uses before running the tool.\n\t\t\t// See docs on `tokenCachePersistenceOptions.name` for information on where this cache is stored.\n\t\t\tloginHint,\n\t\t\tauthenticationRecord,\n\t\t\ttokenCachePersistenceOptions: {\n\t\t\t\tenabled: true,\n\t\t\t\tname: \"fetch-tool\",\n\t\t\t},\n\t\t});\n\n\t\tconst scope = getOdspScope(server);\n\t\tif (authenticationRecord === undefined) {\n\t\t\t// Cache this authentication record for subsequent token requests.\n\t\t\tauthRecordPerServer.set(server, await credential.authenticate(scope));\n\t\t}\n\t\tlet cachedToken = tokensByServer.get(server);\n\t\tif (cachedToken === undefined || forceTokenReauth) {\n\t\t\tconst result = await credential.getToken(scope);\n\t\t\tcachedToken = result.token;\n\t\t\ttokensByServer.set(server, cachedToken);\n\t\t}\n\n\t\treturn await callback({\n\t\t\taccessToken: cachedToken,\n\t\t\trefreshTokenFn: async () => {\n\t\t\t\tawait credential.authenticate(scope);\n\t\t\t\tconst { token } = await credential.getToken(scope);\n\t\t\t\ttokensByServer.set(server, token);\n\t\t\t\treturn token;\n\t\t\t},\n\t\t});\n\t} catch (e: any) {\n\t\tif (e.errorType === DriverErrorTypes.authorizationError && !forceTokenReauth) {\n\t\t\t// Re-auth\n\t\t\treturn resolveWrapper<T>(callback, server, clientConfig, true);\n\t\t}\n\t\tthrow e;\n\t}\n}\n\nasync function resolveDriveItemByServerRelativePath(\n\tserver: string,\n\tserverRelativePath: string,\n\tclientConfig: IPublicClientConfig,\n): Promise<IOdspDriveItem> {\n\treturn resolveWrapper<IOdspDriveItem>(\n\t\t// eslint-disable-next-line @typescript-eslint/promise-function-async\n\t\t(authRequestInfo) =>\n\t\t\tgetDriveItemByServerRelativePath(server, serverRelativePath, authRequestInfo, false),\n\t\tserver,\n\t\tclientConfig,\n\t);\n}\n\nasync function resolveChildrenByDriveItem(\n\tserver: string,\n\tfolderDriveItem: IOdspDriveItem,\n\tclientConfig: IPublicClientConfig,\n): Promise<IOdspDriveItem[]> {\n\treturn resolveWrapper<IOdspDriveItem[]>(\n\t\t// eslint-disable-next-line @typescript-eslint/promise-function-async\n\t\t(authRequestInfo) => getChildrenByDriveItem(folderDriveItem, server, authRequestInfo),\n\t\tserver,\n\t\tclientConfig,\n\t);\n}\n\nexport async function getSharepointFiles(\n\tserver: string,\n\tserverRelativePath: string,\n\trecurse: boolean,\n): Promise<IOdspDriveItem[]> {\n\tconst fileInfo = await resolveDriveItemByServerRelativePath(\n\t\tserver,\n\t\tserverRelativePath,\n\t\tfetchToolClientConfig,\n\t);\n\tconsole.log(fileInfo);\n\tconst pendingFolder: { path: string; folder: IOdspDriveItem }[] = [];\n\tconst files: IOdspDriveItem[] = [];\n\tif (fileInfo.isFolder) {\n\t\tpendingFolder.push({ path: serverRelativePath, folder: fileInfo });\n\t} else {\n\t\tfiles.push(fileInfo);\n\t}\n\n\twhile (true) {\n\t\tconst folderInfo = pendingFolder.shift();\n\t\tif (!folderInfo) {\n\t\t\tbreak;\n\t\t}\n\t\tconst { path, folder } = folderInfo;\n\t\tconst children = await resolveChildrenByDriveItem(server, folder, fetchToolClientConfig);\n\t\tfor (const child of children) {\n\t\t\tconst childPath = `${path}/${child.name}`;\n\t\t\tif (child.isFolder) {\n\t\t\t\tif (recurse) {\n\t\t\t\t\tpendingFolder.push({ path: childPath, folder: child });\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfiles.push(child);\n\t\t\t}\n\t\t}\n\t}\n\treturn files;\n}\n\nexport async function getSingleSharePointFile(\n\tserver: string,\n\tdrive: string,\n\titem: string,\n): Promise<IOdspDriveItem> {\n\treturn resolveWrapper<IOdspDriveItem>(\n\t\t// eslint-disable-next-line @typescript-eslint/promise-function-async\n\t\t(authRequestInfo) => getDriveItemFromDriveAndItem(server, drive, item, authRequestInfo),\n\t\tserver,\n\t\tfetchToolClientConfig,\n\t);\n}\n"]}
|
|
@@ -256,7 +256,7 @@ async function fluidFetchSnapshot(documentService, saveDir) {
|
|
|
256
256
|
console.log("No snapshot tree");
|
|
257
257
|
}
|
|
258
258
|
else {
|
|
259
|
-
// eslint-disable-next-line @typescript-eslint/
|
|
259
|
+
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- intentional behavior
|
|
260
260
|
if (blobsToDump === undefined) {
|
|
261
261
|
blobsToDump = await fetchBlobsFromVersion(storage, version);
|
|
262
262
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fluidFetchSnapshot.js","sourceRoot":"","sources":["../src/fluidFetchSnapshot.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 fs from \"fs\";\nimport util from \"util\";\n\nimport { bufferToString, stringToBuffer } from \"@fluid-internal/client-utils\";\nimport type {\n\tIDocumentService,\n\tIDocumentStorageService,\n\tISnapshotTree,\n\tIVersion,\n} from \"@fluidframework/driver-definitions/internal\";\n\nimport { formatNumber } from \"./fluidAnalyzeMessages.js\";\nimport {\n\tdumpSnapshotStats,\n\tdumpSnapshotTrees,\n\tdumpSnapshotVersions,\n\tparamActualFormatting,\n\tparamNumSnapshotVersions,\n\tparamSnapshotVersionIndex,\n} from \"./fluidFetchArgs.js\";\nimport { latestVersionsId } from \"./fluidFetchInit.js\";\n\ninterface ISnapshotInfo {\n\tblobCountNew: number;\n\tblobCount: number;\n\tsize: number;\n\tsizeNew: number;\n}\n\ntype IFetchedData = IFetchedBlob | IFetchedTree;\n\ninterface IFetchedBlob {\n\ttreePath: string;\n\tfilename: string;\n\tblobId: string;\n\tblob: Promise<ArrayBufferLike | undefined>;\n\treused: boolean;\n}\n\ninterface IFetchedTree {\n\ttreePath: string;\n\tblobId: string;\n\tfilename: string;\n\tblob: ArrayBufferLike;\n\n\treused: false;\n\n\tpatched: boolean;\n}\n\nfunction isFetchedTree(fetchedData: IFetchedData): fetchedData is IFetchedTree {\n\treturn \"patched\" in fetchedData;\n}\n\nconst blobCache = new Map<string, Promise<ArrayBufferLike>>();\nlet blobCachePrevious = new Map<string, Promise<ArrayBufferLike>>();\nlet blobCacheCurrent = new Map<string, Promise<ArrayBufferLike>>();\n\nfunction fetchBlobs(\n\tprefix: string,\n\ttree: ISnapshotTree,\n\tstorage: IDocumentStorageService,\n\tblobIdMap: Map<string, number>,\n): IFetchedBlob[] {\n\tconst result: IFetchedBlob[] = [];\n\tfor (const [item, blobId] of Object.entries(tree.blobs)) {\n\t\tconst treePath = `${prefix}${item}`;\n\t\tif (blobId !== null) {\n\t\t\tlet reused = true;\n\t\t\tlet blob = blobCachePrevious.get(blobId);\n\t\t\tif (!blob) {\n\t\t\t\treused = false;\n\t\t\t\tblob = blobCache.get(blobId);\n\t\t\t\tif (blob === undefined) {\n\t\t\t\t\tblob = storage.readBlob(blobId);\n\t\t\t\t\tblobCache.set(blobId, blob);\n\t\t\t\t}\n\t\t\t}\n\t\t\tblobCacheCurrent.set(blobId, blob);\n\n\t\t\t// Use the blobIdMap to assign a number for each unique blob\n\t\t\t// and use it as a prefix for files to avoid case-insensitive fs\n\t\t\tlet index = blobIdMap.get(blobId);\n\t\t\tif (index === undefined) {\n\t\t\t\tindex = blobIdMap.size;\n\t\t\t\tblobIdMap.set(blobId, index);\n\t\t\t}\n\t\t\tconst filename = `${index}-${blobId}`;\n\t\t\tresult.push({ treePath, blobId, blob, reused, filename });\n\n\t\t\t// patch the tree so that we can write it out to reference the file\n\t\t\ttree.blobs[item] = filename;\n\t\t}\n\t}\n\treturn result;\n}\n\nfunction createTreeBlob(tree: ISnapshotTree, prefix: string, patched: boolean): IFetchedTree {\n\tconst id = tree.id ?? \"original\";\n\tconst blob = stringToBuffer(JSON.stringify(tree), \"utf8\");\n\tconst filename = patched ? \"tree\" : `tree-${id}`;\n\tconst treePath = `${prefix}${filename}`;\n\treturn { treePath, blobId: \"original tree $id\", filename, blob, patched, reused: false };\n}\n\nasync function fetchBlobsFromSnapshotTree(\n\tstorage: IDocumentStorageService,\n\ttree: ISnapshotTree,\n\tprefix: string = \"/\",\n\tparentBlobIdMap?: Map<string, number>,\n): Promise<IFetchedData[]> {\n\tconst isTopLevel = !parentBlobIdMap;\n\tif (isTopLevel && dumpSnapshotTrees) {\n\t\tconsole.log(tree);\n\t}\n\n\tif (prefix === \"/\") {\n\t\tblobCachePrevious = blobCacheCurrent;\n\t\tblobCacheCurrent = new Map<string, Promise<ArrayBufferLike>>();\n\t}\n\n\t// Create the tree info before fetching blobs (which will modify it)\n\tlet topLevelBlob: IFetchedTree | undefined;\n\tif (isTopLevel) {\n\t\ttopLevelBlob = createTreeBlob(tree, prefix, false);\n\t}\n\n\tconst blobIdMap = parentBlobIdMap ?? new Map<string, number>();\n\tlet result: IFetchedData[] = fetchBlobs(prefix, tree, storage, blobIdMap);\n\n\tfor (const [subtreeId, subtree] of Object.entries(tree.trees)) {\n\t\tconst dataStoreBlobs = await fetchBlobsFromSnapshotTree(\n\t\t\tstorage,\n\t\t\tsubtree,\n\t\t\t`${prefix}${subtreeId}/`,\n\t\t\tblobIdMap,\n\t\t);\n\t\tresult = result.concat(dataStoreBlobs);\n\t}\n\n\tif (topLevelBlob) {\n\t\tresult.push(topLevelBlob);\n\t\tresult.push(createTreeBlob(tree, prefix, true));\n\t}\n\treturn result;\n}\n\nfunction getDumpFetchedData(fetchedData: IFetchedData[]): IFetchedData[] {\n\tconst sorted = fetchedData.sort((a, b) => a.treePath.localeCompare(b.treePath));\n\treturn sorted.filter((item) => !isFetchedTree(item) || !item.patched);\n}\n\nasync function dumpSnapshotTreeVerbose(\n\tname: string,\n\tfetchedData: IFetchedData[],\n): Promise<void> {\n\tlet size = 0;\n\tconst sorted = getDumpFetchedData(fetchedData);\n\n\tlet nameLength = 10;\n\tfor (const item of sorted) {\n\t\tnameLength = Math.max(nameLength, item.treePath.length);\n\t}\n\n\tconsole.log(\"\");\n\tconsole.log(`${\"Blob Path\".padEnd(nameLength)} | Reused | Bytes`);\n\tconsole.log(\"-\".repeat(nameLength + 26));\n\tfor (const item of sorted) {\n\t\tconst buffer = await item.blob;\n\t\tif (buffer === undefined) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst blob = bufferToString(buffer, \"utf8\");\n\t\tconsole.log(\n\t\t\t`${item.treePath.padEnd(nameLength)} | ${item.reused ? \"X\" : \" \"} | ${formatNumber(\n\t\t\t\tblob.length,\n\t\t\t).padStart(10)}`,\n\t\t);\n\t\tsize += blob.length;\n\t}\n\n\tconsole.log(\"-\".repeat(nameLength + 26));\n\tconsole.log(\n\t\t`${\"Total snapshot size\".padEnd(nameLength)} | | ${formatNumber(size).padStart(\n\t\t\t10,\n\t\t)}`,\n\t);\n}\n\nasync function dumpSnapshotTree(\n\tname: string,\n\tfetchedData: IFetchedData[],\n): Promise<ISnapshotInfo> {\n\tlet size = 0;\n\tlet sizeNew = 0;\n\tlet blobCountNew = 0;\n\tconst sorted = getDumpFetchedData(fetchedData);\n\n\tfor (const item of sorted) {\n\t\tconst buffer = await item.blob;\n\t\tif (buffer === undefined) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst blob = bufferToString(buffer, \"utf8\");\n\t\tif (!item.reused) {\n\t\t\tsizeNew += blob.length;\n\t\t\tblobCountNew++;\n\t\t}\n\t\tsize += blob.length;\n\t}\n\n\treturn { blobCountNew, blobCount: sorted.length, size, sizeNew };\n}\n\nasync function saveSnapshot(\n\tname: string,\n\tfetchedData: IFetchedData[],\n\tsaveDir: string,\n): Promise<void> {\n\tconst outDir = `${saveDir}/${name}/`;\n\tconst mkdir = util.promisify(fs.mkdir);\n\n\tawait mkdir(`${outDir}/decoded`, { recursive: true });\n\tawait Promise.all(\n\t\tfetchedData.map(async (item) => {\n\t\t\tconst buffer = await item.blob;\n\t\t\tif (buffer === undefined) {\n\t\t\t\tconsole.error(`ERROR: Unable to get data for blob ${item.blobId}`);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (!isFetchedTree(item)) {\n\t\t\t\t// Just write the data as is.\n\t\t\t\tfs.writeFileSync(`${outDir}/${item.filename}`, Buffer.from(buffer));\n\n\t\t\t\t// we assume that the buffer is utf8 here, which currently is true for\n\t\t\t\t// all of our snapshot blobs. It doesn't necessary be true in the future\n\t\t\t\tlet decoded = bufferToString(buffer, \"utf8\");\n\t\t\t\ttry {\n\t\t\t\t\tif (!paramActualFormatting) {\n\t\t\t\t\t\tdecoded = JSON.stringify(JSON.parse(decoded), undefined, 2);\n\t\t\t\t\t}\n\t\t\t\t} catch (e) {\n\t\t\t\t\t// TODO: document why we are ignoring the error here\n\t\t\t\t}\n\t\t\t\tfs.writeFileSync(`${outDir}/decoded/${item.filename}.json`, decoded);\n\t\t\t} else {\n\t\t\t\t// Write out same data for tree decoded or not, except for formatting\n\t\t\t\tconst treeString = bufferToString(buffer, \"utf8\");\n\t\t\t\tfs.writeFileSync(`${outDir}/${item.filename}.json`, treeString);\n\t\t\t\tfs.writeFileSync(\n\t\t\t\t\t`${outDir}/decoded/${item.filename}.json`,\n\t\t\t\t\tparamActualFormatting\n\t\t\t\t\t\t? treeString\n\t\t\t\t\t\t: JSON.stringify(JSON.parse(treeString), undefined, 2),\n\t\t\t\t);\n\t\t\t}\n\t\t}),\n\t);\n}\n\nasync function fetchBlobsFromVersion(\n\tstorage: IDocumentStorageService,\n\tversion: IVersion,\n): Promise<IFetchedData[]> {\n\tconst tree = await reportErrors(\n\t\t`getSnapshotTree ${version.id}`,\n\t\tstorage.getSnapshotTree(version),\n\t);\n\tif (!tree) {\n\t\tthrow new Error(\"Failed to load snapshot tree\");\n\t}\n\treturn fetchBlobsFromSnapshotTree(storage, tree);\n}\n\nasync function reportErrors<T>(message: string, res: Promise<T>): Promise<T> {\n\ttry {\n\t\treturn await res;\n\t} catch (error) {\n\t\tconsole.error(`Error calling ${message}`);\n\t\tthrow error;\n\t}\n}\n\nexport async function fluidFetchSnapshot(\n\tdocumentService?: IDocumentService,\n\tsaveDir?: string,\n): Promise<void> {\n\tif (\n\t\t!dumpSnapshotStats &&\n\t\t!dumpSnapshotTrees &&\n\t\t!dumpSnapshotVersions &&\n\t\tsaveDir === undefined\n\t) {\n\t\treturn;\n\t}\n\n\t// --local mode - do not connect to storage.\n\t// For now, bail out early.\n\t// In future, separate download from analyzes parts and allow offline analyzes\n\tif (!documentService) {\n\t\treturn;\n\t}\n\n\tconsole.log(\"\\n\");\n\n\tconst storage = await documentService.connectToStorage();\n\n\tlet version: IVersion | undefined;\n\tconst versions = await reportErrors(\n\t\t`getVersions ${latestVersionsId}`,\n\t\tstorage.getVersions(latestVersionsId, paramNumSnapshotVersions),\n\t);\n\tif (dumpSnapshotVersions) {\n\t\tconsole.log(\"Snapshot versions\");\n\t\tconsole.log(versions);\n\t}\n\n\tlet blobsToDump: IFetchedData[] | undefined;\n\tif (paramSnapshotVersionIndex !== undefined) {\n\t\tversion = versions[paramSnapshotVersionIndex];\n\t\tif (version === undefined) {\n\t\t\tconsole.log(\n\t\t\t\t`There are only ${versions.length} snapshots, --snapshotVersionIndex is too large`,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\tif (saveDir !== undefined) {\n\t\t\tblobsToDump = await fetchBlobsFromVersion(storage, version);\n\t\t\tconst name = version.id;\n\t\t\tconsole.log(`Saving snapshot ${name}`);\n\t\t\tawait saveSnapshot(name, blobsToDump, saveDir);\n\t\t}\n\t} else {\n\t\tversion = versions[0];\n\t\tif (saveDir !== undefined && versions.length > 0) {\n\t\t\tconsole.log(\n\t\t\t\t\" Name | Date | Size | New Size | Blobs | New Blobs\",\n\t\t\t);\n\t\t\tconsole.log(\"-\".repeat(86));\n\n\t\t\t// Go in reverse order, to correctly calculate blob reuse - from oldest to newest snapshots\n\t\t\tfor (let i = versions.length - 1; i >= 0; i--) {\n\t\t\t\tconst v = versions[i];\n\t\t\t\tconst blobs = await fetchBlobsFromVersion(storage, v);\n\t\t\t\tblobsToDump = blobs;\n\t\t\t\tconst name = `${i}-${v.id}`;\n\t\t\t\tconst res = await dumpSnapshotTree(name, blobs);\n\n\t\t\t\tlet date = \"\";\n\t\t\t\tif (v.date !== undefined) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tdate = new Date(v.date).toLocaleString();\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\tdate = v.date.replace(\"T\", \" \");\n\t\t\t\t\t\tconst index = date.lastIndexOf(\".\");\n\t\t\t\t\t\tif (index > 0) {\n\t\t\t\t\t\t\tdate = `${date.substr(0, index)} Z`;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tdate = date.padStart(23);\n\t\t\t\tconst size = formatNumber(res.size).padStart(10);\n\t\t\t\tconst sizeNew = formatNumber(res.sizeNew).padStart(10);\n\t\t\t\tconst blobCount = formatNumber(res.blobCount).padStart(6);\n\t\t\t\tconst blobCountNew = formatNumber(res.blobCountNew).padStart(9);\n\n\t\t\t\tconsole.log(\n\t\t\t\t\t`${name.padEnd(\n\t\t\t\t\t\t15,\n\t\t\t\t\t)} | ${date} | ${size} | ${sizeNew} | ${blobCount} | ${blobCountNew}`,\n\t\t\t\t);\n\n\t\t\t\tawait saveSnapshot(name, blobs, saveDir);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (dumpSnapshotStats || dumpSnapshotTrees) {\n\t\tif (version === undefined) {\n\t\t\tconsole.log(\"No snapshot tree\");\n\t\t} else {\n\t\t\t// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions, @typescript-eslint/prefer-nullish-coalescing -- intentional behavior\n\t\t\tif (blobsToDump === undefined) {\n\t\t\t\tblobsToDump = await fetchBlobsFromVersion(storage, version);\n\t\t\t}\n\t\t\tconsole.log(`\\n\\nSnapshot version ${version.id}`);\n\t\t\tawait dumpSnapshotTreeVerbose(version.id, blobsToDump);\n\t\t}\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"fluidFetchSnapshot.js","sourceRoot":"","sources":["../src/fluidFetchSnapshot.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 fs from \"fs\";\nimport util from \"util\";\n\nimport { bufferToString, stringToBuffer } from \"@fluid-internal/client-utils\";\nimport type {\n\tIDocumentService,\n\tIDocumentStorageService,\n\tISnapshotTree,\n\tIVersion,\n} from \"@fluidframework/driver-definitions/internal\";\n\nimport { formatNumber } from \"./fluidAnalyzeMessages.js\";\nimport {\n\tdumpSnapshotStats,\n\tdumpSnapshotTrees,\n\tdumpSnapshotVersions,\n\tparamActualFormatting,\n\tparamNumSnapshotVersions,\n\tparamSnapshotVersionIndex,\n} from \"./fluidFetchArgs.js\";\nimport { latestVersionsId } from \"./fluidFetchInit.js\";\n\ninterface ISnapshotInfo {\n\tblobCountNew: number;\n\tblobCount: number;\n\tsize: number;\n\tsizeNew: number;\n}\n\ntype IFetchedData = IFetchedBlob | IFetchedTree;\n\ninterface IFetchedBlob {\n\ttreePath: string;\n\tfilename: string;\n\tblobId: string;\n\tblob: Promise<ArrayBufferLike | undefined>;\n\treused: boolean;\n}\n\ninterface IFetchedTree {\n\ttreePath: string;\n\tblobId: string;\n\tfilename: string;\n\tblob: ArrayBufferLike;\n\n\treused: false;\n\n\tpatched: boolean;\n}\n\nfunction isFetchedTree(fetchedData: IFetchedData): fetchedData is IFetchedTree {\n\treturn \"patched\" in fetchedData;\n}\n\nconst blobCache = new Map<string, Promise<ArrayBufferLike>>();\nlet blobCachePrevious = new Map<string, Promise<ArrayBufferLike>>();\nlet blobCacheCurrent = new Map<string, Promise<ArrayBufferLike>>();\n\nfunction fetchBlobs(\n\tprefix: string,\n\ttree: ISnapshotTree,\n\tstorage: IDocumentStorageService,\n\tblobIdMap: Map<string, number>,\n): IFetchedBlob[] {\n\tconst result: IFetchedBlob[] = [];\n\tfor (const [item, blobId] of Object.entries(tree.blobs)) {\n\t\tconst treePath = `${prefix}${item}`;\n\t\tif (blobId !== null) {\n\t\t\tlet reused = true;\n\t\t\tlet blob = blobCachePrevious.get(blobId);\n\t\t\tif (!blob) {\n\t\t\t\treused = false;\n\t\t\t\tblob = blobCache.get(blobId);\n\t\t\t\tif (blob === undefined) {\n\t\t\t\t\tblob = storage.readBlob(blobId);\n\t\t\t\t\tblobCache.set(blobId, blob);\n\t\t\t\t}\n\t\t\t}\n\t\t\tblobCacheCurrent.set(blobId, blob);\n\n\t\t\t// Use the blobIdMap to assign a number for each unique blob\n\t\t\t// and use it as a prefix for files to avoid case-insensitive fs\n\t\t\tlet index = blobIdMap.get(blobId);\n\t\t\tif (index === undefined) {\n\t\t\t\tindex = blobIdMap.size;\n\t\t\t\tblobIdMap.set(blobId, index);\n\t\t\t}\n\t\t\tconst filename = `${index}-${blobId}`;\n\t\t\tresult.push({ treePath, blobId, blob, reused, filename });\n\n\t\t\t// patch the tree so that we can write it out to reference the file\n\t\t\ttree.blobs[item] = filename;\n\t\t}\n\t}\n\treturn result;\n}\n\nfunction createTreeBlob(tree: ISnapshotTree, prefix: string, patched: boolean): IFetchedTree {\n\tconst id = tree.id ?? \"original\";\n\tconst blob = stringToBuffer(JSON.stringify(tree), \"utf8\");\n\tconst filename = patched ? \"tree\" : `tree-${id}`;\n\tconst treePath = `${prefix}${filename}`;\n\treturn { treePath, blobId: \"original tree $id\", filename, blob, patched, reused: false };\n}\n\nasync function fetchBlobsFromSnapshotTree(\n\tstorage: IDocumentStorageService,\n\ttree: ISnapshotTree,\n\tprefix: string = \"/\",\n\tparentBlobIdMap?: Map<string, number>,\n): Promise<IFetchedData[]> {\n\tconst isTopLevel = !parentBlobIdMap;\n\tif (isTopLevel && dumpSnapshotTrees) {\n\t\tconsole.log(tree);\n\t}\n\n\tif (prefix === \"/\") {\n\t\tblobCachePrevious = blobCacheCurrent;\n\t\tblobCacheCurrent = new Map<string, Promise<ArrayBufferLike>>();\n\t}\n\n\t// Create the tree info before fetching blobs (which will modify it)\n\tlet topLevelBlob: IFetchedTree | undefined;\n\tif (isTopLevel) {\n\t\ttopLevelBlob = createTreeBlob(tree, prefix, false);\n\t}\n\n\tconst blobIdMap = parentBlobIdMap ?? new Map<string, number>();\n\tlet result: IFetchedData[] = fetchBlobs(prefix, tree, storage, blobIdMap);\n\n\tfor (const [subtreeId, subtree] of Object.entries(tree.trees)) {\n\t\tconst dataStoreBlobs = await fetchBlobsFromSnapshotTree(\n\t\t\tstorage,\n\t\t\tsubtree,\n\t\t\t`${prefix}${subtreeId}/`,\n\t\t\tblobIdMap,\n\t\t);\n\t\tresult = result.concat(dataStoreBlobs);\n\t}\n\n\tif (topLevelBlob) {\n\t\tresult.push(topLevelBlob);\n\t\tresult.push(createTreeBlob(tree, prefix, true));\n\t}\n\treturn result;\n}\n\nfunction getDumpFetchedData(fetchedData: IFetchedData[]): IFetchedData[] {\n\tconst sorted = fetchedData.sort((a, b) => a.treePath.localeCompare(b.treePath));\n\treturn sorted.filter((item) => !isFetchedTree(item) || !item.patched);\n}\n\nasync function dumpSnapshotTreeVerbose(\n\tname: string,\n\tfetchedData: IFetchedData[],\n): Promise<void> {\n\tlet size = 0;\n\tconst sorted = getDumpFetchedData(fetchedData);\n\n\tlet nameLength = 10;\n\tfor (const item of sorted) {\n\t\tnameLength = Math.max(nameLength, item.treePath.length);\n\t}\n\n\tconsole.log(\"\");\n\tconsole.log(`${\"Blob Path\".padEnd(nameLength)} | Reused | Bytes`);\n\tconsole.log(\"-\".repeat(nameLength + 26));\n\tfor (const item of sorted) {\n\t\tconst buffer = await item.blob;\n\t\tif (buffer === undefined) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst blob = bufferToString(buffer, \"utf8\");\n\t\tconsole.log(\n\t\t\t`${item.treePath.padEnd(nameLength)} | ${item.reused ? \"X\" : \" \"} | ${formatNumber(\n\t\t\t\tblob.length,\n\t\t\t).padStart(10)}`,\n\t\t);\n\t\tsize += blob.length;\n\t}\n\n\tconsole.log(\"-\".repeat(nameLength + 26));\n\tconsole.log(\n\t\t`${\"Total snapshot size\".padEnd(nameLength)} | | ${formatNumber(size).padStart(\n\t\t\t10,\n\t\t)}`,\n\t);\n}\n\nasync function dumpSnapshotTree(\n\tname: string,\n\tfetchedData: IFetchedData[],\n): Promise<ISnapshotInfo> {\n\tlet size = 0;\n\tlet sizeNew = 0;\n\tlet blobCountNew = 0;\n\tconst sorted = getDumpFetchedData(fetchedData);\n\n\tfor (const item of sorted) {\n\t\tconst buffer = await item.blob;\n\t\tif (buffer === undefined) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst blob = bufferToString(buffer, \"utf8\");\n\t\tif (!item.reused) {\n\t\t\tsizeNew += blob.length;\n\t\t\tblobCountNew++;\n\t\t}\n\t\tsize += blob.length;\n\t}\n\n\treturn { blobCountNew, blobCount: sorted.length, size, sizeNew };\n}\n\nasync function saveSnapshot(\n\tname: string,\n\tfetchedData: IFetchedData[],\n\tsaveDir: string,\n): Promise<void> {\n\tconst outDir = `${saveDir}/${name}/`;\n\tconst mkdir = util.promisify(fs.mkdir);\n\n\tawait mkdir(`${outDir}/decoded`, { recursive: true });\n\tawait Promise.all(\n\t\tfetchedData.map(async (item) => {\n\t\t\tconst buffer = await item.blob;\n\t\t\tif (buffer === undefined) {\n\t\t\t\tconsole.error(`ERROR: Unable to get data for blob ${item.blobId}`);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (!isFetchedTree(item)) {\n\t\t\t\t// Just write the data as is.\n\t\t\t\tfs.writeFileSync(`${outDir}/${item.filename}`, Buffer.from(buffer));\n\n\t\t\t\t// we assume that the buffer is utf8 here, which currently is true for\n\t\t\t\t// all of our snapshot blobs. It doesn't necessary be true in the future\n\t\t\t\tlet decoded = bufferToString(buffer, \"utf8\");\n\t\t\t\ttry {\n\t\t\t\t\tif (!paramActualFormatting) {\n\t\t\t\t\t\tdecoded = JSON.stringify(JSON.parse(decoded), undefined, 2);\n\t\t\t\t\t}\n\t\t\t\t} catch (e) {\n\t\t\t\t\t// TODO: document why we are ignoring the error here\n\t\t\t\t}\n\t\t\t\tfs.writeFileSync(`${outDir}/decoded/${item.filename}.json`, decoded);\n\t\t\t} else {\n\t\t\t\t// Write out same data for tree decoded or not, except for formatting\n\t\t\t\tconst treeString = bufferToString(buffer, \"utf8\");\n\t\t\t\tfs.writeFileSync(`${outDir}/${item.filename}.json`, treeString);\n\t\t\t\tfs.writeFileSync(\n\t\t\t\t\t`${outDir}/decoded/${item.filename}.json`,\n\t\t\t\t\tparamActualFormatting\n\t\t\t\t\t\t? treeString\n\t\t\t\t\t\t: JSON.stringify(JSON.parse(treeString), undefined, 2),\n\t\t\t\t);\n\t\t\t}\n\t\t}),\n\t);\n}\n\nasync function fetchBlobsFromVersion(\n\tstorage: IDocumentStorageService,\n\tversion: IVersion,\n): Promise<IFetchedData[]> {\n\tconst tree = await reportErrors(\n\t\t`getSnapshotTree ${version.id}`,\n\t\tstorage.getSnapshotTree(version),\n\t);\n\tif (!tree) {\n\t\tthrow new Error(\"Failed to load snapshot tree\");\n\t}\n\treturn fetchBlobsFromSnapshotTree(storage, tree);\n}\n\nasync function reportErrors<T>(message: string, res: Promise<T>): Promise<T> {\n\ttry {\n\t\treturn await res;\n\t} catch (error) {\n\t\tconsole.error(`Error calling ${message}`);\n\t\tthrow error;\n\t}\n}\n\nexport async function fluidFetchSnapshot(\n\tdocumentService?: IDocumentService,\n\tsaveDir?: string,\n): Promise<void> {\n\tif (\n\t\t!dumpSnapshotStats &&\n\t\t!dumpSnapshotTrees &&\n\t\t!dumpSnapshotVersions &&\n\t\tsaveDir === undefined\n\t) {\n\t\treturn;\n\t}\n\n\t// --local mode - do not connect to storage.\n\t// For now, bail out early.\n\t// In future, separate download from analyzes parts and allow offline analyzes\n\tif (!documentService) {\n\t\treturn;\n\t}\n\n\tconsole.log(\"\\n\");\n\n\tconst storage = await documentService.connectToStorage();\n\n\tlet version: IVersion | undefined;\n\tconst versions = await reportErrors(\n\t\t`getVersions ${latestVersionsId}`,\n\t\tstorage.getVersions(latestVersionsId, paramNumSnapshotVersions),\n\t);\n\tif (dumpSnapshotVersions) {\n\t\tconsole.log(\"Snapshot versions\");\n\t\tconsole.log(versions);\n\t}\n\n\tlet blobsToDump: IFetchedData[] | undefined;\n\tif (paramSnapshotVersionIndex !== undefined) {\n\t\tversion = versions[paramSnapshotVersionIndex];\n\t\tif (version === undefined) {\n\t\t\tconsole.log(\n\t\t\t\t`There are only ${versions.length} snapshots, --snapshotVersionIndex is too large`,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\tif (saveDir !== undefined) {\n\t\t\tblobsToDump = await fetchBlobsFromVersion(storage, version);\n\t\t\tconst name = version.id;\n\t\t\tconsole.log(`Saving snapshot ${name}`);\n\t\t\tawait saveSnapshot(name, blobsToDump, saveDir);\n\t\t}\n\t} else {\n\t\tversion = versions[0];\n\t\tif (saveDir !== undefined && versions.length > 0) {\n\t\t\tconsole.log(\n\t\t\t\t\" Name | Date | Size | New Size | Blobs | New Blobs\",\n\t\t\t);\n\t\t\tconsole.log(\"-\".repeat(86));\n\n\t\t\t// Go in reverse order, to correctly calculate blob reuse - from oldest to newest snapshots\n\t\t\tfor (let i = versions.length - 1; i >= 0; i--) {\n\t\t\t\tconst v = versions[i];\n\t\t\t\tconst blobs = await fetchBlobsFromVersion(storage, v);\n\t\t\t\tblobsToDump = blobs;\n\t\t\t\tconst name = `${i}-${v.id}`;\n\t\t\t\tconst res = await dumpSnapshotTree(name, blobs);\n\n\t\t\t\tlet date = \"\";\n\t\t\t\tif (v.date !== undefined) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tdate = new Date(v.date).toLocaleString();\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\tdate = v.date.replace(\"T\", \" \");\n\t\t\t\t\t\tconst index = date.lastIndexOf(\".\");\n\t\t\t\t\t\tif (index > 0) {\n\t\t\t\t\t\t\tdate = `${date.substr(0, index)} Z`;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tdate = date.padStart(23);\n\t\t\t\tconst size = formatNumber(res.size).padStart(10);\n\t\t\t\tconst sizeNew = formatNumber(res.sizeNew).padStart(10);\n\t\t\t\tconst blobCount = formatNumber(res.blobCount).padStart(6);\n\t\t\t\tconst blobCountNew = formatNumber(res.blobCountNew).padStart(9);\n\n\t\t\t\tconsole.log(\n\t\t\t\t\t`${name.padEnd(\n\t\t\t\t\t\t15,\n\t\t\t\t\t)} | ${date} | ${size} | ${sizeNew} | ${blobCount} | ${blobCountNew}`,\n\t\t\t\t);\n\n\t\t\t\tawait saveSnapshot(name, blobs, saveDir);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (dumpSnapshotStats || dumpSnapshotTrees) {\n\t\tif (version === undefined) {\n\t\t\tconsole.log(\"No snapshot tree\");\n\t\t} else {\n\t\t\t// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- intentional behavior\n\t\t\tif (blobsToDump === undefined) {\n\t\t\t\tblobsToDump = await fetchBlobsFromVersion(storage, version);\n\t\t\t}\n\t\t\tconsole.log(`\\n\\nSnapshot version ${version.id}`);\n\t\t\tawait dumpSnapshotTreeVerbose(version.id, blobsToDump);\n\t\t}\n\t}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fluidFetchSharePoint.d.ts","sourceRoot":"","sources":["../src/fluidFetchSharePoint.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,OAAO,EACN,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,cAAc,EAMnB,MAAM,4CAA4C,CAAC;AASpD,eAAO,MAAM,qBAAqB,EAAE,mBAUnC,CAAC;AAaF,wBAAsB,cAAc,CAAC,CAAC,EACrC,QAAQ,EAAE,CAAC,eAAe,EAAE,oBAAoB,KAAK,OAAO,CAAC,CAAC,CAAC,EAC/D,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,mBAAmB,EACjC,gBAAgB,UAAQ,GACtB,OAAO,CAAC,CAAC,CAAC,CAmDZ;AA6BD,wBAAsB,kBAAkB,CACvC,MAAM,EAAE,MAAM,EACd,kBAAkB,EAAE,MAAM,EAC1B,OAAO,EAAE,OAAO,GACd,OAAO,CAAC,cAAc,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"fluidFetchSharePoint.d.ts","sourceRoot":"","sources":["../src/fluidFetchSharePoint.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,OAAO,EACN,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,cAAc,EAMnB,MAAM,4CAA4C,CAAC;AASpD,eAAO,MAAM,qBAAqB,EAAE,mBAUnC,CAAC;AAaF,wBAAsB,cAAc,CAAC,CAAC,EACrC,QAAQ,EAAE,CAAC,eAAe,EAAE,oBAAoB,KAAK,OAAO,CAAC,CAAC,CAAC,EAC/D,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,mBAAmB,EACjC,gBAAgB,UAAQ,GACtB,OAAO,CAAC,CAAC,CAAC,CAmDZ;AA6BD,wBAAsB,kBAAkB,CACvC,MAAM,EAAE,MAAM,EACd,kBAAkB,EAAE,MAAM,EAC1B,OAAO,EAAE,OAAO,GACd,OAAO,CAAC,cAAc,EAAE,CAAC,CAkC3B;AAED,wBAAsB,uBAAuB,CAC5C,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,GACV,OAAO,CAAC,cAAc,CAAC,CAOzB"}
|
|
@@ -101,7 +101,6 @@ export async function getSharepointFiles(server, serverRelativePath, recurse) {
|
|
|
101
101
|
else {
|
|
102
102
|
files.push(fileInfo);
|
|
103
103
|
}
|
|
104
|
-
// eslint-disable-next-line no-constant-condition
|
|
105
104
|
while (true) {
|
|
106
105
|
const folderInfo = pendingFolder.shift();
|
|
107
106
|
if (!folderInfo) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fluidFetchSharePoint.js","sourceRoot":"","sources":["../src/fluidFetchSharePoint.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 {\n\tInteractiveBrowserCredential,\n\tuseIdentityPlugin,\n\ttype AuthenticationRecord,\n} from \"@azure/identity\";\nimport { cachePersistencePlugin } from \"@azure/identity-cache-persistence\";\nimport { DriverErrorTypes } from \"@fluidframework/driver-definitions/internal\";\nimport {\n\ttype IPublicClientConfig,\n\ttype IOdspAuthRequestInfo,\n\ttype IOdspDriveItem,\n\tgetChildrenByDriveItem,\n\tgetDriveItemByServerRelativePath,\n\tgetDriveItemFromDriveAndItem,\n\tgetAadTenant,\n\tgetOdspScope,\n} from \"@fluidframework/odsp-doclib-utils/internal\";\n\nimport { loginHint } from \"./fluidFetchArgs.js\";\n\n// Note: the following page may be helpful for debugging auth issues:\n// https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/identity/identity/TROUBLESHOOTING.md\n// See e.g. the section on setting 'AZURE_LOG_LEVEL'.\nuseIdentityPlugin(cachePersistencePlugin);\n\nexport const fetchToolClientConfig: IPublicClientConfig = {\n\tget clientId(): string {\n\t\tconst clientId = process.env.fetch__tool__clientId;\n\t\tif (clientId === undefined) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Client ID environment variable not set: fetch__tool__clientId. Use the getkeys tool to populate it.\",\n\t\t\t);\n\t\t}\n\t\treturn clientId;\n\t},\n};\n\n// Local token cache for resolveWrapper.\n// @azure/identity-cache-persistence does not behave well in response to large numbers of parallel requests, which can happen for documents\n// with lots of blobs. We work around this for now by including a simple in-memory cache.\n// See more information here:\n// https://github.com/Azure/azure-sdk-for-js/issues/31307\nconst tokensByServer = new Map<string, string>();\n\n// If the persisted cache has multiple accounts, InteractiveBrowserCredential ignores it unless it is passed an explicit authentication record.\n// We keep the auth record around for a single run in memory, so that at worst we only have to authenticate once per server/user.\nconst authRecordPerServer = new Map<string, AuthenticationRecord | undefined>();\n\nexport async function resolveWrapper<T>(\n\tcallback: (authRequestInfo: IOdspAuthRequestInfo) => Promise<T>,\n\tserver: string,\n\tclientConfig: IPublicClientConfig,\n\tforceTokenReauth = false,\n): Promise<T> {\n\ttry {\n\t\tconst authenticationRecord = authRecordPerServer.get(server);\n\t\tconst credential = new InteractiveBrowserCredential({\n\t\t\tclientId: fetchToolClientConfig.clientId,\n\t\t\ttenantId: getAadTenant(server),\n\t\t\t// NOTE: fetch-tool flows using multiple sets of user credentials haven't been well-tested.\n\t\t\t// Some of the @azure/identity docs suggest we may need to manage authentication records and choose\n\t\t\t// which one to use explicitly here if we have such scenarios.\n\t\t\t// If we start doing this, it may be worth considering using disableAutomaticAuthentication here so we\n\t\t\t// have better control over when interactive auth may be triggered.\n\t\t\t// For now, fetch-tool doesn't work against personal accounts anyway so the only flow that might necessitate this\n\t\t\t// would be grabbing documents using several identities (e.g. test accounts we use for stress testing).\n\t\t\t// In that case, a simple workaround is to delete the cache that @azure/identity uses before running the tool.\n\t\t\t// See docs on `tokenCachePersistenceOptions.name` for information on where this cache is stored.\n\t\t\tloginHint,\n\t\t\tauthenticationRecord,\n\t\t\ttokenCachePersistenceOptions: {\n\t\t\t\tenabled: true,\n\t\t\t\tname: \"fetch-tool\",\n\t\t\t},\n\t\t});\n\n\t\tconst scope = getOdspScope(server);\n\t\tif (authenticationRecord === undefined) {\n\t\t\t// Cache this authentication record for subsequent token requests.\n\t\t\tauthRecordPerServer.set(server, await credential.authenticate(scope));\n\t\t}\n\t\tlet cachedToken = tokensByServer.get(server);\n\t\tif (cachedToken === undefined || forceTokenReauth) {\n\t\t\tconst result = await credential.getToken(scope);\n\t\t\tcachedToken = result.token;\n\t\t\ttokensByServer.set(server, cachedToken);\n\t\t}\n\n\t\treturn await callback({\n\t\t\taccessToken: cachedToken,\n\t\t\trefreshTokenFn: async () => {\n\t\t\t\tawait credential.authenticate(scope);\n\t\t\t\tconst { token } = await credential.getToken(scope);\n\t\t\t\ttokensByServer.set(server, token);\n\t\t\t\treturn token;\n\t\t\t},\n\t\t});\n\t} catch (e: any) {\n\t\tif (e.errorType === DriverErrorTypes.authorizationError && !forceTokenReauth) {\n\t\t\t// Re-auth\n\t\t\treturn resolveWrapper<T>(callback, server, clientConfig, true);\n\t\t}\n\t\tthrow e;\n\t}\n}\n\nasync function resolveDriveItemByServerRelativePath(\n\tserver: string,\n\tserverRelativePath: string,\n\tclientConfig: IPublicClientConfig,\n): Promise<IOdspDriveItem> {\n\treturn resolveWrapper<IOdspDriveItem>(\n\t\t// eslint-disable-next-line @typescript-eslint/promise-function-async\n\t\t(authRequestInfo) =>\n\t\t\tgetDriveItemByServerRelativePath(server, serverRelativePath, authRequestInfo, false),\n\t\tserver,\n\t\tclientConfig,\n\t);\n}\n\nasync function resolveChildrenByDriveItem(\n\tserver: string,\n\tfolderDriveItem: IOdspDriveItem,\n\tclientConfig: IPublicClientConfig,\n): Promise<IOdspDriveItem[]> {\n\treturn resolveWrapper<IOdspDriveItem[]>(\n\t\t// eslint-disable-next-line @typescript-eslint/promise-function-async\n\t\t(authRequestInfo) => getChildrenByDriveItem(folderDriveItem, server, authRequestInfo),\n\t\tserver,\n\t\tclientConfig,\n\t);\n}\n\nexport async function getSharepointFiles(\n\tserver: string,\n\tserverRelativePath: string,\n\trecurse: boolean,\n): Promise<IOdspDriveItem[]> {\n\tconst fileInfo = await resolveDriveItemByServerRelativePath(\n\t\tserver,\n\t\tserverRelativePath,\n\t\tfetchToolClientConfig,\n\t);\n\tconsole.log(fileInfo);\n\tconst pendingFolder: { path: string; folder: IOdspDriveItem }[] = [];\n\tconst files: IOdspDriveItem[] = [];\n\tif (fileInfo.isFolder) {\n\t\tpendingFolder.push({ path: serverRelativePath, folder: fileInfo });\n\t} else {\n\t\tfiles.push(fileInfo);\n\t}\n\n\t// eslint-disable-next-line no-constant-condition\n\twhile (true) {\n\t\tconst folderInfo = pendingFolder.shift();\n\t\tif (!folderInfo) {\n\t\t\tbreak;\n\t\t}\n\t\tconst { path, folder } = folderInfo;\n\t\tconst children = await resolveChildrenByDriveItem(server, folder, fetchToolClientConfig);\n\t\tfor (const child of children) {\n\t\t\tconst childPath = `${path}/${child.name}`;\n\t\t\tif (child.isFolder) {\n\t\t\t\tif (recurse) {\n\t\t\t\t\tpendingFolder.push({ path: childPath, folder: child });\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfiles.push(child);\n\t\t\t}\n\t\t}\n\t}\n\treturn files;\n}\n\nexport async function getSingleSharePointFile(\n\tserver: string,\n\tdrive: string,\n\titem: string,\n): Promise<IOdspDriveItem> {\n\treturn resolveWrapper<IOdspDriveItem>(\n\t\t// eslint-disable-next-line @typescript-eslint/promise-function-async\n\t\t(authRequestInfo) => getDriveItemFromDriveAndItem(server, drive, item, authRequestInfo),\n\t\tserver,\n\t\tfetchToolClientConfig,\n\t);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"fluidFetchSharePoint.js","sourceRoot":"","sources":["../src/fluidFetchSharePoint.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 {\n\tInteractiveBrowserCredential,\n\tuseIdentityPlugin,\n\ttype AuthenticationRecord,\n} from \"@azure/identity\";\nimport { cachePersistencePlugin } from \"@azure/identity-cache-persistence\";\nimport { DriverErrorTypes } from \"@fluidframework/driver-definitions/internal\";\nimport {\n\ttype IPublicClientConfig,\n\ttype IOdspAuthRequestInfo,\n\ttype IOdspDriveItem,\n\tgetChildrenByDriveItem,\n\tgetDriveItemByServerRelativePath,\n\tgetDriveItemFromDriveAndItem,\n\tgetAadTenant,\n\tgetOdspScope,\n} from \"@fluidframework/odsp-doclib-utils/internal\";\n\nimport { loginHint } from \"./fluidFetchArgs.js\";\n\n// Note: the following page may be helpful for debugging auth issues:\n// https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/identity/identity/TROUBLESHOOTING.md\n// See e.g. the section on setting 'AZURE_LOG_LEVEL'.\nuseIdentityPlugin(cachePersistencePlugin);\n\nexport const fetchToolClientConfig: IPublicClientConfig = {\n\tget clientId(): string {\n\t\tconst clientId = process.env.fetch__tool__clientId;\n\t\tif (clientId === undefined) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Client ID environment variable not set: fetch__tool__clientId. Use the getkeys tool to populate it.\",\n\t\t\t);\n\t\t}\n\t\treturn clientId;\n\t},\n};\n\n// Local token cache for resolveWrapper.\n// @azure/identity-cache-persistence does not behave well in response to large numbers of parallel requests, which can happen for documents\n// with lots of blobs. We work around this for now by including a simple in-memory cache.\n// See more information here:\n// https://github.com/Azure/azure-sdk-for-js/issues/31307\nconst tokensByServer = new Map<string, string>();\n\n// If the persisted cache has multiple accounts, InteractiveBrowserCredential ignores it unless it is passed an explicit authentication record.\n// We keep the auth record around for a single run in memory, so that at worst we only have to authenticate once per server/user.\nconst authRecordPerServer = new Map<string, AuthenticationRecord | undefined>();\n\nexport async function resolveWrapper<T>(\n\tcallback: (authRequestInfo: IOdspAuthRequestInfo) => Promise<T>,\n\tserver: string,\n\tclientConfig: IPublicClientConfig,\n\tforceTokenReauth = false,\n): Promise<T> {\n\ttry {\n\t\tconst authenticationRecord = authRecordPerServer.get(server);\n\t\tconst credential = new InteractiveBrowserCredential({\n\t\t\tclientId: fetchToolClientConfig.clientId,\n\t\t\ttenantId: getAadTenant(server),\n\t\t\t// NOTE: fetch-tool flows using multiple sets of user credentials haven't been well-tested.\n\t\t\t// Some of the @azure/identity docs suggest we may need to manage authentication records and choose\n\t\t\t// which one to use explicitly here if we have such scenarios.\n\t\t\t// If we start doing this, it may be worth considering using disableAutomaticAuthentication here so we\n\t\t\t// have better control over when interactive auth may be triggered.\n\t\t\t// For now, fetch-tool doesn't work against personal accounts anyway so the only flow that might necessitate this\n\t\t\t// would be grabbing documents using several identities (e.g. test accounts we use for stress testing).\n\t\t\t// In that case, a simple workaround is to delete the cache that @azure/identity uses before running the tool.\n\t\t\t// See docs on `tokenCachePersistenceOptions.name` for information on where this cache is stored.\n\t\t\tloginHint,\n\t\t\tauthenticationRecord,\n\t\t\ttokenCachePersistenceOptions: {\n\t\t\t\tenabled: true,\n\t\t\t\tname: \"fetch-tool\",\n\t\t\t},\n\t\t});\n\n\t\tconst scope = getOdspScope(server);\n\t\tif (authenticationRecord === undefined) {\n\t\t\t// Cache this authentication record for subsequent token requests.\n\t\t\tauthRecordPerServer.set(server, await credential.authenticate(scope));\n\t\t}\n\t\tlet cachedToken = tokensByServer.get(server);\n\t\tif (cachedToken === undefined || forceTokenReauth) {\n\t\t\tconst result = await credential.getToken(scope);\n\t\t\tcachedToken = result.token;\n\t\t\ttokensByServer.set(server, cachedToken);\n\t\t}\n\n\t\treturn await callback({\n\t\t\taccessToken: cachedToken,\n\t\t\trefreshTokenFn: async () => {\n\t\t\t\tawait credential.authenticate(scope);\n\t\t\t\tconst { token } = await credential.getToken(scope);\n\t\t\t\ttokensByServer.set(server, token);\n\t\t\t\treturn token;\n\t\t\t},\n\t\t});\n\t} catch (e: any) {\n\t\tif (e.errorType === DriverErrorTypes.authorizationError && !forceTokenReauth) {\n\t\t\t// Re-auth\n\t\t\treturn resolveWrapper<T>(callback, server, clientConfig, true);\n\t\t}\n\t\tthrow e;\n\t}\n}\n\nasync function resolveDriveItemByServerRelativePath(\n\tserver: string,\n\tserverRelativePath: string,\n\tclientConfig: IPublicClientConfig,\n): Promise<IOdspDriveItem> {\n\treturn resolveWrapper<IOdspDriveItem>(\n\t\t// eslint-disable-next-line @typescript-eslint/promise-function-async\n\t\t(authRequestInfo) =>\n\t\t\tgetDriveItemByServerRelativePath(server, serverRelativePath, authRequestInfo, false),\n\t\tserver,\n\t\tclientConfig,\n\t);\n}\n\nasync function resolveChildrenByDriveItem(\n\tserver: string,\n\tfolderDriveItem: IOdspDriveItem,\n\tclientConfig: IPublicClientConfig,\n): Promise<IOdspDriveItem[]> {\n\treturn resolveWrapper<IOdspDriveItem[]>(\n\t\t// eslint-disable-next-line @typescript-eslint/promise-function-async\n\t\t(authRequestInfo) => getChildrenByDriveItem(folderDriveItem, server, authRequestInfo),\n\t\tserver,\n\t\tclientConfig,\n\t);\n}\n\nexport async function getSharepointFiles(\n\tserver: string,\n\tserverRelativePath: string,\n\trecurse: boolean,\n): Promise<IOdspDriveItem[]> {\n\tconst fileInfo = await resolveDriveItemByServerRelativePath(\n\t\tserver,\n\t\tserverRelativePath,\n\t\tfetchToolClientConfig,\n\t);\n\tconsole.log(fileInfo);\n\tconst pendingFolder: { path: string; folder: IOdspDriveItem }[] = [];\n\tconst files: IOdspDriveItem[] = [];\n\tif (fileInfo.isFolder) {\n\t\tpendingFolder.push({ path: serverRelativePath, folder: fileInfo });\n\t} else {\n\t\tfiles.push(fileInfo);\n\t}\n\n\twhile (true) {\n\t\tconst folderInfo = pendingFolder.shift();\n\t\tif (!folderInfo) {\n\t\t\tbreak;\n\t\t}\n\t\tconst { path, folder } = folderInfo;\n\t\tconst children = await resolveChildrenByDriveItem(server, folder, fetchToolClientConfig);\n\t\tfor (const child of children) {\n\t\t\tconst childPath = `${path}/${child.name}`;\n\t\t\tif (child.isFolder) {\n\t\t\t\tif (recurse) {\n\t\t\t\t\tpendingFolder.push({ path: childPath, folder: child });\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfiles.push(child);\n\t\t\t}\n\t\t}\n\t}\n\treturn files;\n}\n\nexport async function getSingleSharePointFile(\n\tserver: string,\n\tdrive: string,\n\titem: string,\n): Promise<IOdspDriveItem> {\n\treturn resolveWrapper<IOdspDriveItem>(\n\t\t// eslint-disable-next-line @typescript-eslint/promise-function-async\n\t\t(authRequestInfo) => getDriveItemFromDriveAndItem(server, drive, item, authRequestInfo),\n\t\tserver,\n\t\tfetchToolClientConfig,\n\t);\n}\n"]}
|
|
@@ -250,7 +250,7 @@ export async function fluidFetchSnapshot(documentService, saveDir) {
|
|
|
250
250
|
console.log("No snapshot tree");
|
|
251
251
|
}
|
|
252
252
|
else {
|
|
253
|
-
// eslint-disable-next-line @typescript-eslint/
|
|
253
|
+
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- intentional behavior
|
|
254
254
|
if (blobsToDump === undefined) {
|
|
255
255
|
blobsToDump = await fetchBlobsFromVersion(storage, version);
|
|
256
256
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fluidFetchSnapshot.js","sourceRoot":"","sources":["../src/fluidFetchSnapshot.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 fs from \"fs\";\nimport util from \"util\";\n\nimport { bufferToString, stringToBuffer } from \"@fluid-internal/client-utils\";\nimport type {\n\tIDocumentService,\n\tIDocumentStorageService,\n\tISnapshotTree,\n\tIVersion,\n} from \"@fluidframework/driver-definitions/internal\";\n\nimport { formatNumber } from \"./fluidAnalyzeMessages.js\";\nimport {\n\tdumpSnapshotStats,\n\tdumpSnapshotTrees,\n\tdumpSnapshotVersions,\n\tparamActualFormatting,\n\tparamNumSnapshotVersions,\n\tparamSnapshotVersionIndex,\n} from \"./fluidFetchArgs.js\";\nimport { latestVersionsId } from \"./fluidFetchInit.js\";\n\ninterface ISnapshotInfo {\n\tblobCountNew: number;\n\tblobCount: number;\n\tsize: number;\n\tsizeNew: number;\n}\n\ntype IFetchedData = IFetchedBlob | IFetchedTree;\n\ninterface IFetchedBlob {\n\ttreePath: string;\n\tfilename: string;\n\tblobId: string;\n\tblob: Promise<ArrayBufferLike | undefined>;\n\treused: boolean;\n}\n\ninterface IFetchedTree {\n\ttreePath: string;\n\tblobId: string;\n\tfilename: string;\n\tblob: ArrayBufferLike;\n\n\treused: false;\n\n\tpatched: boolean;\n}\n\nfunction isFetchedTree(fetchedData: IFetchedData): fetchedData is IFetchedTree {\n\treturn \"patched\" in fetchedData;\n}\n\nconst blobCache = new Map<string, Promise<ArrayBufferLike>>();\nlet blobCachePrevious = new Map<string, Promise<ArrayBufferLike>>();\nlet blobCacheCurrent = new Map<string, Promise<ArrayBufferLike>>();\n\nfunction fetchBlobs(\n\tprefix: string,\n\ttree: ISnapshotTree,\n\tstorage: IDocumentStorageService,\n\tblobIdMap: Map<string, number>,\n): IFetchedBlob[] {\n\tconst result: IFetchedBlob[] = [];\n\tfor (const [item, blobId] of Object.entries(tree.blobs)) {\n\t\tconst treePath = `${prefix}${item}`;\n\t\tif (blobId !== null) {\n\t\t\tlet reused = true;\n\t\t\tlet blob = blobCachePrevious.get(blobId);\n\t\t\tif (!blob) {\n\t\t\t\treused = false;\n\t\t\t\tblob = blobCache.get(blobId);\n\t\t\t\tif (blob === undefined) {\n\t\t\t\t\tblob = storage.readBlob(blobId);\n\t\t\t\t\tblobCache.set(blobId, blob);\n\t\t\t\t}\n\t\t\t}\n\t\t\tblobCacheCurrent.set(blobId, blob);\n\n\t\t\t// Use the blobIdMap to assign a number for each unique blob\n\t\t\t// and use it as a prefix for files to avoid case-insensitive fs\n\t\t\tlet index = blobIdMap.get(blobId);\n\t\t\tif (index === undefined) {\n\t\t\t\tindex = blobIdMap.size;\n\t\t\t\tblobIdMap.set(blobId, index);\n\t\t\t}\n\t\t\tconst filename = `${index}-${blobId}`;\n\t\t\tresult.push({ treePath, blobId, blob, reused, filename });\n\n\t\t\t// patch the tree so that we can write it out to reference the file\n\t\t\ttree.blobs[item] = filename;\n\t\t}\n\t}\n\treturn result;\n}\n\nfunction createTreeBlob(tree: ISnapshotTree, prefix: string, patched: boolean): IFetchedTree {\n\tconst id = tree.id ?? \"original\";\n\tconst blob = stringToBuffer(JSON.stringify(tree), \"utf8\");\n\tconst filename = patched ? \"tree\" : `tree-${id}`;\n\tconst treePath = `${prefix}${filename}`;\n\treturn { treePath, blobId: \"original tree $id\", filename, blob, patched, reused: false };\n}\n\nasync function fetchBlobsFromSnapshotTree(\n\tstorage: IDocumentStorageService,\n\ttree: ISnapshotTree,\n\tprefix: string = \"/\",\n\tparentBlobIdMap?: Map<string, number>,\n): Promise<IFetchedData[]> {\n\tconst isTopLevel = !parentBlobIdMap;\n\tif (isTopLevel && dumpSnapshotTrees) {\n\t\tconsole.log(tree);\n\t}\n\n\tif (prefix === \"/\") {\n\t\tblobCachePrevious = blobCacheCurrent;\n\t\tblobCacheCurrent = new Map<string, Promise<ArrayBufferLike>>();\n\t}\n\n\t// Create the tree info before fetching blobs (which will modify it)\n\tlet topLevelBlob: IFetchedTree | undefined;\n\tif (isTopLevel) {\n\t\ttopLevelBlob = createTreeBlob(tree, prefix, false);\n\t}\n\n\tconst blobIdMap = parentBlobIdMap ?? new Map<string, number>();\n\tlet result: IFetchedData[] = fetchBlobs(prefix, tree, storage, blobIdMap);\n\n\tfor (const [subtreeId, subtree] of Object.entries(tree.trees)) {\n\t\tconst dataStoreBlobs = await fetchBlobsFromSnapshotTree(\n\t\t\tstorage,\n\t\t\tsubtree,\n\t\t\t`${prefix}${subtreeId}/`,\n\t\t\tblobIdMap,\n\t\t);\n\t\tresult = result.concat(dataStoreBlobs);\n\t}\n\n\tif (topLevelBlob) {\n\t\tresult.push(topLevelBlob);\n\t\tresult.push(createTreeBlob(tree, prefix, true));\n\t}\n\treturn result;\n}\n\nfunction getDumpFetchedData(fetchedData: IFetchedData[]): IFetchedData[] {\n\tconst sorted = fetchedData.sort((a, b) => a.treePath.localeCompare(b.treePath));\n\treturn sorted.filter((item) => !isFetchedTree(item) || !item.patched);\n}\n\nasync function dumpSnapshotTreeVerbose(\n\tname: string,\n\tfetchedData: IFetchedData[],\n): Promise<void> {\n\tlet size = 0;\n\tconst sorted = getDumpFetchedData(fetchedData);\n\n\tlet nameLength = 10;\n\tfor (const item of sorted) {\n\t\tnameLength = Math.max(nameLength, item.treePath.length);\n\t}\n\n\tconsole.log(\"\");\n\tconsole.log(`${\"Blob Path\".padEnd(nameLength)} | Reused | Bytes`);\n\tconsole.log(\"-\".repeat(nameLength + 26));\n\tfor (const item of sorted) {\n\t\tconst buffer = await item.blob;\n\t\tif (buffer === undefined) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst blob = bufferToString(buffer, \"utf8\");\n\t\tconsole.log(\n\t\t\t`${item.treePath.padEnd(nameLength)} | ${item.reused ? \"X\" : \" \"} | ${formatNumber(\n\t\t\t\tblob.length,\n\t\t\t).padStart(10)}`,\n\t\t);\n\t\tsize += blob.length;\n\t}\n\n\tconsole.log(\"-\".repeat(nameLength + 26));\n\tconsole.log(\n\t\t`${\"Total snapshot size\".padEnd(nameLength)} | | ${formatNumber(size).padStart(\n\t\t\t10,\n\t\t)}`,\n\t);\n}\n\nasync function dumpSnapshotTree(\n\tname: string,\n\tfetchedData: IFetchedData[],\n): Promise<ISnapshotInfo> {\n\tlet size = 0;\n\tlet sizeNew = 0;\n\tlet blobCountNew = 0;\n\tconst sorted = getDumpFetchedData(fetchedData);\n\n\tfor (const item of sorted) {\n\t\tconst buffer = await item.blob;\n\t\tif (buffer === undefined) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst blob = bufferToString(buffer, \"utf8\");\n\t\tif (!item.reused) {\n\t\t\tsizeNew += blob.length;\n\t\t\tblobCountNew++;\n\t\t}\n\t\tsize += blob.length;\n\t}\n\n\treturn { blobCountNew, blobCount: sorted.length, size, sizeNew };\n}\n\nasync function saveSnapshot(\n\tname: string,\n\tfetchedData: IFetchedData[],\n\tsaveDir: string,\n): Promise<void> {\n\tconst outDir = `${saveDir}/${name}/`;\n\tconst mkdir = util.promisify(fs.mkdir);\n\n\tawait mkdir(`${outDir}/decoded`, { recursive: true });\n\tawait Promise.all(\n\t\tfetchedData.map(async (item) => {\n\t\t\tconst buffer = await item.blob;\n\t\t\tif (buffer === undefined) {\n\t\t\t\tconsole.error(`ERROR: Unable to get data for blob ${item.blobId}`);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (!isFetchedTree(item)) {\n\t\t\t\t// Just write the data as is.\n\t\t\t\tfs.writeFileSync(`${outDir}/${item.filename}`, Buffer.from(buffer));\n\n\t\t\t\t// we assume that the buffer is utf8 here, which currently is true for\n\t\t\t\t// all of our snapshot blobs. It doesn't necessary be true in the future\n\t\t\t\tlet decoded = bufferToString(buffer, \"utf8\");\n\t\t\t\ttry {\n\t\t\t\t\tif (!paramActualFormatting) {\n\t\t\t\t\t\tdecoded = JSON.stringify(JSON.parse(decoded), undefined, 2);\n\t\t\t\t\t}\n\t\t\t\t} catch (e) {\n\t\t\t\t\t// TODO: document why we are ignoring the error here\n\t\t\t\t}\n\t\t\t\tfs.writeFileSync(`${outDir}/decoded/${item.filename}.json`, decoded);\n\t\t\t} else {\n\t\t\t\t// Write out same data for tree decoded or not, except for formatting\n\t\t\t\tconst treeString = bufferToString(buffer, \"utf8\");\n\t\t\t\tfs.writeFileSync(`${outDir}/${item.filename}.json`, treeString);\n\t\t\t\tfs.writeFileSync(\n\t\t\t\t\t`${outDir}/decoded/${item.filename}.json`,\n\t\t\t\t\tparamActualFormatting\n\t\t\t\t\t\t? treeString\n\t\t\t\t\t\t: JSON.stringify(JSON.parse(treeString), undefined, 2),\n\t\t\t\t);\n\t\t\t}\n\t\t}),\n\t);\n}\n\nasync function fetchBlobsFromVersion(\n\tstorage: IDocumentStorageService,\n\tversion: IVersion,\n): Promise<IFetchedData[]> {\n\tconst tree = await reportErrors(\n\t\t`getSnapshotTree ${version.id}`,\n\t\tstorage.getSnapshotTree(version),\n\t);\n\tif (!tree) {\n\t\tthrow new Error(\"Failed to load snapshot tree\");\n\t}\n\treturn fetchBlobsFromSnapshotTree(storage, tree);\n}\n\nasync function reportErrors<T>(message: string, res: Promise<T>): Promise<T> {\n\ttry {\n\t\treturn await res;\n\t} catch (error) {\n\t\tconsole.error(`Error calling ${message}`);\n\t\tthrow error;\n\t}\n}\n\nexport async function fluidFetchSnapshot(\n\tdocumentService?: IDocumentService,\n\tsaveDir?: string,\n): Promise<void> {\n\tif (\n\t\t!dumpSnapshotStats &&\n\t\t!dumpSnapshotTrees &&\n\t\t!dumpSnapshotVersions &&\n\t\tsaveDir === undefined\n\t) {\n\t\treturn;\n\t}\n\n\t// --local mode - do not connect to storage.\n\t// For now, bail out early.\n\t// In future, separate download from analyzes parts and allow offline analyzes\n\tif (!documentService) {\n\t\treturn;\n\t}\n\n\tconsole.log(\"\\n\");\n\n\tconst storage = await documentService.connectToStorage();\n\n\tlet version: IVersion | undefined;\n\tconst versions = await reportErrors(\n\t\t`getVersions ${latestVersionsId}`,\n\t\tstorage.getVersions(latestVersionsId, paramNumSnapshotVersions),\n\t);\n\tif (dumpSnapshotVersions) {\n\t\tconsole.log(\"Snapshot versions\");\n\t\tconsole.log(versions);\n\t}\n\n\tlet blobsToDump: IFetchedData[] | undefined;\n\tif (paramSnapshotVersionIndex !== undefined) {\n\t\tversion = versions[paramSnapshotVersionIndex];\n\t\tif (version === undefined) {\n\t\t\tconsole.log(\n\t\t\t\t`There are only ${versions.length} snapshots, --snapshotVersionIndex is too large`,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\tif (saveDir !== undefined) {\n\t\t\tblobsToDump = await fetchBlobsFromVersion(storage, version);\n\t\t\tconst name = version.id;\n\t\t\tconsole.log(`Saving snapshot ${name}`);\n\t\t\tawait saveSnapshot(name, blobsToDump, saveDir);\n\t\t}\n\t} else {\n\t\tversion = versions[0];\n\t\tif (saveDir !== undefined && versions.length > 0) {\n\t\t\tconsole.log(\n\t\t\t\t\" Name | Date | Size | New Size | Blobs | New Blobs\",\n\t\t\t);\n\t\t\tconsole.log(\"-\".repeat(86));\n\n\t\t\t// Go in reverse order, to correctly calculate blob reuse - from oldest to newest snapshots\n\t\t\tfor (let i = versions.length - 1; i >= 0; i--) {\n\t\t\t\tconst v = versions[i];\n\t\t\t\tconst blobs = await fetchBlobsFromVersion(storage, v);\n\t\t\t\tblobsToDump = blobs;\n\t\t\t\tconst name = `${i}-${v.id}`;\n\t\t\t\tconst res = await dumpSnapshotTree(name, blobs);\n\n\t\t\t\tlet date = \"\";\n\t\t\t\tif (v.date !== undefined) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tdate = new Date(v.date).toLocaleString();\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\tdate = v.date.replace(\"T\", \" \");\n\t\t\t\t\t\tconst index = date.lastIndexOf(\".\");\n\t\t\t\t\t\tif (index > 0) {\n\t\t\t\t\t\t\tdate = `${date.substr(0, index)} Z`;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tdate = date.padStart(23);\n\t\t\t\tconst size = formatNumber(res.size).padStart(10);\n\t\t\t\tconst sizeNew = formatNumber(res.sizeNew).padStart(10);\n\t\t\t\tconst blobCount = formatNumber(res.blobCount).padStart(6);\n\t\t\t\tconst blobCountNew = formatNumber(res.blobCountNew).padStart(9);\n\n\t\t\t\tconsole.log(\n\t\t\t\t\t`${name.padEnd(\n\t\t\t\t\t\t15,\n\t\t\t\t\t)} | ${date} | ${size} | ${sizeNew} | ${blobCount} | ${blobCountNew}`,\n\t\t\t\t);\n\n\t\t\t\tawait saveSnapshot(name, blobs, saveDir);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (dumpSnapshotStats || dumpSnapshotTrees) {\n\t\tif (version === undefined) {\n\t\t\tconsole.log(\"No snapshot tree\");\n\t\t} else {\n\t\t\t// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions, @typescript-eslint/prefer-nullish-coalescing -- intentional behavior\n\t\t\tif (blobsToDump === undefined) {\n\t\t\t\tblobsToDump = await fetchBlobsFromVersion(storage, version);\n\t\t\t}\n\t\t\tconsole.log(`\\n\\nSnapshot version ${version.id}`);\n\t\t\tawait dumpSnapshotTreeVerbose(version.id, blobsToDump);\n\t\t}\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"fluidFetchSnapshot.js","sourceRoot":"","sources":["../src/fluidFetchSnapshot.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAQ9E,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EACN,iBAAiB,EACjB,iBAAiB,EACjB,oBAAoB,EACpB,qBAAqB,EACrB,wBAAwB,EACxB,yBAAyB,GACzB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AA8BvD,SAAS,aAAa,CAAC,WAAyB;IAC/C,OAAO,SAAS,IAAI,WAAW,CAAC;AACjC,CAAC;AAED,MAAM,SAAS,GAAG,IAAI,GAAG,EAAoC,CAAC;AAC9D,IAAI,iBAAiB,GAAG,IAAI,GAAG,EAAoC,CAAC;AACpE,IAAI,gBAAgB,GAAG,IAAI,GAAG,EAAoC,CAAC;AAEnE,SAAS,UAAU,CAClB,MAAc,EACd,IAAmB,EACnB,OAAgC,EAChC,SAA8B;IAE9B,MAAM,MAAM,GAAmB,EAAE,CAAC;IAClC,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACzD,MAAM,QAAQ,GAAG,GAAG,MAAM,GAAG,IAAI,EAAE,CAAC;QACpC,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YACrB,IAAI,MAAM,GAAG,IAAI,CAAC;YAClB,IAAI,IAAI,GAAG,iBAAiB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACzC,IAAI,CAAC,IAAI,EAAE,CAAC;gBACX,MAAM,GAAG,KAAK,CAAC;gBACf,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;gBAC7B,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;oBACxB,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;oBAChC,SAAS,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;gBAC7B,CAAC;YACF,CAAC;YACD,gBAAgB,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;YAEnC,4DAA4D;YAC5D,gEAAgE;YAChE,IAAI,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAClC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACzB,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC;gBACvB,SAAS,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;YAC9B,CAAC;YACD,MAAM,QAAQ,GAAG,GAAG,KAAK,IAAI,MAAM,EAAE,CAAC;YACtC,MAAM,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;YAE1D,mEAAmE;YACnE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC;QAC7B,CAAC;IACF,CAAC;IACD,OAAO,MAAM,CAAC;AACf,CAAC;AAED,SAAS,cAAc,CAAC,IAAmB,EAAE,MAAc,EAAE,OAAgB;IAC5E,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,IAAI,UAAU,CAAC;IACjC,MAAM,IAAI,GAAG,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;IAC1D,MAAM,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC;IACjD,MAAM,QAAQ,GAAG,GAAG,MAAM,GAAG,QAAQ,EAAE,CAAC;IACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,mBAAmB,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;AAC1F,CAAC;AAED,KAAK,UAAU,0BAA0B,CACxC,OAAgC,EAChC,IAAmB,EACnB,SAAiB,GAAG,EACpB,eAAqC;IAErC,MAAM,UAAU,GAAG,CAAC,eAAe,CAAC;IACpC,IAAI,UAAU,IAAI,iBAAiB,EAAE,CAAC;QACrC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACnB,CAAC;IAED,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;QACpB,iBAAiB,GAAG,gBAAgB,CAAC;QACrC,gBAAgB,GAAG,IAAI,GAAG,EAAoC,CAAC;IAChE,CAAC;IAED,oEAAoE;IACpE,IAAI,YAAsC,CAAC;IAC3C,IAAI,UAAU,EAAE,CAAC;QAChB,YAAY,GAAG,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;IACpD,CAAC;IAED,MAAM,SAAS,GAAG,eAAe,IAAI,IAAI,GAAG,EAAkB,CAAC;IAC/D,IAAI,MAAM,GAAmB,UAAU,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;IAE1E,KAAK,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC/D,MAAM,cAAc,GAAG,MAAM,0BAA0B,CACtD,OAAO,EACP,OAAO,EACP,GAAG,MAAM,GAAG,SAAS,GAAG,EACxB,SAAS,CACT,CAAC;QACF,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;IACxC,CAAC;IAED,IAAI,YAAY,EAAE,CAAC;QAClB,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC1B,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;IACjD,CAAC;IACD,OAAO,MAAM,CAAC;AACf,CAAC;AAED,SAAS,kBAAkB,CAAC,WAA2B;IACtD,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;IAChF,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AACvE,CAAC;AAED,KAAK,UAAU,uBAAuB,CACrC,IAAY,EACZ,WAA2B;IAE3B,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,MAAM,MAAM,GAAG,kBAAkB,CAAC,WAAW,CAAC,CAAC;IAE/C,IAAI,UAAU,GAAG,EAAE,CAAC;IACpB,KAAK,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC;QAC3B,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACzD,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,GAAG,WAAW,CAAC,MAAM,CAAC,UAAU,CAAC,wBAAwB,CAAC,CAAC;IACvE,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,GAAG,EAAE,CAAC,CAAC,CAAC;IACzC,KAAK,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC;QAC/B,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YAC1B,SAAS;QACV,CAAC;QACD,MAAM,IAAI,GAAG,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC5C,OAAO,CAAC,GAAG,CACV,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,SAAS,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,QAAQ,YAAY,CACtF,IAAI,CAAC,MAAM,CACX,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAChB,CAAC;QACF,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,GAAG,EAAE,CAAC,CAAC,CAAC;IACzC,OAAO,CAAC,GAAG,CACV,GAAG,qBAAqB,CAAC,MAAM,CAAC,UAAU,CAAC,eAAe,YAAY,CAAC,IAAI,CAAC,CAAC,QAAQ,CACpF,EAAE,CACF,EAAE,CACH,CAAC;AACH,CAAC;AAED,KAAK,UAAU,gBAAgB,CAC9B,IAAY,EACZ,WAA2B;IAE3B,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,MAAM,MAAM,GAAG,kBAAkB,CAAC,WAAW,CAAC,CAAC;IAE/C,KAAK,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC;QAC/B,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YAC1B,SAAS;QACV,CAAC;QACD,MAAM,IAAI,GAAG,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC5C,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YAClB,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC;YACvB,YAAY,EAAE,CAAC;QAChB,CAAC;QACD,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AAClE,CAAC;AAED,KAAK,UAAU,YAAY,CAC1B,IAAY,EACZ,WAA2B,EAC3B,OAAe;IAEf,MAAM,MAAM,GAAG,GAAG,OAAO,IAAI,IAAI,GAAG,CAAC;IACrC,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;IAEvC,MAAM,KAAK,CAAC,GAAG,MAAM,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACtD,MAAM,OAAO,CAAC,GAAG,CAChB,WAAW,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QAC9B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC;QAC/B,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YAC1B,OAAO,CAAC,KAAK,CAAC,sCAAsC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YACnE,OAAO;QACR,CAAC;QAED,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1B,6BAA6B;YAC7B,EAAE,CAAC,aAAa,CAAC,GAAG,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;YAEpE,sEAAsE;YACtE,yEAAyE;YACzE,IAAI,OAAO,GAAG,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YAC7C,IAAI,CAAC;gBACJ,IAAI,CAAC,qBAAqB,EAAE,CAAC;oBAC5B,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;gBAC7D,CAAC;YACF,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACZ,oDAAoD;YACrD,CAAC;YACD,EAAE,CAAC,aAAa,CAAC,GAAG,MAAM,YAAY,IAAI,CAAC,QAAQ,OAAO,EAAE,OAAO,CAAC,CAAC;QACtE,CAAC;aAAM,CAAC;YACP,qEAAqE;YACrE,MAAM,UAAU,GAAG,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YAClD,EAAE,CAAC,aAAa,CAAC,GAAG,MAAM,IAAI,IAAI,CAAC,QAAQ,OAAO,EAAE,UAAU,CAAC,CAAC;YAChE,EAAE,CAAC,aAAa,CACf,GAAG,MAAM,YAAY,IAAI,CAAC,QAAQ,OAAO,EACzC,qBAAqB;gBACpB,CAAC,CAAC,UAAU;gBACZ,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CACvD,CAAC;QACH,CAAC;IACF,CAAC,CAAC,CACF,CAAC;AACH,CAAC;AAED,KAAK,UAAU,qBAAqB,CACnC,OAAgC,EAChC,OAAiB;IAEjB,MAAM,IAAI,GAAG,MAAM,YAAY,CAC9B,mBAAmB,OAAO,CAAC,EAAE,EAAE,EAC/B,OAAO,CAAC,eAAe,CAAC,OAAO,CAAC,CAChC,CAAC;IACF,IAAI,CAAC,IAAI,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;IACjD,CAAC;IACD,OAAO,0BAA0B,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;AAClD,CAAC;AAED,KAAK,UAAU,YAAY,CAAI,OAAe,EAAE,GAAe;IAC9D,IAAI,CAAC;QACJ,OAAO,MAAM,GAAG,CAAC;IAClB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,OAAO,CAAC,KAAK,CAAC,iBAAiB,OAAO,EAAE,CAAC,CAAC;QAC1C,MAAM,KAAK,CAAC;IACb,CAAC;AACF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACvC,eAAkC,EAClC,OAAgB;IAEhB,IACC,CAAC,iBAAiB;QAClB,CAAC,iBAAiB;QAClB,CAAC,oBAAoB;QACrB,OAAO,KAAK,SAAS,EACpB,CAAC;QACF,OAAO;IACR,CAAC;IAED,4CAA4C;IAC5C,2BAA2B;IAC3B,8EAA8E;IAC9E,IAAI,CAAC,eAAe,EAAE,CAAC;QACtB,OAAO;IACR,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAElB,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC,gBAAgB,EAAE,CAAC;IAEzD,IAAI,OAA6B,CAAC;IAClC,MAAM,QAAQ,GAAG,MAAM,YAAY,CAClC,eAAe,gBAAgB,EAAE,EACjC,OAAO,CAAC,WAAW,CAAC,gBAAgB,EAAE,wBAAwB,CAAC,CAC/D,CAAC;IACF,IAAI,oBAAoB,EAAE,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;QACjC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACvB,CAAC;IAED,IAAI,WAAuC,CAAC;IAC5C,IAAI,yBAAyB,KAAK,SAAS,EAAE,CAAC;QAC7C,OAAO,GAAG,QAAQ,CAAC,yBAAyB,CAAC,CAAC;QAC9C,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC3B,OAAO,CAAC,GAAG,CACV,kBAAkB,QAAQ,CAAC,MAAM,iDAAiD,CAClF,CAAC;YACF,OAAO;QACR,CAAC;QACD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC3B,WAAW,GAAG,MAAM,qBAAqB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC5D,MAAM,IAAI,GAAG,OAAO,CAAC,EAAE,CAAC;YACxB,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,EAAE,CAAC,CAAC;YACvC,MAAM,YAAY,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;QAChD,CAAC;IACF,CAAC;SAAM,CAAC;QACP,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,OAAO,KAAK,SAAS,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClD,OAAO,CAAC,GAAG,CACV,0FAA0F,CAC1F,CAAC;YACF,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;YAE5B,2FAA2F;YAC3F,KAAK,IAAI,CAAC,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC/C,MAAM,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;gBACtB,MAAM,KAAK,GAAG,MAAM,qBAAqB,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;gBACtD,WAAW,GAAG,KAAK,CAAC;gBACpB,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC;gBAC5B,MAAM,GAAG,GAAG,MAAM,gBAAgB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;gBAEhD,IAAI,IAAI,GAAG,EAAE,CAAC;gBACd,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;oBAC1B,IAAI,CAAC;wBACJ,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,cAAc,EAAE,CAAC;oBAC1C,CAAC;oBAAC,OAAO,CAAC,EAAE,CAAC;wBACZ,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;wBAChC,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;wBACpC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;4BACf,IAAI,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC;wBACrC,CAAC;oBACF,CAAC;gBACF,CAAC;gBACD,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;gBACzB,MAAM,IAAI,GAAG,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;gBACjD,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;gBACvD,MAAM,SAAS,GAAG,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;gBAC1D,MAAM,YAAY,GAAG,YAAY,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;gBAEhE,OAAO,CAAC,GAAG,CACV,GAAG,IAAI,CAAC,MAAM,CACb,EAAE,CACF,MAAM,IAAI,MAAM,IAAI,MAAM,OAAO,MAAM,SAAS,MAAM,YAAY,EAAE,CACrE,CAAC;gBAEF,MAAM,YAAY,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;YAC1C,CAAC;QACF,CAAC;IACF,CAAC;IAED,IAAI,iBAAiB,IAAI,iBAAiB,EAAE,CAAC;QAC5C,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC3B,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;QACjC,CAAC;aAAM,CAAC;YACP,gGAAgG;YAChG,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;gBAC/B,WAAW,GAAG,MAAM,qBAAqB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC7D,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,wBAAwB,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;YAClD,MAAM,uBAAuB,CAAC,OAAO,CAAC,EAAE,EAAE,WAAW,CAAC,CAAC;QACxD,CAAC;IACF,CAAC;AACF,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport fs from \"fs\";\nimport util from \"util\";\n\nimport { bufferToString, stringToBuffer } from \"@fluid-internal/client-utils\";\nimport type {\n\tIDocumentService,\n\tIDocumentStorageService,\n\tISnapshotTree,\n\tIVersion,\n} from \"@fluidframework/driver-definitions/internal\";\n\nimport { formatNumber } from \"./fluidAnalyzeMessages.js\";\nimport {\n\tdumpSnapshotStats,\n\tdumpSnapshotTrees,\n\tdumpSnapshotVersions,\n\tparamActualFormatting,\n\tparamNumSnapshotVersions,\n\tparamSnapshotVersionIndex,\n} from \"./fluidFetchArgs.js\";\nimport { latestVersionsId } from \"./fluidFetchInit.js\";\n\ninterface ISnapshotInfo {\n\tblobCountNew: number;\n\tblobCount: number;\n\tsize: number;\n\tsizeNew: number;\n}\n\ntype IFetchedData = IFetchedBlob | IFetchedTree;\n\ninterface IFetchedBlob {\n\ttreePath: string;\n\tfilename: string;\n\tblobId: string;\n\tblob: Promise<ArrayBufferLike | undefined>;\n\treused: boolean;\n}\n\ninterface IFetchedTree {\n\ttreePath: string;\n\tblobId: string;\n\tfilename: string;\n\tblob: ArrayBufferLike;\n\n\treused: false;\n\n\tpatched: boolean;\n}\n\nfunction isFetchedTree(fetchedData: IFetchedData): fetchedData is IFetchedTree {\n\treturn \"patched\" in fetchedData;\n}\n\nconst blobCache = new Map<string, Promise<ArrayBufferLike>>();\nlet blobCachePrevious = new Map<string, Promise<ArrayBufferLike>>();\nlet blobCacheCurrent = new Map<string, Promise<ArrayBufferLike>>();\n\nfunction fetchBlobs(\n\tprefix: string,\n\ttree: ISnapshotTree,\n\tstorage: IDocumentStorageService,\n\tblobIdMap: Map<string, number>,\n): IFetchedBlob[] {\n\tconst result: IFetchedBlob[] = [];\n\tfor (const [item, blobId] of Object.entries(tree.blobs)) {\n\t\tconst treePath = `${prefix}${item}`;\n\t\tif (blobId !== null) {\n\t\t\tlet reused = true;\n\t\t\tlet blob = blobCachePrevious.get(blobId);\n\t\t\tif (!blob) {\n\t\t\t\treused = false;\n\t\t\t\tblob = blobCache.get(blobId);\n\t\t\t\tif (blob === undefined) {\n\t\t\t\t\tblob = storage.readBlob(blobId);\n\t\t\t\t\tblobCache.set(blobId, blob);\n\t\t\t\t}\n\t\t\t}\n\t\t\tblobCacheCurrent.set(blobId, blob);\n\n\t\t\t// Use the blobIdMap to assign a number for each unique blob\n\t\t\t// and use it as a prefix for files to avoid case-insensitive fs\n\t\t\tlet index = blobIdMap.get(blobId);\n\t\t\tif (index === undefined) {\n\t\t\t\tindex = blobIdMap.size;\n\t\t\t\tblobIdMap.set(blobId, index);\n\t\t\t}\n\t\t\tconst filename = `${index}-${blobId}`;\n\t\t\tresult.push({ treePath, blobId, blob, reused, filename });\n\n\t\t\t// patch the tree so that we can write it out to reference the file\n\t\t\ttree.blobs[item] = filename;\n\t\t}\n\t}\n\treturn result;\n}\n\nfunction createTreeBlob(tree: ISnapshotTree, prefix: string, patched: boolean): IFetchedTree {\n\tconst id = tree.id ?? \"original\";\n\tconst blob = stringToBuffer(JSON.stringify(tree), \"utf8\");\n\tconst filename = patched ? \"tree\" : `tree-${id}`;\n\tconst treePath = `${prefix}${filename}`;\n\treturn { treePath, blobId: \"original tree $id\", filename, blob, patched, reused: false };\n}\n\nasync function fetchBlobsFromSnapshotTree(\n\tstorage: IDocumentStorageService,\n\ttree: ISnapshotTree,\n\tprefix: string = \"/\",\n\tparentBlobIdMap?: Map<string, number>,\n): Promise<IFetchedData[]> {\n\tconst isTopLevel = !parentBlobIdMap;\n\tif (isTopLevel && dumpSnapshotTrees) {\n\t\tconsole.log(tree);\n\t}\n\n\tif (prefix === \"/\") {\n\t\tblobCachePrevious = blobCacheCurrent;\n\t\tblobCacheCurrent = new Map<string, Promise<ArrayBufferLike>>();\n\t}\n\n\t// Create the tree info before fetching blobs (which will modify it)\n\tlet topLevelBlob: IFetchedTree | undefined;\n\tif (isTopLevel) {\n\t\ttopLevelBlob = createTreeBlob(tree, prefix, false);\n\t}\n\n\tconst blobIdMap = parentBlobIdMap ?? new Map<string, number>();\n\tlet result: IFetchedData[] = fetchBlobs(prefix, tree, storage, blobIdMap);\n\n\tfor (const [subtreeId, subtree] of Object.entries(tree.trees)) {\n\t\tconst dataStoreBlobs = await fetchBlobsFromSnapshotTree(\n\t\t\tstorage,\n\t\t\tsubtree,\n\t\t\t`${prefix}${subtreeId}/`,\n\t\t\tblobIdMap,\n\t\t);\n\t\tresult = result.concat(dataStoreBlobs);\n\t}\n\n\tif (topLevelBlob) {\n\t\tresult.push(topLevelBlob);\n\t\tresult.push(createTreeBlob(tree, prefix, true));\n\t}\n\treturn result;\n}\n\nfunction getDumpFetchedData(fetchedData: IFetchedData[]): IFetchedData[] {\n\tconst sorted = fetchedData.sort((a, b) => a.treePath.localeCompare(b.treePath));\n\treturn sorted.filter((item) => !isFetchedTree(item) || !item.patched);\n}\n\nasync function dumpSnapshotTreeVerbose(\n\tname: string,\n\tfetchedData: IFetchedData[],\n): Promise<void> {\n\tlet size = 0;\n\tconst sorted = getDumpFetchedData(fetchedData);\n\n\tlet nameLength = 10;\n\tfor (const item of sorted) {\n\t\tnameLength = Math.max(nameLength, item.treePath.length);\n\t}\n\n\tconsole.log(\"\");\n\tconsole.log(`${\"Blob Path\".padEnd(nameLength)} | Reused | Bytes`);\n\tconsole.log(\"-\".repeat(nameLength + 26));\n\tfor (const item of sorted) {\n\t\tconst buffer = await item.blob;\n\t\tif (buffer === undefined) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst blob = bufferToString(buffer, \"utf8\");\n\t\tconsole.log(\n\t\t\t`${item.treePath.padEnd(nameLength)} | ${item.reused ? \"X\" : \" \"} | ${formatNumber(\n\t\t\t\tblob.length,\n\t\t\t).padStart(10)}`,\n\t\t);\n\t\tsize += blob.length;\n\t}\n\n\tconsole.log(\"-\".repeat(nameLength + 26));\n\tconsole.log(\n\t\t`${\"Total snapshot size\".padEnd(nameLength)} | | ${formatNumber(size).padStart(\n\t\t\t10,\n\t\t)}`,\n\t);\n}\n\nasync function dumpSnapshotTree(\n\tname: string,\n\tfetchedData: IFetchedData[],\n): Promise<ISnapshotInfo> {\n\tlet size = 0;\n\tlet sizeNew = 0;\n\tlet blobCountNew = 0;\n\tconst sorted = getDumpFetchedData(fetchedData);\n\n\tfor (const item of sorted) {\n\t\tconst buffer = await item.blob;\n\t\tif (buffer === undefined) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst blob = bufferToString(buffer, \"utf8\");\n\t\tif (!item.reused) {\n\t\t\tsizeNew += blob.length;\n\t\t\tblobCountNew++;\n\t\t}\n\t\tsize += blob.length;\n\t}\n\n\treturn { blobCountNew, blobCount: sorted.length, size, sizeNew };\n}\n\nasync function saveSnapshot(\n\tname: string,\n\tfetchedData: IFetchedData[],\n\tsaveDir: string,\n): Promise<void> {\n\tconst outDir = `${saveDir}/${name}/`;\n\tconst mkdir = util.promisify(fs.mkdir);\n\n\tawait mkdir(`${outDir}/decoded`, { recursive: true });\n\tawait Promise.all(\n\t\tfetchedData.map(async (item) => {\n\t\t\tconst buffer = await item.blob;\n\t\t\tif (buffer === undefined) {\n\t\t\t\tconsole.error(`ERROR: Unable to get data for blob ${item.blobId}`);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (!isFetchedTree(item)) {\n\t\t\t\t// Just write the data as is.\n\t\t\t\tfs.writeFileSync(`${outDir}/${item.filename}`, Buffer.from(buffer));\n\n\t\t\t\t// we assume that the buffer is utf8 here, which currently is true for\n\t\t\t\t// all of our snapshot blobs. It doesn't necessary be true in the future\n\t\t\t\tlet decoded = bufferToString(buffer, \"utf8\");\n\t\t\t\ttry {\n\t\t\t\t\tif (!paramActualFormatting) {\n\t\t\t\t\t\tdecoded = JSON.stringify(JSON.parse(decoded), undefined, 2);\n\t\t\t\t\t}\n\t\t\t\t} catch (e) {\n\t\t\t\t\t// TODO: document why we are ignoring the error here\n\t\t\t\t}\n\t\t\t\tfs.writeFileSync(`${outDir}/decoded/${item.filename}.json`, decoded);\n\t\t\t} else {\n\t\t\t\t// Write out same data for tree decoded or not, except for formatting\n\t\t\t\tconst treeString = bufferToString(buffer, \"utf8\");\n\t\t\t\tfs.writeFileSync(`${outDir}/${item.filename}.json`, treeString);\n\t\t\t\tfs.writeFileSync(\n\t\t\t\t\t`${outDir}/decoded/${item.filename}.json`,\n\t\t\t\t\tparamActualFormatting\n\t\t\t\t\t\t? treeString\n\t\t\t\t\t\t: JSON.stringify(JSON.parse(treeString), undefined, 2),\n\t\t\t\t);\n\t\t\t}\n\t\t}),\n\t);\n}\n\nasync function fetchBlobsFromVersion(\n\tstorage: IDocumentStorageService,\n\tversion: IVersion,\n): Promise<IFetchedData[]> {\n\tconst tree = await reportErrors(\n\t\t`getSnapshotTree ${version.id}`,\n\t\tstorage.getSnapshotTree(version),\n\t);\n\tif (!tree) {\n\t\tthrow new Error(\"Failed to load snapshot tree\");\n\t}\n\treturn fetchBlobsFromSnapshotTree(storage, tree);\n}\n\nasync function reportErrors<T>(message: string, res: Promise<T>): Promise<T> {\n\ttry {\n\t\treturn await res;\n\t} catch (error) {\n\t\tconsole.error(`Error calling ${message}`);\n\t\tthrow error;\n\t}\n}\n\nexport async function fluidFetchSnapshot(\n\tdocumentService?: IDocumentService,\n\tsaveDir?: string,\n): Promise<void> {\n\tif (\n\t\t!dumpSnapshotStats &&\n\t\t!dumpSnapshotTrees &&\n\t\t!dumpSnapshotVersions &&\n\t\tsaveDir === undefined\n\t) {\n\t\treturn;\n\t}\n\n\t// --local mode - do not connect to storage.\n\t// For now, bail out early.\n\t// In future, separate download from analyzes parts and allow offline analyzes\n\tif (!documentService) {\n\t\treturn;\n\t}\n\n\tconsole.log(\"\\n\");\n\n\tconst storage = await documentService.connectToStorage();\n\n\tlet version: IVersion | undefined;\n\tconst versions = await reportErrors(\n\t\t`getVersions ${latestVersionsId}`,\n\t\tstorage.getVersions(latestVersionsId, paramNumSnapshotVersions),\n\t);\n\tif (dumpSnapshotVersions) {\n\t\tconsole.log(\"Snapshot versions\");\n\t\tconsole.log(versions);\n\t}\n\n\tlet blobsToDump: IFetchedData[] | undefined;\n\tif (paramSnapshotVersionIndex !== undefined) {\n\t\tversion = versions[paramSnapshotVersionIndex];\n\t\tif (version === undefined) {\n\t\t\tconsole.log(\n\t\t\t\t`There are only ${versions.length} snapshots, --snapshotVersionIndex is too large`,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\tif (saveDir !== undefined) {\n\t\t\tblobsToDump = await fetchBlobsFromVersion(storage, version);\n\t\t\tconst name = version.id;\n\t\t\tconsole.log(`Saving snapshot ${name}`);\n\t\t\tawait saveSnapshot(name, blobsToDump, saveDir);\n\t\t}\n\t} else {\n\t\tversion = versions[0];\n\t\tif (saveDir !== undefined && versions.length > 0) {\n\t\t\tconsole.log(\n\t\t\t\t\" Name | Date | Size | New Size | Blobs | New Blobs\",\n\t\t\t);\n\t\t\tconsole.log(\"-\".repeat(86));\n\n\t\t\t// Go in reverse order, to correctly calculate blob reuse - from oldest to newest snapshots\n\t\t\tfor (let i = versions.length - 1; i >= 0; i--) {\n\t\t\t\tconst v = versions[i];\n\t\t\t\tconst blobs = await fetchBlobsFromVersion(storage, v);\n\t\t\t\tblobsToDump = blobs;\n\t\t\t\tconst name = `${i}-${v.id}`;\n\t\t\t\tconst res = await dumpSnapshotTree(name, blobs);\n\n\t\t\t\tlet date = \"\";\n\t\t\t\tif (v.date !== undefined) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tdate = new Date(v.date).toLocaleString();\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\tdate = v.date.replace(\"T\", \" \");\n\t\t\t\t\t\tconst index = date.lastIndexOf(\".\");\n\t\t\t\t\t\tif (index > 0) {\n\t\t\t\t\t\t\tdate = `${date.substr(0, index)} Z`;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tdate = date.padStart(23);\n\t\t\t\tconst size = formatNumber(res.size).padStart(10);\n\t\t\t\tconst sizeNew = formatNumber(res.sizeNew).padStart(10);\n\t\t\t\tconst blobCount = formatNumber(res.blobCount).padStart(6);\n\t\t\t\tconst blobCountNew = formatNumber(res.blobCountNew).padStart(9);\n\n\t\t\t\tconsole.log(\n\t\t\t\t\t`${name.padEnd(\n\t\t\t\t\t\t15,\n\t\t\t\t\t)} | ${date} | ${size} | ${sizeNew} | ${blobCount} | ${blobCountNew}`,\n\t\t\t\t);\n\n\t\t\t\tawait saveSnapshot(name, blobs, saveDir);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (dumpSnapshotStats || dumpSnapshotTrees) {\n\t\tif (version === undefined) {\n\t\t\tconsole.log(\"No snapshot tree\");\n\t\t} else {\n\t\t\t// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- intentional behavior\n\t\t\tif (blobsToDump === undefined) {\n\t\t\t\tblobsToDump = await fetchBlobsFromVersion(storage, version);\n\t\t\t}\n\t\t\tconsole.log(`\\n\\nSnapshot version ${version.id}`);\n\t\t\tawait dumpSnapshotTreeVerbose(version.id, blobsToDump);\n\t\t}\n\t}\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluid-tools/fetch-tool",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.91.0",
|
|
4
4
|
"description": "Console tool to fetch Fluid data from relay service",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
6
|
"repository": {
|
|
@@ -17,33 +17,33 @@
|
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"@azure/identity": "^4.4.1",
|
|
19
19
|
"@azure/identity-cache-persistence": "^1.1.0",
|
|
20
|
-
"@fluid-internal/client-utils": "2.
|
|
21
|
-
"@fluidframework/container-runtime": "2.
|
|
22
|
-
"@fluidframework/core-interfaces": "2.
|
|
23
|
-
"@fluidframework/core-utils": "2.
|
|
24
|
-
"@fluidframework/datastore": "2.
|
|
25
|
-
"@fluidframework/driver-definitions": "2.
|
|
26
|
-
"@fluidframework/odsp-doclib-utils": "2.
|
|
27
|
-
"@fluidframework/odsp-driver": "2.
|
|
28
|
-
"@fluidframework/odsp-driver-definitions": "2.
|
|
29
|
-
"@fluidframework/odsp-urlresolver": "2.
|
|
30
|
-
"@fluidframework/routerlicious-driver": "2.
|
|
31
|
-
"@fluidframework/routerlicious-urlresolver": "2.
|
|
32
|
-
"@fluidframework/runtime-definitions": "2.
|
|
33
|
-
"@fluidframework/tool-utils": "2.
|
|
20
|
+
"@fluid-internal/client-utils": "~2.91.0",
|
|
21
|
+
"@fluidframework/container-runtime": "~2.91.0",
|
|
22
|
+
"@fluidframework/core-interfaces": "~2.91.0",
|
|
23
|
+
"@fluidframework/core-utils": "~2.91.0",
|
|
24
|
+
"@fluidframework/datastore": "~2.91.0",
|
|
25
|
+
"@fluidframework/driver-definitions": "~2.91.0",
|
|
26
|
+
"@fluidframework/odsp-doclib-utils": "~2.91.0",
|
|
27
|
+
"@fluidframework/odsp-driver": "~2.91.0",
|
|
28
|
+
"@fluidframework/odsp-driver-definitions": "~2.91.0",
|
|
29
|
+
"@fluidframework/odsp-urlresolver": "~2.91.0",
|
|
30
|
+
"@fluidframework/routerlicious-driver": "~2.91.0",
|
|
31
|
+
"@fluidframework/routerlicious-urlresolver": "~2.91.0",
|
|
32
|
+
"@fluidframework/runtime-definitions": "~2.91.0",
|
|
33
|
+
"@fluidframework/tool-utils": "~2.91.0"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
|
-
"@biomejs/biome": "~
|
|
36
|
+
"@biomejs/biome": "~2.4.5",
|
|
37
37
|
"@fluid-tools/build-cli": "^0.63.0",
|
|
38
|
-
"@fluid-tools/fetch-tool-previous": "npm:@fluid-tools/fetch-tool@2.
|
|
38
|
+
"@fluid-tools/fetch-tool-previous": "npm:@fluid-tools/fetch-tool@2.83.0",
|
|
39
39
|
"@fluidframework/build-common": "^2.0.3",
|
|
40
40
|
"@fluidframework/build-tools": "^0.63.0",
|
|
41
|
-
"@fluidframework/eslint-config-fluid": "2.
|
|
41
|
+
"@fluidframework/eslint-config-fluid": "~2.91.0",
|
|
42
42
|
"@types/node": "~20.19.30",
|
|
43
43
|
"copyfiles": "^2.4.1",
|
|
44
44
|
"eslint": "~9.39.1",
|
|
45
45
|
"jiti": "^2.6.1",
|
|
46
|
-
"rimraf": "^6.1.
|
|
46
|
+
"rimraf": "^6.1.3",
|
|
47
47
|
"typescript": "~5.4.5"
|
|
48
48
|
},
|
|
49
49
|
"typeValidation": {
|
|
@@ -385,7 +385,7 @@ export async function fluidFetchSnapshot(
|
|
|
385
385
|
if (version === undefined) {
|
|
386
386
|
console.log("No snapshot tree");
|
|
387
387
|
} else {
|
|
388
|
-
// eslint-disable-next-line @typescript-eslint/
|
|
388
|
+
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- intentional behavior
|
|
389
389
|
if (blobsToDump === undefined) {
|
|
390
390
|
blobsToDump = await fetchBlobsFromVersion(storage, version);
|
|
391
391
|
}
|