@fluidframework/odsp-driver 1.2.0-78837 → 1.2.2

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.
@@ -1 +1 @@
1
- {"version":3,"file":"compactSnapshotParser.d.ts","sourceRoot":"","sources":["../src/compactSnapshotParser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAa/C,eAAO,MAAM,sBAAsB,QAAQ,CAAC;AAC5C,eAAO,MAAM,kBAAkB,QAAQ,CAAC;AAgGxC;;;;GAIG;AACH,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,UAAU,GAAG,iBAAiB,CA2BlF"}
1
+ {"version":3,"file":"compactSnapshotParser.d.ts","sourceRoot":"","sources":["../src/compactSnapshotParser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAa/C,eAAO,MAAM,sBAAsB,QAAQ,CAAC;AAC5C,eAAO,MAAM,kBAAkB,QAAQ,CAAC;AAkGxC;;;;GAIG;AACH,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,UAAU,GAAG,iBAAiB,CA2BlF"}
@@ -60,10 +60,13 @@ function readTreeSection(node) {
60
60
  (0, zipItDataRepresentationUtils_1.assertBlobCoreInstance)(records.value, "Blob value should be BlobCore");
61
61
  snapshotTree.blobs[path] = records.value.toString();
62
62
  }
63
- else {
63
+ else if (records.children !== undefined) {
64
64
  (0, zipItDataRepresentationUtils_1.assertNodeCoreInstance)(records.children, "Trees should be of type NodeCore");
65
65
  snapshotTree.trees[path] = readTreeSection(records.children);
66
66
  }
67
+ else {
68
+ snapshotTree.trees[path] = { blobs: {}, commits: {}, trees: {} };
69
+ }
67
70
  if (records.unreferenced !== undefined) {
68
71
  (0, zipItDataRepresentationUtils_1.assertBoolInstance)(records.unreferenced, "Unreferenced flag should be bool");
69
72
  const unreferenced = records.unreferenced.valueOf();
@@ -1 +1 @@
1
- {"version":3,"file":"compactSnapshotParser.js","sourceRoot":"","sources":["../src/compactSnapshotParser.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/common-utils\";\nimport { ISequencedDocumentMessage, ISnapshotTree } from \"@fluidframework/protocol-definitions\";\nimport { ISnapshotContents } from \"./odspPublicUtils\";\nimport { ReadBuffer } from \"./ReadBufferUtils\";\nimport { ISnapshotTreeEx } from \"./contracts\";\nimport {\n assertBlobCoreInstance,\n assertBoolInstance,\n assertNodeCoreInstance,\n assertNumberInstance,\n getAndValidateNodeProps,\n NodeCore,\n NodeTypes,\n TreeBuilder,\n} from \"./zipItDataRepresentationUtils\";\n\nexport const snapshotMinReadVersion = \"1.0\";\nexport const currentReadVersion = \"1.0\";\n\ninterface ISnapshotSection {\n snapshotTree: ISnapshotTree;\n sequenceNumber: number;\n}\n\n/**\n * Recreates blobs section of the tree.\n * @param node - tree node to read blob section from\n */\nfunction readBlobSection(node: NodeTypes) {\n assertNodeCoreInstance(node, \"TreeBlobs should be of type NodeCore\");\n const blobs: Map<string, ArrayBuffer> = new Map();\n for (let count = 0; count < node.length; ++count) {\n const blob = node.getNode(count);\n const records = getAndValidateNodeProps(blob, [\"id\", \"data\"]);\n assertBlobCoreInstance(records.data, \"data should be of BlobCore type\");\n assertBlobCoreInstance(records.id, \"blob id should be of BlobCore type\");\n blobs.set(records.id.toString(), records.data.arrayBuffer);\n }\n return blobs;\n}\n\n/**\n * Recreates ops section of the tree.\n * @param node - tree node to read ops section from\n */\nfunction readOpsSection(node: NodeTypes) {\n assertNodeCoreInstance(node, \"Deltas should be of type NodeCore\");\n const ops: ISequencedDocumentMessage[] = [];\n const records = getAndValidateNodeProps(node, [\"firstSequenceNumber\", \"deltas\"]);\n assertNumberInstance(records.firstSequenceNumber, \"Seq number should be a number\");\n assertNodeCoreInstance(records.deltas, \"Deltas should be a Node\");\n for (let i = 0; i < records.deltas.length; ++i) {\n ops.push(JSON.parse(records.deltas.getString(i)));\n }\n assert(records.firstSequenceNumber.valueOf() === ops[0].sequenceNumber,\n 0x280 /* \"Validate first op seq number\" */);\n return ops;\n}\n\n/**\n * Recreates snapshot tree out of tree representation.\n * @param node - tree node to de-serialize from\n */\nfunction readTreeSection(node: NodeCore) {\n const snapshotTree: ISnapshotTreeEx = {\n blobs: {},\n commits: {},\n trees: {},\n };\n for (let count = 0; count < node.length; count++) {\n const treeNode = node.getNode(count);\n const records = getAndValidateNodeProps(treeNode,\n [\"name\", \"value\", \"children\", \"unreferenced\"], false);\n assertBlobCoreInstance(records.name, \"Path should be of BlobCore\");\n const path = records.name.toString();\n if (records.value !== undefined) {\n assertBlobCoreInstance(records.value, \"Blob value should be BlobCore\");\n snapshotTree.blobs[path] = records.value.toString();\n } else {\n assertNodeCoreInstance(records.children, \"Trees should be of type NodeCore\");\n snapshotTree.trees[path] = readTreeSection(records.children);\n }\n if (records.unreferenced !== undefined) {\n assertBoolInstance(records.unreferenced, \"Unreferenced flag should be bool\");\n const unreferenced = records.unreferenced.valueOf();\n assert(unreferenced, 0x281 /* \"Unreferenced if present should be true\" */);\n snapshotTree.unreferenced = unreferenced;\n }\n }\n return snapshotTree;\n}\n\n/**\n * Recreates snapshot tree out of tree representation.\n * @param node - tree node to de-serialize from\n */\nfunction readSnapshotSection(node: NodeTypes): ISnapshotSection {\n assertNodeCoreInstance(node, \"Snapshot should be of type NodeCore\");\n const records = getAndValidateNodeProps(node,\n [\"id\", \"sequenceNumber\", \"treeNodes\"]);\n\n assertNodeCoreInstance(records.treeNodes, \"TreeNodes should be of type NodeCore\");\n assertNumberInstance(records.sequenceNumber, \"sequenceNumber should be of type number\");\n assertBlobCoreInstance(records.id, \"snapshotId should be BlobCore\");\n const snapshotTree: ISnapshotTree = readTreeSection(records.treeNodes);\n snapshotTree.id = records.id.toString();\n const sequenceNumber = records.sequenceNumber.valueOf();\n return {\n sequenceNumber,\n snapshotTree,\n };\n}\n\n/**\n * Converts snapshot from binary compact representation to tree/blobs/ops.\n * @param buffer - Compact snapshot to be parsed into tree/blobs/ops.\n * @returns - tree, blobs and ops from the snapshot.\n */\nexport function parseCompactSnapshotResponse(buffer: ReadBuffer): ISnapshotContents {\n const builder = TreeBuilder.load(buffer);\n assert(builder.length === 1, 0x219 /* \"1 root should be there\" */);\n const root = builder.getNode(0);\n\n const records = getAndValidateNodeProps(root,\n [\"mrv\", \"cv\", \"lsn\", \"snapshot\", \"blobs\", \"deltas\"], false);\n\n assertBlobCoreInstance(records.mrv, \"minReadVersion should be of BlobCore type\");\n assertBlobCoreInstance(records.cv, \"createVersion should be of BlobCore type\");\n if (records.lsn !== undefined) {\n assertNumberInstance(records.lsn, \"lsn should be a number\");\n }\n\n assert(parseFloat(snapshotMinReadVersion) >= parseFloat(records.mrv.toString()),\n 0x20f /* \"Driver min read version should >= to server minReadVersion\" */);\n assert(parseFloat(records.cv.toString()) >= parseFloat(snapshotMinReadVersion),\n 0x210 /* \"Snapshot should be created with minReadVersion or above\" */);\n assert(currentReadVersion === records.cv.toString(),\n 0x2c2 /* \"Create Version should be equal to currentReadVersion\" */);\n\n return {\n ...readSnapshotSection(records.snapshot),\n blobs: readBlobSection(records.blobs),\n ops: records.deltas !== undefined ? readOpsSection(records.deltas) : [],\n latestSequenceNumber: records.lsn,\n };\n}\n"]}
1
+ {"version":3,"file":"compactSnapshotParser.js","sourceRoot":"","sources":["../src/compactSnapshotParser.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/common-utils\";\nimport { ISequencedDocumentMessage, ISnapshotTree } from \"@fluidframework/protocol-definitions\";\nimport { ISnapshotContents } from \"./odspPublicUtils\";\nimport { ReadBuffer } from \"./ReadBufferUtils\";\nimport { ISnapshotTreeEx } from \"./contracts\";\nimport {\n assertBlobCoreInstance,\n assertBoolInstance,\n assertNodeCoreInstance,\n assertNumberInstance,\n getAndValidateNodeProps,\n NodeCore,\n NodeTypes,\n TreeBuilder,\n} from \"./zipItDataRepresentationUtils\";\n\nexport const snapshotMinReadVersion = \"1.0\";\nexport const currentReadVersion = \"1.0\";\n\ninterface ISnapshotSection {\n snapshotTree: ISnapshotTree;\n sequenceNumber: number;\n}\n\n/**\n * Recreates blobs section of the tree.\n * @param node - tree node to read blob section from\n */\nfunction readBlobSection(node: NodeTypes) {\n assertNodeCoreInstance(node, \"TreeBlobs should be of type NodeCore\");\n const blobs: Map<string, ArrayBuffer> = new Map();\n for (let count = 0; count < node.length; ++count) {\n const blob = node.getNode(count);\n const records = getAndValidateNodeProps(blob, [\"id\", \"data\"]);\n assertBlobCoreInstance(records.data, \"data should be of BlobCore type\");\n assertBlobCoreInstance(records.id, \"blob id should be of BlobCore type\");\n blobs.set(records.id.toString(), records.data.arrayBuffer);\n }\n return blobs;\n}\n\n/**\n * Recreates ops section of the tree.\n * @param node - tree node to read ops section from\n */\nfunction readOpsSection(node: NodeTypes) {\n assertNodeCoreInstance(node, \"Deltas should be of type NodeCore\");\n const ops: ISequencedDocumentMessage[] = [];\n const records = getAndValidateNodeProps(node, [\"firstSequenceNumber\", \"deltas\"]);\n assertNumberInstance(records.firstSequenceNumber, \"Seq number should be a number\");\n assertNodeCoreInstance(records.deltas, \"Deltas should be a Node\");\n for (let i = 0; i < records.deltas.length; ++i) {\n ops.push(JSON.parse(records.deltas.getString(i)));\n }\n assert(records.firstSequenceNumber.valueOf() === ops[0].sequenceNumber,\n 0x280 /* \"Validate first op seq number\" */);\n return ops;\n}\n\n/**\n * Recreates snapshot tree out of tree representation.\n * @param node - tree node to de-serialize from\n */\nfunction readTreeSection(node: NodeCore) {\n const snapshotTree: ISnapshotTreeEx = {\n blobs: {},\n commits: {},\n trees: {},\n };\n for (let count = 0; count < node.length; count++) {\n const treeNode = node.getNode(count);\n const records = getAndValidateNodeProps(treeNode,\n [\"name\", \"value\", \"children\", \"unreferenced\"], false);\n assertBlobCoreInstance(records.name, \"Path should be of BlobCore\");\n const path = records.name.toString();\n if (records.value !== undefined) {\n assertBlobCoreInstance(records.value, \"Blob value should be BlobCore\");\n snapshotTree.blobs[path] = records.value.toString();\n } else if (records.children !== undefined) {\n assertNodeCoreInstance(records.children, \"Trees should be of type NodeCore\");\n snapshotTree.trees[path] = readTreeSection(records.children);\n } else {\n snapshotTree.trees[path] = { blobs: {}, commits: {}, trees: {} };\n }\n if (records.unreferenced !== undefined) {\n assertBoolInstance(records.unreferenced, \"Unreferenced flag should be bool\");\n const unreferenced = records.unreferenced.valueOf();\n assert(unreferenced, 0x281 /* \"Unreferenced if present should be true\" */);\n snapshotTree.unreferenced = unreferenced;\n }\n }\n return snapshotTree;\n}\n\n/**\n * Recreates snapshot tree out of tree representation.\n * @param node - tree node to de-serialize from\n */\nfunction readSnapshotSection(node: NodeTypes): ISnapshotSection {\n assertNodeCoreInstance(node, \"Snapshot should be of type NodeCore\");\n const records = getAndValidateNodeProps(node,\n [\"id\", \"sequenceNumber\", \"treeNodes\"]);\n\n assertNodeCoreInstance(records.treeNodes, \"TreeNodes should be of type NodeCore\");\n assertNumberInstance(records.sequenceNumber, \"sequenceNumber should be of type number\");\n assertBlobCoreInstance(records.id, \"snapshotId should be BlobCore\");\n const snapshotTree: ISnapshotTree = readTreeSection(records.treeNodes);\n snapshotTree.id = records.id.toString();\n const sequenceNumber = records.sequenceNumber.valueOf();\n return {\n sequenceNumber,\n snapshotTree,\n };\n}\n\n/**\n * Converts snapshot from binary compact representation to tree/blobs/ops.\n * @param buffer - Compact snapshot to be parsed into tree/blobs/ops.\n * @returns - tree, blobs and ops from the snapshot.\n */\nexport function parseCompactSnapshotResponse(buffer: ReadBuffer): ISnapshotContents {\n const builder = TreeBuilder.load(buffer);\n assert(builder.length === 1, 0x219 /* \"1 root should be there\" */);\n const root = builder.getNode(0);\n\n const records = getAndValidateNodeProps(root,\n [\"mrv\", \"cv\", \"lsn\", \"snapshot\", \"blobs\", \"deltas\"], false);\n\n assertBlobCoreInstance(records.mrv, \"minReadVersion should be of BlobCore type\");\n assertBlobCoreInstance(records.cv, \"createVersion should be of BlobCore type\");\n if (records.lsn !== undefined) {\n assertNumberInstance(records.lsn, \"lsn should be a number\");\n }\n\n assert(parseFloat(snapshotMinReadVersion) >= parseFloat(records.mrv.toString()),\n 0x20f /* \"Driver min read version should >= to server minReadVersion\" */);\n assert(parseFloat(records.cv.toString()) >= parseFloat(snapshotMinReadVersion),\n 0x210 /* \"Snapshot should be created with minReadVersion or above\" */);\n assert(currentReadVersion === records.cv.toString(),\n 0x2c2 /* \"Create Version should be equal to currentReadVersion\" */);\n\n return {\n ...readSnapshotSection(records.snapshot),\n blobs: readBlobSection(records.blobs),\n ops: records.deltas !== undefined ? readOpsSection(records.deltas) : [],\n latestSequenceNumber: records.lsn,\n };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"compactSnapshotWriter.d.ts","sourceRoot":"","sources":["../src/compactSnapshotWriter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAkH/C;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,gBAAgB,EAAE,iBAAiB,GAAG,UAAU,CAyBxF"}
1
+ {"version":3,"file":"compactSnapshotWriter.d.ts","sourceRoot":"","sources":["../src/compactSnapshotWriter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAqH/C;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,gBAAgB,EAAE,iBAAiB,GAAG,UAAU,CAyBxF"}
@@ -57,9 +57,12 @@ function writeTreeSectionCore(treesNode, snapshotTree) {
57
57
  if (snapshotTree.unreferenced) {
58
58
  (0, zipItDataRepresentationUtils_1.addBoolProperty)(treeNode, "unreferenced", snapshotTree.unreferenced);
59
59
  }
60
- treeNode.addString("children", true);
61
- const childNode = treeNode.addNode("list");
62
- writeTreeSectionCore(childNode, value);
60
+ // Only write children prop if either blobs or trees are present.
61
+ if (Object.keys(value.blobs).length > 0 || Object.keys(value.trees).length > 0) {
62
+ treeNode.addString("children", true);
63
+ const childNode = treeNode.addNode("list");
64
+ writeTreeSectionCore(childNode, value);
65
+ }
63
66
  }
64
67
  if (snapshotTree.blobs) {
65
68
  for (const [path, id] of Object.entries(snapshotTree.blobs)) {
@@ -1 +1 @@
1
- {"version":3,"file":"compactSnapshotWriter.js","sourceRoot":"","sources":["../src/compactSnapshotWriter.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert, stringToBuffer } from \"@fluidframework/common-utils\";\nimport { IBlob, ISequencedDocumentMessage, ISnapshotTree } from \"@fluidframework/protocol-definitions\";\nimport { snapshotMinReadVersion } from \"./compactSnapshotParser\";\nimport { ISnapshotContents } from \"./odspPublicUtils\";\nimport { ReadBuffer } from \"./ReadBufferUtils\";\nimport { TreeBuilderSerializer } from \"./WriteBufferUtils\";\nimport { addBoolProperty, addNumberProperty, addStringProperty, NodeCore } from \"./zipItDataRepresentationUtils\";\n\n/**\n * Writes header section of the snapshot.\n * @param node - snapshot node to serialize to\n * @param latestSequenceNumber - latest seq number of the container.\n*/\nfunction writeSnapshotProps(node: NodeCore, latestSequenceNumber: number) {\n addStringProperty(node, \"mrv\", snapshotMinReadVersion);\n addStringProperty(node, \"cv\", snapshotMinReadVersion);\n addNumberProperty(node, \"lsn\", latestSequenceNumber);\n}\n\n/**\n * Represents blobs in the tree.\n * @param snapshotNode - node to serialize to.\n * @param blobs - blobs that is being serialized\n*/\nfunction writeBlobsSection(snapshotNode: NodeCore, blobs: Map<string, IBlob | ArrayBuffer>) {\n snapshotNode.addString(\"blobs\", true);\n const blobsNode = snapshotNode.addNode(\"list\");\n for (const [storageBlobId, blob] of blobs) {\n const blobNode = blobsNode.addNode();\n addStringProperty(blobNode, \"id\", storageBlobId, true);\n blobNode.addString(\"data\", true);\n if (blob instanceof ArrayBuffer) {\n blobNode.addBlob(new Uint8Array(blob), false);\n } else {\n blobNode.addBlob(new Uint8Array(stringToBuffer(blob.contents, blob.encoding ?? \"utf-8\")), false);\n }\n }\n}\n\n/**\n * Represents and serializes tree part of the snapshot\n * @param snapshotNode - tree node to serialize to\n * @param snapshotTree - snapshot tree that is being serialized\n*/\nfunction writeTreeSection(snapshotNode: NodeCore, snapshotTree: ISnapshotTree) {\n snapshotNode.addString(\"treeNodes\", true);\n const treesNode = snapshotNode.addNode(\"list\");\n writeTreeSectionCore(treesNode, snapshotTree);\n}\n\nfunction writeTreeSectionCore(treesNode: NodeCore, snapshotTree: ISnapshotTree) {\n for (const [path, value] of Object.entries(snapshotTree.trees)) {\n const treeNode = treesNode.addNode();\n addStringProperty(treeNode, \"name\", path);\n if (snapshotTree.unreferenced) {\n addBoolProperty(treeNode, \"unreferenced\", snapshotTree.unreferenced);\n }\n treeNode.addString(\"children\", true);\n const childNode = treeNode.addNode(\"list\");\n writeTreeSectionCore(childNode, value);\n }\n\n if (snapshotTree.blobs) {\n for (const [path, id] of Object.entries(snapshotTree.blobs)) {\n const blobNode = treesNode.addNode();\n addStringProperty(blobNode, \"name\", path);\n addStringProperty(blobNode, \"value\", id, true);\n }\n }\n}\n\n/**\n * Represents (serializes) snapshot tree as generalizes tree\n * @param rootNode - tree node to serialize to\n * @param snapshotTree - snapshot tree that is being serialized\n * @param blobs - blobs mapping of the snapshot\n * @param snapshotSequenceNumber - seq number at which snapshot is taken\n*/\nfunction writeSnapshotSection(\n rootNode: NodeCore,\n snapshotTree: ISnapshotTree,\n snapshotSequenceNumber: number,\n) {\n rootNode.addString(\"snapshot\", true);\n const snapshotNode = rootNode.addNode();\n\n const snapshotId = snapshotTree.id;\n assert(snapshotId !== undefined, 0x21b /* \"Snapshot id should be provided\" */);\n addStringProperty(snapshotNode, \"id\", snapshotId);\n addStringProperty(snapshotNode, \"message\", `Snapshot@${snapshotSequenceNumber}`);\n addNumberProperty(snapshotNode, \"sequenceNumber\", snapshotSequenceNumber);\n\n // Add Trees\n writeTreeSection(snapshotNode, snapshotTree);\n}\n\n/**\n * Represents ops in the tree.\n * @param rootNode - node to serialize to.\n * @param ops - ops that is being serialized\n*/\nfunction writeOpsSection(rootNode: NodeCore, ops: ISequencedDocumentMessage[]) {\n let firstSequenceNumber: number | undefined;\n if (ops.length > 0) {\n firstSequenceNumber = ops[0].sequenceNumber;\n }\n if (firstSequenceNumber !== undefined) {\n rootNode.addString(\"deltas\", true);\n const opsNode = rootNode.addNode();\n addNumberProperty(opsNode, \"firstSequenceNumber\", firstSequenceNumber);\n opsNode.addString(\"deltas\", true);\n const deltaNode = opsNode.addNode(\"list\");\n ops.forEach((op) => {\n deltaNode.addString(JSON.stringify(op), false);\n });\n }\n}\n\n/**\n * Converts trees/blobs/ops to binary compact representation.\n * @param snapshotContents - snapshot tree contents to serialize\n * @returns - ReadBuffer - binary representation of the data.\n */\nexport function convertToCompactSnapshot(snapshotContents: ISnapshotContents): ReadBuffer {\n const builder = new TreeBuilderSerializer();\n // Create the root node.\n const rootNode = builder.addNode();\n assert(snapshotContents.sequenceNumber !== undefined, 0x21c /* \"Seq number should be provided\" */);\n\n const latestSequenceNumber = snapshotContents.latestSequenceNumber ??\n snapshotContents.ops.length > 0 ?\n snapshotContents.ops[snapshotContents.ops.length - 1].sequenceNumber : snapshotContents.sequenceNumber;\n\n writeSnapshotProps(rootNode, latestSequenceNumber);\n\n writeSnapshotSection(\n rootNode,\n snapshotContents.snapshotTree,\n snapshotContents.sequenceNumber,\n );\n\n // Add Blobs\n writeBlobsSection(rootNode, snapshotContents.blobs);\n\n // Then write the ops node.\n writeOpsSection(rootNode, snapshotContents.ops);\n\n return builder.serialize();\n}\n"]}
1
+ {"version":3,"file":"compactSnapshotWriter.js","sourceRoot":"","sources":["../src/compactSnapshotWriter.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert, stringToBuffer } from \"@fluidframework/common-utils\";\nimport { IBlob, ISequencedDocumentMessage, ISnapshotTree } from \"@fluidframework/protocol-definitions\";\nimport { snapshotMinReadVersion } from \"./compactSnapshotParser\";\nimport { ISnapshotContents } from \"./odspPublicUtils\";\nimport { ReadBuffer } from \"./ReadBufferUtils\";\nimport { TreeBuilderSerializer } from \"./WriteBufferUtils\";\nimport { addBoolProperty, addNumberProperty, addStringProperty, NodeCore } from \"./zipItDataRepresentationUtils\";\n\n/**\n * Writes header section of the snapshot.\n * @param node - snapshot node to serialize to\n * @param latestSequenceNumber - latest seq number of the container.\n*/\nfunction writeSnapshotProps(node: NodeCore, latestSequenceNumber: number) {\n addStringProperty(node, \"mrv\", snapshotMinReadVersion);\n addStringProperty(node, \"cv\", snapshotMinReadVersion);\n addNumberProperty(node, \"lsn\", latestSequenceNumber);\n}\n\n/**\n * Represents blobs in the tree.\n * @param snapshotNode - node to serialize to.\n * @param blobs - blobs that is being serialized\n*/\nfunction writeBlobsSection(snapshotNode: NodeCore, blobs: Map<string, IBlob | ArrayBuffer>) {\n snapshotNode.addString(\"blobs\", true);\n const blobsNode = snapshotNode.addNode(\"list\");\n for (const [storageBlobId, blob] of blobs) {\n const blobNode = blobsNode.addNode();\n addStringProperty(blobNode, \"id\", storageBlobId, true);\n blobNode.addString(\"data\", true);\n if (blob instanceof ArrayBuffer) {\n blobNode.addBlob(new Uint8Array(blob), false);\n } else {\n blobNode.addBlob(new Uint8Array(stringToBuffer(blob.contents, blob.encoding ?? \"utf-8\")), false);\n }\n }\n}\n\n/**\n * Represents and serializes tree part of the snapshot\n * @param snapshotNode - tree node to serialize to\n * @param snapshotTree - snapshot tree that is being serialized\n*/\nfunction writeTreeSection(snapshotNode: NodeCore, snapshotTree: ISnapshotTree) {\n snapshotNode.addString(\"treeNodes\", true);\n const treesNode = snapshotNode.addNode(\"list\");\n writeTreeSectionCore(treesNode, snapshotTree);\n}\n\nfunction writeTreeSectionCore(treesNode: NodeCore, snapshotTree: ISnapshotTree) {\n for (const [path, value] of Object.entries(snapshotTree.trees)) {\n const treeNode = treesNode.addNode();\n addStringProperty(treeNode, \"name\", path);\n if (snapshotTree.unreferenced) {\n addBoolProperty(treeNode, \"unreferenced\", snapshotTree.unreferenced);\n }\n // Only write children prop if either blobs or trees are present.\n if (Object.keys(value.blobs).length > 0 || Object.keys(value.trees).length > 0) {\n treeNode.addString(\"children\", true);\n const childNode = treeNode.addNode(\"list\");\n writeTreeSectionCore(childNode, value);\n }\n }\n\n if (snapshotTree.blobs) {\n for (const [path, id] of Object.entries(snapshotTree.blobs)) {\n const blobNode = treesNode.addNode();\n addStringProperty(blobNode, \"name\", path);\n addStringProperty(blobNode, \"value\", id, true);\n }\n }\n}\n\n/**\n * Represents (serializes) snapshot tree as generalizes tree\n * @param rootNode - tree node to serialize to\n * @param snapshotTree - snapshot tree that is being serialized\n * @param blobs - blobs mapping of the snapshot\n * @param snapshotSequenceNumber - seq number at which snapshot is taken\n*/\nfunction writeSnapshotSection(\n rootNode: NodeCore,\n snapshotTree: ISnapshotTree,\n snapshotSequenceNumber: number,\n) {\n rootNode.addString(\"snapshot\", true);\n const snapshotNode = rootNode.addNode();\n\n const snapshotId = snapshotTree.id;\n assert(snapshotId !== undefined, 0x21b /* \"Snapshot id should be provided\" */);\n addStringProperty(snapshotNode, \"id\", snapshotId);\n addStringProperty(snapshotNode, \"message\", `Snapshot@${snapshotSequenceNumber}`);\n addNumberProperty(snapshotNode, \"sequenceNumber\", snapshotSequenceNumber);\n\n // Add Trees\n writeTreeSection(snapshotNode, snapshotTree);\n}\n\n/**\n * Represents ops in the tree.\n * @param rootNode - node to serialize to.\n * @param ops - ops that is being serialized\n*/\nfunction writeOpsSection(rootNode: NodeCore, ops: ISequencedDocumentMessage[]) {\n let firstSequenceNumber: number | undefined;\n if (ops.length > 0) {\n firstSequenceNumber = ops[0].sequenceNumber;\n }\n if (firstSequenceNumber !== undefined) {\n rootNode.addString(\"deltas\", true);\n const opsNode = rootNode.addNode();\n addNumberProperty(opsNode, \"firstSequenceNumber\", firstSequenceNumber);\n opsNode.addString(\"deltas\", true);\n const deltaNode = opsNode.addNode(\"list\");\n ops.forEach((op) => {\n deltaNode.addString(JSON.stringify(op), false);\n });\n }\n}\n\n/**\n * Converts trees/blobs/ops to binary compact representation.\n * @param snapshotContents - snapshot tree contents to serialize\n * @returns - ReadBuffer - binary representation of the data.\n */\nexport function convertToCompactSnapshot(snapshotContents: ISnapshotContents): ReadBuffer {\n const builder = new TreeBuilderSerializer();\n // Create the root node.\n const rootNode = builder.addNode();\n assert(snapshotContents.sequenceNumber !== undefined, 0x21c /* \"Seq number should be provided\" */);\n\n const latestSequenceNumber = snapshotContents.latestSequenceNumber ??\n snapshotContents.ops.length > 0 ?\n snapshotContents.ops[snapshotContents.ops.length - 1].sequenceNumber : snapshotContents.sequenceNumber;\n\n writeSnapshotProps(rootNode, latestSequenceNumber);\n\n writeSnapshotSection(\n rootNode,\n snapshotContents.snapshotTree,\n snapshotContents.sequenceNumber,\n );\n\n // Add Blobs\n writeBlobsSection(rootNode, snapshotContents.blobs);\n\n // Then write the ops node.\n writeOpsSection(rootNode, snapshotContents.ops);\n\n return builder.serialize();\n}\n"]}
@@ -69,7 +69,7 @@ exports.getFileLink = getFileLink;
69
69
  async function getFileLinkCore(getToken, odspUrlParts, identityType, logger) {
70
70
  const fileItem = await getFileItemLite(getToken, odspUrlParts, logger, identityType === "Consumer");
71
71
  // ODSP link requires extra call to return link that is resistant to file being renamed or moved to different folder
72
- return telemetry_utils_1.PerformanceEvent.timedExecAsync(logger, { eventName: "odspFileLink", requestName: "getSharingLink" }, async (event) => {
72
+ return telemetry_utils_1.PerformanceEvent.timedExecAsync(logger, { eventName: "odspFileLink", requestName: "getSharingInformation" }, async (event) => {
73
73
  let attempts = 0;
74
74
  let additionalProps;
75
75
  const fileLink = await (0, odspUtils_1.getWithRetryForTokenRefresh)(async (options) => {
@@ -78,7 +78,7 @@ async function getFileLinkCore(getToken, odspUrlParts, identityType, logger) {
78
78
  const storageTokenFetcher = (0, odspUtils_1.toInstrumentedOdspTokenFetcher)(logger, odspUrlParts, getToken, true /* throwOnNullToken */);
79
79
  const storageToken = await storageTokenFetcher(options, "GetFileLinkCore");
80
80
  (0, common_utils_1.assert)(storageToken !== null, 0x2bb /* "Instrumented token fetcher with throwOnNullToken = true should never return null" */);
81
- const { url, headers } = (0, getUrlAndHeadersWithAuth_1.getUrlAndHeadersWithAuth)(`${odspUrlParts.siteUrl}/_api/web/GetFileByServerRelativeUrl(@a1)/Linkingurl?@a1=${encodeURIComponent(`'${new URL(fileItem.webDavUrl).pathname}'`)}`, storageToken, false);
81
+ const { url, headers } = (0, getUrlAndHeadersWithAuth_1.getUrlAndHeadersWithAuth)(`${odspUrlParts.siteUrl}/_api/web/GetFileByUrl(@a1)/ListItemAllFields/GetSharingInformation?@a1=${encodeURIComponent(`'${fileItem.webDavUrl}'`)}`, storageToken, false);
82
82
  const requestInit = {
83
83
  method: "POST",
84
84
  headers: Object.assign({ "Content-Type": "application/json;odata=verbose", "Accept": "application/json;odata=verbose" }, headers),
@@ -86,12 +86,12 @@ async function getFileLinkCore(getToken, odspUrlParts, identityType, logger) {
86
86
  const response = await (0, odspUtils_1.fetchHelper)(url, requestInit);
87
87
  additionalProps = response.propsToLog;
88
88
  const sharingInfo = await response.content.json();
89
- const linkingUrl = (_a = sharingInfo === null || sharingInfo === void 0 ? void 0 : sharingInfo.d) === null || _a === void 0 ? void 0 : _a.LinkingUrl;
90
- if (typeof linkingUrl !== "string") {
89
+ const directUrl = (_a = sharingInfo === null || sharingInfo === void 0 ? void 0 : sharingInfo.d) === null || _a === void 0 ? void 0 : _a.directUrl;
90
+ if (typeof directUrl !== "string") {
91
91
  // This will retry once in getWithRetryForTokenRefresh
92
- throw new driver_utils_1.NonRetryableError("Malformed GetSharingLink response", driver_definitions_1.DriverErrorType.incorrectServerResponse, { driverVersion: packageVersion_1.pkgVersion });
92
+ throw new driver_utils_1.NonRetryableError("Malformed GetSharingInformation response", driver_definitions_1.DriverErrorType.incorrectServerResponse, { driverVersion: packageVersion_1.pkgVersion });
93
93
  }
94
- return linkingUrl;
94
+ return directUrl;
95
95
  });
96
96
  event.end(Object.assign(Object.assign({}, additionalProps), { attempts }));
97
97
  return fileLink;
@@ -1 +1 @@
1
- {"version":3,"file":"getFileLink.js","sourceRoot":"","sources":["../src/getFileLink.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 { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { assert, delay } from \"@fluidframework/common-utils\";\nimport { canRetryOnError, getRetryDelayFromError, NonRetryableError } from \"@fluidframework/driver-utils\";\nimport { PerformanceEvent } from \"@fluidframework/telemetry-utils\";\nimport { DriverErrorType } from \"@fluidframework/driver-definitions\";\nimport {\n IOdspUrlParts,\n OdspResourceTokenFetchOptions,\n IdentityType,\n TokenFetcher,\n} from \"@fluidframework/odsp-driver-definitions\";\nimport { getUrlAndHeadersWithAuth } from \"./getUrlAndHeadersWithAuth\";\nimport { fetchHelper, getWithRetryForTokenRefresh, toInstrumentedOdspTokenFetcher } from \"./odspUtils\";\nimport { pkgVersion as driverVersion } from \"./packageVersion\";\n\n// Store cached responses for the lifetime of web session as file link remains the same for given file item\nconst fileLinkCache = new Map<string, Promise<string>>();\n\n/**\n * Returns file link for a file with given drive and item ids.\n * Scope needed: files.readwrite.all.\n * This function keeps retrying if it gets a retriable error or wait for some delay if it gets a\n * throttling error. In future, we are thinking of app allowing to pass some cancel token, with which\n * we would be able to stop retrying.\n * @param getToken - used to fetch access tokens needed to execute operation\n * @param siteUrl - url of the site that contains the file\n * @param driveId - drive where file is stored\n * @param itemId - file id\n * @param identityType - type of client account\n * @param logger - used to log results of operation, including any error\n * @returns Promise which resolves to file link url when successful; otherwise, undefined.\n */\nexport async function getFileLink(\n getToken: TokenFetcher<OdspResourceTokenFetchOptions>,\n odspUrlParts: IOdspUrlParts,\n identityType: IdentityType,\n logger: ITelemetryLogger,\n): Promise<string> {\n const cacheKey = `${odspUrlParts.siteUrl}_${odspUrlParts.driveId}_${odspUrlParts.itemId}`;\n const maybeFileLinkCacheEntry = fileLinkCache.get(cacheKey);\n if (maybeFileLinkCacheEntry !== undefined) {\n return maybeFileLinkCacheEntry;\n }\n\n const valueGenerator = async function() {\n let result: string | undefined;\n let success = false;\n let retryAfterMs = 1000;\n do {\n try {\n result = await getFileLinkCore(getToken, odspUrlParts, identityType, logger);\n success = true;\n } catch (err) {\n // If it is not retriable, then just throw\n if (!canRetryOnError(err)) {\n // Delete from the cache to permit retrying later.\n fileLinkCache.delete(cacheKey);\n throw err;\n }\n // If the error is throttling error, then wait for the specified time before retrying.\n // If the waitTime is not specified, then we start with retrying immediately to max of 8s.\n retryAfterMs = getRetryDelayFromError(err) ?? Math.min(retryAfterMs * 2, 8000);\n await delay(retryAfterMs);\n }\n } while (!success);\n\n // We are guaranteed to run the getFileLinkCore at least once with successful result (which must be a string)\n assert(result !== undefined, 0x292 /* \"Unexpected undefined result from getFileLinkCore\" */);\n return result;\n };\n const fileLink = valueGenerator();\n fileLinkCache.set(cacheKey, fileLink);\n return fileLink;\n}\n\nasync function getFileLinkCore(\n getToken: TokenFetcher<OdspResourceTokenFetchOptions>,\n odspUrlParts: IOdspUrlParts,\n identityType: IdentityType,\n logger: ITelemetryLogger,\n): Promise<string> {\n const fileItem = await getFileItemLite(getToken, odspUrlParts, logger, identityType === \"Consumer\");\n\n // ODSP link requires extra call to return link that is resistant to file being renamed or moved to different folder\n return PerformanceEvent.timedExecAsync(\n logger,\n { eventName: \"odspFileLink\", requestName: \"getSharingLink\" },\n async (event) => {\n let attempts = 0;\n let additionalProps;\n const fileLink = await getWithRetryForTokenRefresh(async (options) => {\n attempts++;\n const storageTokenFetcher = toInstrumentedOdspTokenFetcher(\n logger,\n odspUrlParts,\n getToken,\n true /* throwOnNullToken */,\n );\n const storageToken = await storageTokenFetcher(options, \"GetFileLinkCore\");\n assert(storageToken !== null,\n 0x2bb /* \"Instrumented token fetcher with throwOnNullToken = true should never return null\" */);\n\n const { url, headers } = getUrlAndHeadersWithAuth(\n `${odspUrlParts.siteUrl}/_api/web/GetFileByServerRelativeUrl(@a1)/Linkingurl?@a1=${\n encodeURIComponent(`'${new URL(fileItem.webDavUrl).pathname}'`)\n }`,\n storageToken,\n false,\n );\n const requestInit = {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json;odata=verbose\",\n \"Accept\": \"application/json;odata=verbose\",\n ...headers,\n },\n };\n const response = await fetchHelper(url, requestInit);\n additionalProps = response.propsToLog;\n\n const sharingInfo = await response.content.json();\n const linkingUrl = sharingInfo?.d?.LinkingUrl;\n if (typeof linkingUrl !== \"string\") {\n // This will retry once in getWithRetryForTokenRefresh\n throw new NonRetryableError(\n \"Malformed GetSharingLink response\",\n DriverErrorType.incorrectServerResponse,\n { driverVersion });\n }\n return linkingUrl;\n });\n event.end({ ...additionalProps, attempts });\n return fileLink;\n },\n );\n}\n\n/**\n * This represents a lite version of file item containing only the webUrl and webDavUrl properties\n */\ninterface FileItemLite {\n webUrl: string;\n webDavUrl: string;\n}\n\nconst isFileItemLite = (maybeFileItemLite: any): maybeFileItemLite is FileItemLite => {\n if (typeof maybeFileItemLite.webUrl !== \"string\" || typeof maybeFileItemLite.webDavUrl !== \"string\") {\n return false;\n }\n return true;\n};\n\nasync function getFileItemLite(\n getToken: TokenFetcher<OdspResourceTokenFetchOptions>,\n odspUrlParts: IOdspUrlParts,\n logger: ITelemetryLogger,\n forceAccessTokenViaAuthorizationHeader: boolean,\n): Promise<FileItemLite> {\n return PerformanceEvent.timedExecAsync(\n logger,\n { eventName: \"odspFileLink\", requestName: \"getFileItemLite\" },\n async (event) => {\n let attempts = 0;\n let additionalProps;\n const fileItem = await getWithRetryForTokenRefresh(async (options) => {\n attempts++;\n const { siteUrl, driveId, itemId } = odspUrlParts;\n const storageTokenFetcher = toInstrumentedOdspTokenFetcher(\n logger,\n odspUrlParts,\n getToken,\n true /* throwOnNullToken */,\n );\n const storageToken = await storageTokenFetcher(options, \"GetFileItemLite\");\n assert(storageToken !== null,\n 0x2bc /* \"Instrumented token fetcher with throwOnNullToken =true should never return null\" */);\n\n const { url, headers } = getUrlAndHeadersWithAuth(\n `${siteUrl}/_api/v2.0/drives/${driveId}/items/${itemId}?select=webUrl,webDavUrl`,\n storageToken,\n forceAccessTokenViaAuthorizationHeader,\n );\n const requestInit = { method: \"GET\", headers };\n const response = await fetchHelper(url, requestInit);\n additionalProps = response.propsToLog;\n\n const responseJson = await response.content.json();\n if (!isFileItemLite(responseJson)) {\n // This will retry once in getWithRetryForTokenRefresh\n throw new NonRetryableError(\n \"Malformed getFileItemLite response\",\n DriverErrorType.incorrectServerResponse,\n { driverVersion });\n }\n return responseJson;\n });\n event.end({ ...additionalProps, attempts });\n return fileItem;\n },\n );\n}\n"]}
1
+ {"version":3,"file":"getFileLink.js","sourceRoot":"","sources":["../src/getFileLink.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 { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { assert, delay } from \"@fluidframework/common-utils\";\nimport { canRetryOnError, getRetryDelayFromError, NonRetryableError } from \"@fluidframework/driver-utils\";\nimport { PerformanceEvent } from \"@fluidframework/telemetry-utils\";\nimport { DriverErrorType } from \"@fluidframework/driver-definitions\";\nimport {\n IOdspUrlParts,\n OdspResourceTokenFetchOptions,\n IdentityType,\n TokenFetcher,\n} from \"@fluidframework/odsp-driver-definitions\";\nimport { getUrlAndHeadersWithAuth } from \"./getUrlAndHeadersWithAuth\";\nimport { fetchHelper, getWithRetryForTokenRefresh, toInstrumentedOdspTokenFetcher } from \"./odspUtils\";\nimport { pkgVersion as driverVersion } from \"./packageVersion\";\n\n// Store cached responses for the lifetime of web session as file link remains the same for given file item\nconst fileLinkCache = new Map<string, Promise<string>>();\n\n/**\n * Returns file link for a file with given drive and item ids.\n * Scope needed: files.readwrite.all.\n * This function keeps retrying if it gets a retriable error or wait for some delay if it gets a\n * throttling error. In future, we are thinking of app allowing to pass some cancel token, with which\n * we would be able to stop retrying.\n * @param getToken - used to fetch access tokens needed to execute operation\n * @param siteUrl - url of the site that contains the file\n * @param driveId - drive where file is stored\n * @param itemId - file id\n * @param identityType - type of client account\n * @param logger - used to log results of operation, including any error\n * @returns Promise which resolves to file link url when successful; otherwise, undefined.\n */\nexport async function getFileLink(\n getToken: TokenFetcher<OdspResourceTokenFetchOptions>,\n odspUrlParts: IOdspUrlParts,\n identityType: IdentityType,\n logger: ITelemetryLogger,\n): Promise<string> {\n const cacheKey = `${odspUrlParts.siteUrl}_${odspUrlParts.driveId}_${odspUrlParts.itemId}`;\n const maybeFileLinkCacheEntry = fileLinkCache.get(cacheKey);\n if (maybeFileLinkCacheEntry !== undefined) {\n return maybeFileLinkCacheEntry;\n }\n\n const valueGenerator = async function() {\n let result: string | undefined;\n let success = false;\n let retryAfterMs = 1000;\n do {\n try {\n result = await getFileLinkCore(getToken, odspUrlParts, identityType, logger);\n success = true;\n } catch (err) {\n // If it is not retriable, then just throw\n if (!canRetryOnError(err)) {\n // Delete from the cache to permit retrying later.\n fileLinkCache.delete(cacheKey);\n throw err;\n }\n // If the error is throttling error, then wait for the specified time before retrying.\n // If the waitTime is not specified, then we start with retrying immediately to max of 8s.\n retryAfterMs = getRetryDelayFromError(err) ?? Math.min(retryAfterMs * 2, 8000);\n await delay(retryAfterMs);\n }\n } while (!success);\n\n // We are guaranteed to run the getFileLinkCore at least once with successful result (which must be a string)\n assert(result !== undefined, 0x292 /* \"Unexpected undefined result from getFileLinkCore\" */);\n return result;\n };\n const fileLink = valueGenerator();\n fileLinkCache.set(cacheKey, fileLink);\n return fileLink;\n}\n\nasync function getFileLinkCore(\n getToken: TokenFetcher<OdspResourceTokenFetchOptions>,\n odspUrlParts: IOdspUrlParts,\n identityType: IdentityType,\n logger: ITelemetryLogger,\n): Promise<string> {\n const fileItem = await getFileItemLite(getToken, odspUrlParts, logger, identityType === \"Consumer\");\n\n // ODSP link requires extra call to return link that is resistant to file being renamed or moved to different folder\n return PerformanceEvent.timedExecAsync(\n logger,\n { eventName: \"odspFileLink\", requestName: \"getSharingInformation\" },\n async (event) => {\n let attempts = 0;\n let additionalProps;\n const fileLink = await getWithRetryForTokenRefresh(async (options) => {\n attempts++;\n const storageTokenFetcher = toInstrumentedOdspTokenFetcher(\n logger,\n odspUrlParts,\n getToken,\n true /* throwOnNullToken */,\n );\n const storageToken = await storageTokenFetcher(options, \"GetFileLinkCore\");\n assert(storageToken !== null,\n 0x2bb /* \"Instrumented token fetcher with throwOnNullToken = true should never return null\" */);\n\n const { url, headers } = getUrlAndHeadersWithAuth(\n `${odspUrlParts.siteUrl}/_api/web/GetFileByUrl(@a1)/ListItemAllFields/GetSharingInformation?@a1=${\n encodeURIComponent(`'${fileItem.webDavUrl}'`)\n }`,\n storageToken,\n false,\n );\n const requestInit = {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json;odata=verbose\",\n \"Accept\": \"application/json;odata=verbose\",\n ...headers,\n },\n };\n const response = await fetchHelper(url, requestInit);\n additionalProps = response.propsToLog;\n\n const sharingInfo = await response.content.json();\n const directUrl = sharingInfo?.d?.directUrl;\n if (typeof directUrl !== \"string\") {\n // This will retry once in getWithRetryForTokenRefresh\n throw new NonRetryableError(\n \"Malformed GetSharingInformation response\",\n DriverErrorType.incorrectServerResponse,\n { driverVersion });\n }\n return directUrl;\n });\n event.end({ ...additionalProps, attempts });\n return fileLink;\n },\n );\n}\n\n/**\n * This represents a lite version of file item containing only the webUrl and webDavUrl properties\n */\ninterface FileItemLite {\n webUrl: string;\n webDavUrl: string;\n}\n\nconst isFileItemLite = (maybeFileItemLite: any): maybeFileItemLite is FileItemLite => {\n if (typeof maybeFileItemLite.webUrl !== \"string\" || typeof maybeFileItemLite.webDavUrl !== \"string\") {\n return false;\n }\n return true;\n};\n\nasync function getFileItemLite(\n getToken: TokenFetcher<OdspResourceTokenFetchOptions>,\n odspUrlParts: IOdspUrlParts,\n logger: ITelemetryLogger,\n forceAccessTokenViaAuthorizationHeader: boolean,\n): Promise<FileItemLite> {\n return PerformanceEvent.timedExecAsync(\n logger,\n { eventName: \"odspFileLink\", requestName: \"getFileItemLite\" },\n async (event) => {\n let attempts = 0;\n let additionalProps;\n const fileItem = await getWithRetryForTokenRefresh(async (options) => {\n attempts++;\n const { siteUrl, driveId, itemId } = odspUrlParts;\n const storageTokenFetcher = toInstrumentedOdspTokenFetcher(\n logger,\n odspUrlParts,\n getToken,\n true /* throwOnNullToken */,\n );\n const storageToken = await storageTokenFetcher(options, \"GetFileItemLite\");\n assert(storageToken !== null,\n 0x2bc /* \"Instrumented token fetcher with throwOnNullToken =true should never return null\" */);\n\n const { url, headers } = getUrlAndHeadersWithAuth(\n `${siteUrl}/_api/v2.0/drives/${driveId}/items/${itemId}?select=webUrl,webDavUrl`,\n storageToken,\n forceAccessTokenViaAuthorizationHeader,\n );\n const requestInit = { method: \"GET\", headers };\n const response = await fetchHelper(url, requestInit);\n additionalProps = response.propsToLog;\n\n const responseJson = await response.content.json();\n if (!isFileItemLite(responseJson)) {\n // This will retry once in getWithRetryForTokenRefresh\n throw new NonRetryableError(\n \"Malformed getFileItemLite response\",\n DriverErrorType.incorrectServerResponse,\n { driverVersion });\n }\n return responseJson;\n });\n event.end({ ...additionalProps, attempts });\n return fileItem;\n },\n );\n}\n"]}
@@ -5,5 +5,5 @@
5
5
  * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
6
6
  */
7
7
  export declare const pkgName = "@fluidframework/odsp-driver";
8
- export declare const pkgVersion = "1.2.0-78837";
8
+ export declare const pkgVersion = "1.2.2";
9
9
  //# sourceMappingURL=packageVersion.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"packageVersion.d.ts","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,OAAO,gCAAgC,CAAC;AACrD,eAAO,MAAM,UAAU,gBAAgB,CAAC"}
1
+ {"version":3,"file":"packageVersion.d.ts","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,OAAO,gCAAgC,CAAC;AACrD,eAAO,MAAM,UAAU,UAAU,CAAC"}
@@ -8,5 +8,5 @@
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.pkgVersion = exports.pkgName = void 0;
10
10
  exports.pkgName = "@fluidframework/odsp-driver";
11
- exports.pkgVersion = "1.2.0-78837";
11
+ exports.pkgVersion = "1.2.2";
12
12
  //# sourceMappingURL=packageVersion.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEU,QAAA,OAAO,GAAG,6BAA6B,CAAC;AACxC,QAAA,UAAU,GAAG,aAAa,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/odsp-driver\";\nexport const pkgVersion = \"1.2.0-78837\";\n"]}
1
+ {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEU,QAAA,OAAO,GAAG,6BAA6B,CAAC;AACxC,QAAA,UAAU,GAAG,OAAO,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/odsp-driver\";\nexport const pkgVersion = \"1.2.2\";\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"compactSnapshotParser.d.ts","sourceRoot":"","sources":["../src/compactSnapshotParser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAa/C,eAAO,MAAM,sBAAsB,QAAQ,CAAC;AAC5C,eAAO,MAAM,kBAAkB,QAAQ,CAAC;AAgGxC;;;;GAIG;AACH,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,UAAU,GAAG,iBAAiB,CA2BlF"}
1
+ {"version":3,"file":"compactSnapshotParser.d.ts","sourceRoot":"","sources":["../src/compactSnapshotParser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAa/C,eAAO,MAAM,sBAAsB,QAAQ,CAAC;AAC5C,eAAO,MAAM,kBAAkB,QAAQ,CAAC;AAkGxC;;;;GAIG;AACH,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,UAAU,GAAG,iBAAiB,CA2BlF"}
@@ -57,10 +57,13 @@ function readTreeSection(node) {
57
57
  assertBlobCoreInstance(records.value, "Blob value should be BlobCore");
58
58
  snapshotTree.blobs[path] = records.value.toString();
59
59
  }
60
- else {
60
+ else if (records.children !== undefined) {
61
61
  assertNodeCoreInstance(records.children, "Trees should be of type NodeCore");
62
62
  snapshotTree.trees[path] = readTreeSection(records.children);
63
63
  }
64
+ else {
65
+ snapshotTree.trees[path] = { blobs: {}, commits: {}, trees: {} };
66
+ }
64
67
  if (records.unreferenced !== undefined) {
65
68
  assertBoolInstance(records.unreferenced, "Unreferenced flag should be bool");
66
69
  const unreferenced = records.unreferenced.valueOf();
@@ -1 +1 @@
1
- {"version":3,"file":"compactSnapshotParser.js","sourceRoot":"","sources":["../src/compactSnapshotParser.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/common-utils\";\nimport { ISequencedDocumentMessage, ISnapshotTree } from \"@fluidframework/protocol-definitions\";\nimport { ISnapshotContents } from \"./odspPublicUtils\";\nimport { ReadBuffer } from \"./ReadBufferUtils\";\nimport { ISnapshotTreeEx } from \"./contracts\";\nimport {\n assertBlobCoreInstance,\n assertBoolInstance,\n assertNodeCoreInstance,\n assertNumberInstance,\n getAndValidateNodeProps,\n NodeCore,\n NodeTypes,\n TreeBuilder,\n} from \"./zipItDataRepresentationUtils\";\n\nexport const snapshotMinReadVersion = \"1.0\";\nexport const currentReadVersion = \"1.0\";\n\ninterface ISnapshotSection {\n snapshotTree: ISnapshotTree;\n sequenceNumber: number;\n}\n\n/**\n * Recreates blobs section of the tree.\n * @param node - tree node to read blob section from\n */\nfunction readBlobSection(node: NodeTypes) {\n assertNodeCoreInstance(node, \"TreeBlobs should be of type NodeCore\");\n const blobs: Map<string, ArrayBuffer> = new Map();\n for (let count = 0; count < node.length; ++count) {\n const blob = node.getNode(count);\n const records = getAndValidateNodeProps(blob, [\"id\", \"data\"]);\n assertBlobCoreInstance(records.data, \"data should be of BlobCore type\");\n assertBlobCoreInstance(records.id, \"blob id should be of BlobCore type\");\n blobs.set(records.id.toString(), records.data.arrayBuffer);\n }\n return blobs;\n}\n\n/**\n * Recreates ops section of the tree.\n * @param node - tree node to read ops section from\n */\nfunction readOpsSection(node: NodeTypes) {\n assertNodeCoreInstance(node, \"Deltas should be of type NodeCore\");\n const ops: ISequencedDocumentMessage[] = [];\n const records = getAndValidateNodeProps(node, [\"firstSequenceNumber\", \"deltas\"]);\n assertNumberInstance(records.firstSequenceNumber, \"Seq number should be a number\");\n assertNodeCoreInstance(records.deltas, \"Deltas should be a Node\");\n for (let i = 0; i < records.deltas.length; ++i) {\n ops.push(JSON.parse(records.deltas.getString(i)));\n }\n assert(records.firstSequenceNumber.valueOf() === ops[0].sequenceNumber,\n 0x280 /* \"Validate first op seq number\" */);\n return ops;\n}\n\n/**\n * Recreates snapshot tree out of tree representation.\n * @param node - tree node to de-serialize from\n */\nfunction readTreeSection(node: NodeCore) {\n const snapshotTree: ISnapshotTreeEx = {\n blobs: {},\n commits: {},\n trees: {},\n };\n for (let count = 0; count < node.length; count++) {\n const treeNode = node.getNode(count);\n const records = getAndValidateNodeProps(treeNode,\n [\"name\", \"value\", \"children\", \"unreferenced\"], false);\n assertBlobCoreInstance(records.name, \"Path should be of BlobCore\");\n const path = records.name.toString();\n if (records.value !== undefined) {\n assertBlobCoreInstance(records.value, \"Blob value should be BlobCore\");\n snapshotTree.blobs[path] = records.value.toString();\n } else {\n assertNodeCoreInstance(records.children, \"Trees should be of type NodeCore\");\n snapshotTree.trees[path] = readTreeSection(records.children);\n }\n if (records.unreferenced !== undefined) {\n assertBoolInstance(records.unreferenced, \"Unreferenced flag should be bool\");\n const unreferenced = records.unreferenced.valueOf();\n assert(unreferenced, 0x281 /* \"Unreferenced if present should be true\" */);\n snapshotTree.unreferenced = unreferenced;\n }\n }\n return snapshotTree;\n}\n\n/**\n * Recreates snapshot tree out of tree representation.\n * @param node - tree node to de-serialize from\n */\nfunction readSnapshotSection(node: NodeTypes): ISnapshotSection {\n assertNodeCoreInstance(node, \"Snapshot should be of type NodeCore\");\n const records = getAndValidateNodeProps(node,\n [\"id\", \"sequenceNumber\", \"treeNodes\"]);\n\n assertNodeCoreInstance(records.treeNodes, \"TreeNodes should be of type NodeCore\");\n assertNumberInstance(records.sequenceNumber, \"sequenceNumber should be of type number\");\n assertBlobCoreInstance(records.id, \"snapshotId should be BlobCore\");\n const snapshotTree: ISnapshotTree = readTreeSection(records.treeNodes);\n snapshotTree.id = records.id.toString();\n const sequenceNumber = records.sequenceNumber.valueOf();\n return {\n sequenceNumber,\n snapshotTree,\n };\n}\n\n/**\n * Converts snapshot from binary compact representation to tree/blobs/ops.\n * @param buffer - Compact snapshot to be parsed into tree/blobs/ops.\n * @returns - tree, blobs and ops from the snapshot.\n */\nexport function parseCompactSnapshotResponse(buffer: ReadBuffer): ISnapshotContents {\n const builder = TreeBuilder.load(buffer);\n assert(builder.length === 1, 0x219 /* \"1 root should be there\" */);\n const root = builder.getNode(0);\n\n const records = getAndValidateNodeProps(root,\n [\"mrv\", \"cv\", \"lsn\", \"snapshot\", \"blobs\", \"deltas\"], false);\n\n assertBlobCoreInstance(records.mrv, \"minReadVersion should be of BlobCore type\");\n assertBlobCoreInstance(records.cv, \"createVersion should be of BlobCore type\");\n if (records.lsn !== undefined) {\n assertNumberInstance(records.lsn, \"lsn should be a number\");\n }\n\n assert(parseFloat(snapshotMinReadVersion) >= parseFloat(records.mrv.toString()),\n 0x20f /* \"Driver min read version should >= to server minReadVersion\" */);\n assert(parseFloat(records.cv.toString()) >= parseFloat(snapshotMinReadVersion),\n 0x210 /* \"Snapshot should be created with minReadVersion or above\" */);\n assert(currentReadVersion === records.cv.toString(),\n 0x2c2 /* \"Create Version should be equal to currentReadVersion\" */);\n\n return {\n ...readSnapshotSection(records.snapshot),\n blobs: readBlobSection(records.blobs),\n ops: records.deltas !== undefined ? readOpsSection(records.deltas) : [],\n latestSequenceNumber: records.lsn,\n };\n}\n"]}
1
+ {"version":3,"file":"compactSnapshotParser.js","sourceRoot":"","sources":["../src/compactSnapshotParser.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/common-utils\";\nimport { ISequencedDocumentMessage, ISnapshotTree } from \"@fluidframework/protocol-definitions\";\nimport { ISnapshotContents } from \"./odspPublicUtils\";\nimport { ReadBuffer } from \"./ReadBufferUtils\";\nimport { ISnapshotTreeEx } from \"./contracts\";\nimport {\n assertBlobCoreInstance,\n assertBoolInstance,\n assertNodeCoreInstance,\n assertNumberInstance,\n getAndValidateNodeProps,\n NodeCore,\n NodeTypes,\n TreeBuilder,\n} from \"./zipItDataRepresentationUtils\";\n\nexport const snapshotMinReadVersion = \"1.0\";\nexport const currentReadVersion = \"1.0\";\n\ninterface ISnapshotSection {\n snapshotTree: ISnapshotTree;\n sequenceNumber: number;\n}\n\n/**\n * Recreates blobs section of the tree.\n * @param node - tree node to read blob section from\n */\nfunction readBlobSection(node: NodeTypes) {\n assertNodeCoreInstance(node, \"TreeBlobs should be of type NodeCore\");\n const blobs: Map<string, ArrayBuffer> = new Map();\n for (let count = 0; count < node.length; ++count) {\n const blob = node.getNode(count);\n const records = getAndValidateNodeProps(blob, [\"id\", \"data\"]);\n assertBlobCoreInstance(records.data, \"data should be of BlobCore type\");\n assertBlobCoreInstance(records.id, \"blob id should be of BlobCore type\");\n blobs.set(records.id.toString(), records.data.arrayBuffer);\n }\n return blobs;\n}\n\n/**\n * Recreates ops section of the tree.\n * @param node - tree node to read ops section from\n */\nfunction readOpsSection(node: NodeTypes) {\n assertNodeCoreInstance(node, \"Deltas should be of type NodeCore\");\n const ops: ISequencedDocumentMessage[] = [];\n const records = getAndValidateNodeProps(node, [\"firstSequenceNumber\", \"deltas\"]);\n assertNumberInstance(records.firstSequenceNumber, \"Seq number should be a number\");\n assertNodeCoreInstance(records.deltas, \"Deltas should be a Node\");\n for (let i = 0; i < records.deltas.length; ++i) {\n ops.push(JSON.parse(records.deltas.getString(i)));\n }\n assert(records.firstSequenceNumber.valueOf() === ops[0].sequenceNumber,\n 0x280 /* \"Validate first op seq number\" */);\n return ops;\n}\n\n/**\n * Recreates snapshot tree out of tree representation.\n * @param node - tree node to de-serialize from\n */\nfunction readTreeSection(node: NodeCore) {\n const snapshotTree: ISnapshotTreeEx = {\n blobs: {},\n commits: {},\n trees: {},\n };\n for (let count = 0; count < node.length; count++) {\n const treeNode = node.getNode(count);\n const records = getAndValidateNodeProps(treeNode,\n [\"name\", \"value\", \"children\", \"unreferenced\"], false);\n assertBlobCoreInstance(records.name, \"Path should be of BlobCore\");\n const path = records.name.toString();\n if (records.value !== undefined) {\n assertBlobCoreInstance(records.value, \"Blob value should be BlobCore\");\n snapshotTree.blobs[path] = records.value.toString();\n } else if (records.children !== undefined) {\n assertNodeCoreInstance(records.children, \"Trees should be of type NodeCore\");\n snapshotTree.trees[path] = readTreeSection(records.children);\n } else {\n snapshotTree.trees[path] = { blobs: {}, commits: {}, trees: {} };\n }\n if (records.unreferenced !== undefined) {\n assertBoolInstance(records.unreferenced, \"Unreferenced flag should be bool\");\n const unreferenced = records.unreferenced.valueOf();\n assert(unreferenced, 0x281 /* \"Unreferenced if present should be true\" */);\n snapshotTree.unreferenced = unreferenced;\n }\n }\n return snapshotTree;\n}\n\n/**\n * Recreates snapshot tree out of tree representation.\n * @param node - tree node to de-serialize from\n */\nfunction readSnapshotSection(node: NodeTypes): ISnapshotSection {\n assertNodeCoreInstance(node, \"Snapshot should be of type NodeCore\");\n const records = getAndValidateNodeProps(node,\n [\"id\", \"sequenceNumber\", \"treeNodes\"]);\n\n assertNodeCoreInstance(records.treeNodes, \"TreeNodes should be of type NodeCore\");\n assertNumberInstance(records.sequenceNumber, \"sequenceNumber should be of type number\");\n assertBlobCoreInstance(records.id, \"snapshotId should be BlobCore\");\n const snapshotTree: ISnapshotTree = readTreeSection(records.treeNodes);\n snapshotTree.id = records.id.toString();\n const sequenceNumber = records.sequenceNumber.valueOf();\n return {\n sequenceNumber,\n snapshotTree,\n };\n}\n\n/**\n * Converts snapshot from binary compact representation to tree/blobs/ops.\n * @param buffer - Compact snapshot to be parsed into tree/blobs/ops.\n * @returns - tree, blobs and ops from the snapshot.\n */\nexport function parseCompactSnapshotResponse(buffer: ReadBuffer): ISnapshotContents {\n const builder = TreeBuilder.load(buffer);\n assert(builder.length === 1, 0x219 /* \"1 root should be there\" */);\n const root = builder.getNode(0);\n\n const records = getAndValidateNodeProps(root,\n [\"mrv\", \"cv\", \"lsn\", \"snapshot\", \"blobs\", \"deltas\"], false);\n\n assertBlobCoreInstance(records.mrv, \"minReadVersion should be of BlobCore type\");\n assertBlobCoreInstance(records.cv, \"createVersion should be of BlobCore type\");\n if (records.lsn !== undefined) {\n assertNumberInstance(records.lsn, \"lsn should be a number\");\n }\n\n assert(parseFloat(snapshotMinReadVersion) >= parseFloat(records.mrv.toString()),\n 0x20f /* \"Driver min read version should >= to server minReadVersion\" */);\n assert(parseFloat(records.cv.toString()) >= parseFloat(snapshotMinReadVersion),\n 0x210 /* \"Snapshot should be created with minReadVersion or above\" */);\n assert(currentReadVersion === records.cv.toString(),\n 0x2c2 /* \"Create Version should be equal to currentReadVersion\" */);\n\n return {\n ...readSnapshotSection(records.snapshot),\n blobs: readBlobSection(records.blobs),\n ops: records.deltas !== undefined ? readOpsSection(records.deltas) : [],\n latestSequenceNumber: records.lsn,\n };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"compactSnapshotWriter.d.ts","sourceRoot":"","sources":["../src/compactSnapshotWriter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAkH/C;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,gBAAgB,EAAE,iBAAiB,GAAG,UAAU,CAyBxF"}
1
+ {"version":3,"file":"compactSnapshotWriter.d.ts","sourceRoot":"","sources":["../src/compactSnapshotWriter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAqH/C;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,gBAAgB,EAAE,iBAAiB,GAAG,UAAU,CAyBxF"}
@@ -54,9 +54,12 @@ function writeTreeSectionCore(treesNode, snapshotTree) {
54
54
  if (snapshotTree.unreferenced) {
55
55
  addBoolProperty(treeNode, "unreferenced", snapshotTree.unreferenced);
56
56
  }
57
- treeNode.addString("children", true);
58
- const childNode = treeNode.addNode("list");
59
- writeTreeSectionCore(childNode, value);
57
+ // Only write children prop if either blobs or trees are present.
58
+ if (Object.keys(value.blobs).length > 0 || Object.keys(value.trees).length > 0) {
59
+ treeNode.addString("children", true);
60
+ const childNode = treeNode.addNode("list");
61
+ writeTreeSectionCore(childNode, value);
62
+ }
60
63
  }
61
64
  if (snapshotTree.blobs) {
62
65
  for (const [path, id] of Object.entries(snapshotTree.blobs)) {
@@ -1 +1 @@
1
- {"version":3,"file":"compactSnapshotWriter.js","sourceRoot":"","sources":["../src/compactSnapshotWriter.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert, stringToBuffer } from \"@fluidframework/common-utils\";\nimport { IBlob, ISequencedDocumentMessage, ISnapshotTree } from \"@fluidframework/protocol-definitions\";\nimport { snapshotMinReadVersion } from \"./compactSnapshotParser\";\nimport { ISnapshotContents } from \"./odspPublicUtils\";\nimport { ReadBuffer } from \"./ReadBufferUtils\";\nimport { TreeBuilderSerializer } from \"./WriteBufferUtils\";\nimport { addBoolProperty, addNumberProperty, addStringProperty, NodeCore } from \"./zipItDataRepresentationUtils\";\n\n/**\n * Writes header section of the snapshot.\n * @param node - snapshot node to serialize to\n * @param latestSequenceNumber - latest seq number of the container.\n*/\nfunction writeSnapshotProps(node: NodeCore, latestSequenceNumber: number) {\n addStringProperty(node, \"mrv\", snapshotMinReadVersion);\n addStringProperty(node, \"cv\", snapshotMinReadVersion);\n addNumberProperty(node, \"lsn\", latestSequenceNumber);\n}\n\n/**\n * Represents blobs in the tree.\n * @param snapshotNode - node to serialize to.\n * @param blobs - blobs that is being serialized\n*/\nfunction writeBlobsSection(snapshotNode: NodeCore, blobs: Map<string, IBlob | ArrayBuffer>) {\n snapshotNode.addString(\"blobs\", true);\n const blobsNode = snapshotNode.addNode(\"list\");\n for (const [storageBlobId, blob] of blobs) {\n const blobNode = blobsNode.addNode();\n addStringProperty(blobNode, \"id\", storageBlobId, true);\n blobNode.addString(\"data\", true);\n if (blob instanceof ArrayBuffer) {\n blobNode.addBlob(new Uint8Array(blob), false);\n } else {\n blobNode.addBlob(new Uint8Array(stringToBuffer(blob.contents, blob.encoding ?? \"utf-8\")), false);\n }\n }\n}\n\n/**\n * Represents and serializes tree part of the snapshot\n * @param snapshotNode - tree node to serialize to\n * @param snapshotTree - snapshot tree that is being serialized\n*/\nfunction writeTreeSection(snapshotNode: NodeCore, snapshotTree: ISnapshotTree) {\n snapshotNode.addString(\"treeNodes\", true);\n const treesNode = snapshotNode.addNode(\"list\");\n writeTreeSectionCore(treesNode, snapshotTree);\n}\n\nfunction writeTreeSectionCore(treesNode: NodeCore, snapshotTree: ISnapshotTree) {\n for (const [path, value] of Object.entries(snapshotTree.trees)) {\n const treeNode = treesNode.addNode();\n addStringProperty(treeNode, \"name\", path);\n if (snapshotTree.unreferenced) {\n addBoolProperty(treeNode, \"unreferenced\", snapshotTree.unreferenced);\n }\n treeNode.addString(\"children\", true);\n const childNode = treeNode.addNode(\"list\");\n writeTreeSectionCore(childNode, value);\n }\n\n if (snapshotTree.blobs) {\n for (const [path, id] of Object.entries(snapshotTree.blobs)) {\n const blobNode = treesNode.addNode();\n addStringProperty(blobNode, \"name\", path);\n addStringProperty(blobNode, \"value\", id, true);\n }\n }\n}\n\n/**\n * Represents (serializes) snapshot tree as generalizes tree\n * @param rootNode - tree node to serialize to\n * @param snapshotTree - snapshot tree that is being serialized\n * @param blobs - blobs mapping of the snapshot\n * @param snapshotSequenceNumber - seq number at which snapshot is taken\n*/\nfunction writeSnapshotSection(\n rootNode: NodeCore,\n snapshotTree: ISnapshotTree,\n snapshotSequenceNumber: number,\n) {\n rootNode.addString(\"snapshot\", true);\n const snapshotNode = rootNode.addNode();\n\n const snapshotId = snapshotTree.id;\n assert(snapshotId !== undefined, 0x21b /* \"Snapshot id should be provided\" */);\n addStringProperty(snapshotNode, \"id\", snapshotId);\n addStringProperty(snapshotNode, \"message\", `Snapshot@${snapshotSequenceNumber}`);\n addNumberProperty(snapshotNode, \"sequenceNumber\", snapshotSequenceNumber);\n\n // Add Trees\n writeTreeSection(snapshotNode, snapshotTree);\n}\n\n/**\n * Represents ops in the tree.\n * @param rootNode - node to serialize to.\n * @param ops - ops that is being serialized\n*/\nfunction writeOpsSection(rootNode: NodeCore, ops: ISequencedDocumentMessage[]) {\n let firstSequenceNumber: number | undefined;\n if (ops.length > 0) {\n firstSequenceNumber = ops[0].sequenceNumber;\n }\n if (firstSequenceNumber !== undefined) {\n rootNode.addString(\"deltas\", true);\n const opsNode = rootNode.addNode();\n addNumberProperty(opsNode, \"firstSequenceNumber\", firstSequenceNumber);\n opsNode.addString(\"deltas\", true);\n const deltaNode = opsNode.addNode(\"list\");\n ops.forEach((op) => {\n deltaNode.addString(JSON.stringify(op), false);\n });\n }\n}\n\n/**\n * Converts trees/blobs/ops to binary compact representation.\n * @param snapshotContents - snapshot tree contents to serialize\n * @returns - ReadBuffer - binary representation of the data.\n */\nexport function convertToCompactSnapshot(snapshotContents: ISnapshotContents): ReadBuffer {\n const builder = new TreeBuilderSerializer();\n // Create the root node.\n const rootNode = builder.addNode();\n assert(snapshotContents.sequenceNumber !== undefined, 0x21c /* \"Seq number should be provided\" */);\n\n const latestSequenceNumber = snapshotContents.latestSequenceNumber ??\n snapshotContents.ops.length > 0 ?\n snapshotContents.ops[snapshotContents.ops.length - 1].sequenceNumber : snapshotContents.sequenceNumber;\n\n writeSnapshotProps(rootNode, latestSequenceNumber);\n\n writeSnapshotSection(\n rootNode,\n snapshotContents.snapshotTree,\n snapshotContents.sequenceNumber,\n );\n\n // Add Blobs\n writeBlobsSection(rootNode, snapshotContents.blobs);\n\n // Then write the ops node.\n writeOpsSection(rootNode, snapshotContents.ops);\n\n return builder.serialize();\n}\n"]}
1
+ {"version":3,"file":"compactSnapshotWriter.js","sourceRoot":"","sources":["../src/compactSnapshotWriter.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert, stringToBuffer } from \"@fluidframework/common-utils\";\nimport { IBlob, ISequencedDocumentMessage, ISnapshotTree } from \"@fluidframework/protocol-definitions\";\nimport { snapshotMinReadVersion } from \"./compactSnapshotParser\";\nimport { ISnapshotContents } from \"./odspPublicUtils\";\nimport { ReadBuffer } from \"./ReadBufferUtils\";\nimport { TreeBuilderSerializer } from \"./WriteBufferUtils\";\nimport { addBoolProperty, addNumberProperty, addStringProperty, NodeCore } from \"./zipItDataRepresentationUtils\";\n\n/**\n * Writes header section of the snapshot.\n * @param node - snapshot node to serialize to\n * @param latestSequenceNumber - latest seq number of the container.\n*/\nfunction writeSnapshotProps(node: NodeCore, latestSequenceNumber: number) {\n addStringProperty(node, \"mrv\", snapshotMinReadVersion);\n addStringProperty(node, \"cv\", snapshotMinReadVersion);\n addNumberProperty(node, \"lsn\", latestSequenceNumber);\n}\n\n/**\n * Represents blobs in the tree.\n * @param snapshotNode - node to serialize to.\n * @param blobs - blobs that is being serialized\n*/\nfunction writeBlobsSection(snapshotNode: NodeCore, blobs: Map<string, IBlob | ArrayBuffer>) {\n snapshotNode.addString(\"blobs\", true);\n const blobsNode = snapshotNode.addNode(\"list\");\n for (const [storageBlobId, blob] of blobs) {\n const blobNode = blobsNode.addNode();\n addStringProperty(blobNode, \"id\", storageBlobId, true);\n blobNode.addString(\"data\", true);\n if (blob instanceof ArrayBuffer) {\n blobNode.addBlob(new Uint8Array(blob), false);\n } else {\n blobNode.addBlob(new Uint8Array(stringToBuffer(blob.contents, blob.encoding ?? \"utf-8\")), false);\n }\n }\n}\n\n/**\n * Represents and serializes tree part of the snapshot\n * @param snapshotNode - tree node to serialize to\n * @param snapshotTree - snapshot tree that is being serialized\n*/\nfunction writeTreeSection(snapshotNode: NodeCore, snapshotTree: ISnapshotTree) {\n snapshotNode.addString(\"treeNodes\", true);\n const treesNode = snapshotNode.addNode(\"list\");\n writeTreeSectionCore(treesNode, snapshotTree);\n}\n\nfunction writeTreeSectionCore(treesNode: NodeCore, snapshotTree: ISnapshotTree) {\n for (const [path, value] of Object.entries(snapshotTree.trees)) {\n const treeNode = treesNode.addNode();\n addStringProperty(treeNode, \"name\", path);\n if (snapshotTree.unreferenced) {\n addBoolProperty(treeNode, \"unreferenced\", snapshotTree.unreferenced);\n }\n // Only write children prop if either blobs or trees are present.\n if (Object.keys(value.blobs).length > 0 || Object.keys(value.trees).length > 0) {\n treeNode.addString(\"children\", true);\n const childNode = treeNode.addNode(\"list\");\n writeTreeSectionCore(childNode, value);\n }\n }\n\n if (snapshotTree.blobs) {\n for (const [path, id] of Object.entries(snapshotTree.blobs)) {\n const blobNode = treesNode.addNode();\n addStringProperty(blobNode, \"name\", path);\n addStringProperty(blobNode, \"value\", id, true);\n }\n }\n}\n\n/**\n * Represents (serializes) snapshot tree as generalizes tree\n * @param rootNode - tree node to serialize to\n * @param snapshotTree - snapshot tree that is being serialized\n * @param blobs - blobs mapping of the snapshot\n * @param snapshotSequenceNumber - seq number at which snapshot is taken\n*/\nfunction writeSnapshotSection(\n rootNode: NodeCore,\n snapshotTree: ISnapshotTree,\n snapshotSequenceNumber: number,\n) {\n rootNode.addString(\"snapshot\", true);\n const snapshotNode = rootNode.addNode();\n\n const snapshotId = snapshotTree.id;\n assert(snapshotId !== undefined, 0x21b /* \"Snapshot id should be provided\" */);\n addStringProperty(snapshotNode, \"id\", snapshotId);\n addStringProperty(snapshotNode, \"message\", `Snapshot@${snapshotSequenceNumber}`);\n addNumberProperty(snapshotNode, \"sequenceNumber\", snapshotSequenceNumber);\n\n // Add Trees\n writeTreeSection(snapshotNode, snapshotTree);\n}\n\n/**\n * Represents ops in the tree.\n * @param rootNode - node to serialize to.\n * @param ops - ops that is being serialized\n*/\nfunction writeOpsSection(rootNode: NodeCore, ops: ISequencedDocumentMessage[]) {\n let firstSequenceNumber: number | undefined;\n if (ops.length > 0) {\n firstSequenceNumber = ops[0].sequenceNumber;\n }\n if (firstSequenceNumber !== undefined) {\n rootNode.addString(\"deltas\", true);\n const opsNode = rootNode.addNode();\n addNumberProperty(opsNode, \"firstSequenceNumber\", firstSequenceNumber);\n opsNode.addString(\"deltas\", true);\n const deltaNode = opsNode.addNode(\"list\");\n ops.forEach((op) => {\n deltaNode.addString(JSON.stringify(op), false);\n });\n }\n}\n\n/**\n * Converts trees/blobs/ops to binary compact representation.\n * @param snapshotContents - snapshot tree contents to serialize\n * @returns - ReadBuffer - binary representation of the data.\n */\nexport function convertToCompactSnapshot(snapshotContents: ISnapshotContents): ReadBuffer {\n const builder = new TreeBuilderSerializer();\n // Create the root node.\n const rootNode = builder.addNode();\n assert(snapshotContents.sequenceNumber !== undefined, 0x21c /* \"Seq number should be provided\" */);\n\n const latestSequenceNumber = snapshotContents.latestSequenceNumber ??\n snapshotContents.ops.length > 0 ?\n snapshotContents.ops[snapshotContents.ops.length - 1].sequenceNumber : snapshotContents.sequenceNumber;\n\n writeSnapshotProps(rootNode, latestSequenceNumber);\n\n writeSnapshotSection(\n rootNode,\n snapshotContents.snapshotTree,\n snapshotContents.sequenceNumber,\n );\n\n // Add Blobs\n writeBlobsSection(rootNode, snapshotContents.blobs);\n\n // Then write the ops node.\n writeOpsSection(rootNode, snapshotContents.ops);\n\n return builder.serialize();\n}\n"]}
@@ -65,7 +65,7 @@ export async function getFileLink(getToken, odspUrlParts, identityType, logger)
65
65
  async function getFileLinkCore(getToken, odspUrlParts, identityType, logger) {
66
66
  const fileItem = await getFileItemLite(getToken, odspUrlParts, logger, identityType === "Consumer");
67
67
  // ODSP link requires extra call to return link that is resistant to file being renamed or moved to different folder
68
- return PerformanceEvent.timedExecAsync(logger, { eventName: "odspFileLink", requestName: "getSharingLink" }, async (event) => {
68
+ return PerformanceEvent.timedExecAsync(logger, { eventName: "odspFileLink", requestName: "getSharingInformation" }, async (event) => {
69
69
  let attempts = 0;
70
70
  let additionalProps;
71
71
  const fileLink = await getWithRetryForTokenRefresh(async (options) => {
@@ -74,7 +74,7 @@ async function getFileLinkCore(getToken, odspUrlParts, identityType, logger) {
74
74
  const storageTokenFetcher = toInstrumentedOdspTokenFetcher(logger, odspUrlParts, getToken, true /* throwOnNullToken */);
75
75
  const storageToken = await storageTokenFetcher(options, "GetFileLinkCore");
76
76
  assert(storageToken !== null, 0x2bb /* "Instrumented token fetcher with throwOnNullToken = true should never return null" */);
77
- const { url, headers } = getUrlAndHeadersWithAuth(`${odspUrlParts.siteUrl}/_api/web/GetFileByServerRelativeUrl(@a1)/Linkingurl?@a1=${encodeURIComponent(`'${new URL(fileItem.webDavUrl).pathname}'`)}`, storageToken, false);
77
+ const { url, headers } = getUrlAndHeadersWithAuth(`${odspUrlParts.siteUrl}/_api/web/GetFileByUrl(@a1)/ListItemAllFields/GetSharingInformation?@a1=${encodeURIComponent(`'${fileItem.webDavUrl}'`)}`, storageToken, false);
78
78
  const requestInit = {
79
79
  method: "POST",
80
80
  headers: Object.assign({ "Content-Type": "application/json;odata=verbose", "Accept": "application/json;odata=verbose" }, headers),
@@ -82,12 +82,12 @@ async function getFileLinkCore(getToken, odspUrlParts, identityType, logger) {
82
82
  const response = await fetchHelper(url, requestInit);
83
83
  additionalProps = response.propsToLog;
84
84
  const sharingInfo = await response.content.json();
85
- const linkingUrl = (_a = sharingInfo === null || sharingInfo === void 0 ? void 0 : sharingInfo.d) === null || _a === void 0 ? void 0 : _a.LinkingUrl;
86
- if (typeof linkingUrl !== "string") {
85
+ const directUrl = (_a = sharingInfo === null || sharingInfo === void 0 ? void 0 : sharingInfo.d) === null || _a === void 0 ? void 0 : _a.directUrl;
86
+ if (typeof directUrl !== "string") {
87
87
  // This will retry once in getWithRetryForTokenRefresh
88
- throw new NonRetryableError("Malformed GetSharingLink response", DriverErrorType.incorrectServerResponse, { driverVersion });
88
+ throw new NonRetryableError("Malformed GetSharingInformation response", DriverErrorType.incorrectServerResponse, { driverVersion });
89
89
  }
90
- return linkingUrl;
90
+ return directUrl;
91
91
  });
92
92
  event.end(Object.assign(Object.assign({}, additionalProps), { attempts }));
93
93
  return fileLink;
@@ -1 +1 @@
1
- {"version":3,"file":"getFileLink.js","sourceRoot":"","sources":["../src/getFileLink.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 { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { assert, delay } from \"@fluidframework/common-utils\";\nimport { canRetryOnError, getRetryDelayFromError, NonRetryableError } from \"@fluidframework/driver-utils\";\nimport { PerformanceEvent } from \"@fluidframework/telemetry-utils\";\nimport { DriverErrorType } from \"@fluidframework/driver-definitions\";\nimport {\n IOdspUrlParts,\n OdspResourceTokenFetchOptions,\n IdentityType,\n TokenFetcher,\n} from \"@fluidframework/odsp-driver-definitions\";\nimport { getUrlAndHeadersWithAuth } from \"./getUrlAndHeadersWithAuth\";\nimport { fetchHelper, getWithRetryForTokenRefresh, toInstrumentedOdspTokenFetcher } from \"./odspUtils\";\nimport { pkgVersion as driverVersion } from \"./packageVersion\";\n\n// Store cached responses for the lifetime of web session as file link remains the same for given file item\nconst fileLinkCache = new Map<string, Promise<string>>();\n\n/**\n * Returns file link for a file with given drive and item ids.\n * Scope needed: files.readwrite.all.\n * This function keeps retrying if it gets a retriable error or wait for some delay if it gets a\n * throttling error. In future, we are thinking of app allowing to pass some cancel token, with which\n * we would be able to stop retrying.\n * @param getToken - used to fetch access tokens needed to execute operation\n * @param siteUrl - url of the site that contains the file\n * @param driveId - drive where file is stored\n * @param itemId - file id\n * @param identityType - type of client account\n * @param logger - used to log results of operation, including any error\n * @returns Promise which resolves to file link url when successful; otherwise, undefined.\n */\nexport async function getFileLink(\n getToken: TokenFetcher<OdspResourceTokenFetchOptions>,\n odspUrlParts: IOdspUrlParts,\n identityType: IdentityType,\n logger: ITelemetryLogger,\n): Promise<string> {\n const cacheKey = `${odspUrlParts.siteUrl}_${odspUrlParts.driveId}_${odspUrlParts.itemId}`;\n const maybeFileLinkCacheEntry = fileLinkCache.get(cacheKey);\n if (maybeFileLinkCacheEntry !== undefined) {\n return maybeFileLinkCacheEntry;\n }\n\n const valueGenerator = async function() {\n let result: string | undefined;\n let success = false;\n let retryAfterMs = 1000;\n do {\n try {\n result = await getFileLinkCore(getToken, odspUrlParts, identityType, logger);\n success = true;\n } catch (err) {\n // If it is not retriable, then just throw\n if (!canRetryOnError(err)) {\n // Delete from the cache to permit retrying later.\n fileLinkCache.delete(cacheKey);\n throw err;\n }\n // If the error is throttling error, then wait for the specified time before retrying.\n // If the waitTime is not specified, then we start with retrying immediately to max of 8s.\n retryAfterMs = getRetryDelayFromError(err) ?? Math.min(retryAfterMs * 2, 8000);\n await delay(retryAfterMs);\n }\n } while (!success);\n\n // We are guaranteed to run the getFileLinkCore at least once with successful result (which must be a string)\n assert(result !== undefined, 0x292 /* \"Unexpected undefined result from getFileLinkCore\" */);\n return result;\n };\n const fileLink = valueGenerator();\n fileLinkCache.set(cacheKey, fileLink);\n return fileLink;\n}\n\nasync function getFileLinkCore(\n getToken: TokenFetcher<OdspResourceTokenFetchOptions>,\n odspUrlParts: IOdspUrlParts,\n identityType: IdentityType,\n logger: ITelemetryLogger,\n): Promise<string> {\n const fileItem = await getFileItemLite(getToken, odspUrlParts, logger, identityType === \"Consumer\");\n\n // ODSP link requires extra call to return link that is resistant to file being renamed or moved to different folder\n return PerformanceEvent.timedExecAsync(\n logger,\n { eventName: \"odspFileLink\", requestName: \"getSharingLink\" },\n async (event) => {\n let attempts = 0;\n let additionalProps;\n const fileLink = await getWithRetryForTokenRefresh(async (options) => {\n attempts++;\n const storageTokenFetcher = toInstrumentedOdspTokenFetcher(\n logger,\n odspUrlParts,\n getToken,\n true /* throwOnNullToken */,\n );\n const storageToken = await storageTokenFetcher(options, \"GetFileLinkCore\");\n assert(storageToken !== null,\n 0x2bb /* \"Instrumented token fetcher with throwOnNullToken = true should never return null\" */);\n\n const { url, headers } = getUrlAndHeadersWithAuth(\n `${odspUrlParts.siteUrl}/_api/web/GetFileByServerRelativeUrl(@a1)/Linkingurl?@a1=${\n encodeURIComponent(`'${new URL(fileItem.webDavUrl).pathname}'`)\n }`,\n storageToken,\n false,\n );\n const requestInit = {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json;odata=verbose\",\n \"Accept\": \"application/json;odata=verbose\",\n ...headers,\n },\n };\n const response = await fetchHelper(url, requestInit);\n additionalProps = response.propsToLog;\n\n const sharingInfo = await response.content.json();\n const linkingUrl = sharingInfo?.d?.LinkingUrl;\n if (typeof linkingUrl !== \"string\") {\n // This will retry once in getWithRetryForTokenRefresh\n throw new NonRetryableError(\n \"Malformed GetSharingLink response\",\n DriverErrorType.incorrectServerResponse,\n { driverVersion });\n }\n return linkingUrl;\n });\n event.end({ ...additionalProps, attempts });\n return fileLink;\n },\n );\n}\n\n/**\n * This represents a lite version of file item containing only the webUrl and webDavUrl properties\n */\ninterface FileItemLite {\n webUrl: string;\n webDavUrl: string;\n}\n\nconst isFileItemLite = (maybeFileItemLite: any): maybeFileItemLite is FileItemLite => {\n if (typeof maybeFileItemLite.webUrl !== \"string\" || typeof maybeFileItemLite.webDavUrl !== \"string\") {\n return false;\n }\n return true;\n};\n\nasync function getFileItemLite(\n getToken: TokenFetcher<OdspResourceTokenFetchOptions>,\n odspUrlParts: IOdspUrlParts,\n logger: ITelemetryLogger,\n forceAccessTokenViaAuthorizationHeader: boolean,\n): Promise<FileItemLite> {\n return PerformanceEvent.timedExecAsync(\n logger,\n { eventName: \"odspFileLink\", requestName: \"getFileItemLite\" },\n async (event) => {\n let attempts = 0;\n let additionalProps;\n const fileItem = await getWithRetryForTokenRefresh(async (options) => {\n attempts++;\n const { siteUrl, driveId, itemId } = odspUrlParts;\n const storageTokenFetcher = toInstrumentedOdspTokenFetcher(\n logger,\n odspUrlParts,\n getToken,\n true /* throwOnNullToken */,\n );\n const storageToken = await storageTokenFetcher(options, \"GetFileItemLite\");\n assert(storageToken !== null,\n 0x2bc /* \"Instrumented token fetcher with throwOnNullToken =true should never return null\" */);\n\n const { url, headers } = getUrlAndHeadersWithAuth(\n `${siteUrl}/_api/v2.0/drives/${driveId}/items/${itemId}?select=webUrl,webDavUrl`,\n storageToken,\n forceAccessTokenViaAuthorizationHeader,\n );\n const requestInit = { method: \"GET\", headers };\n const response = await fetchHelper(url, requestInit);\n additionalProps = response.propsToLog;\n\n const responseJson = await response.content.json();\n if (!isFileItemLite(responseJson)) {\n // This will retry once in getWithRetryForTokenRefresh\n throw new NonRetryableError(\n \"Malformed getFileItemLite response\",\n DriverErrorType.incorrectServerResponse,\n { driverVersion });\n }\n return responseJson;\n });\n event.end({ ...additionalProps, attempts });\n return fileItem;\n },\n );\n}\n"]}
1
+ {"version":3,"file":"getFileLink.js","sourceRoot":"","sources":["../src/getFileLink.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 { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { assert, delay } from \"@fluidframework/common-utils\";\nimport { canRetryOnError, getRetryDelayFromError, NonRetryableError } from \"@fluidframework/driver-utils\";\nimport { PerformanceEvent } from \"@fluidframework/telemetry-utils\";\nimport { DriverErrorType } from \"@fluidframework/driver-definitions\";\nimport {\n IOdspUrlParts,\n OdspResourceTokenFetchOptions,\n IdentityType,\n TokenFetcher,\n} from \"@fluidframework/odsp-driver-definitions\";\nimport { getUrlAndHeadersWithAuth } from \"./getUrlAndHeadersWithAuth\";\nimport { fetchHelper, getWithRetryForTokenRefresh, toInstrumentedOdspTokenFetcher } from \"./odspUtils\";\nimport { pkgVersion as driverVersion } from \"./packageVersion\";\n\n// Store cached responses for the lifetime of web session as file link remains the same for given file item\nconst fileLinkCache = new Map<string, Promise<string>>();\n\n/**\n * Returns file link for a file with given drive and item ids.\n * Scope needed: files.readwrite.all.\n * This function keeps retrying if it gets a retriable error or wait for some delay if it gets a\n * throttling error. In future, we are thinking of app allowing to pass some cancel token, with which\n * we would be able to stop retrying.\n * @param getToken - used to fetch access tokens needed to execute operation\n * @param siteUrl - url of the site that contains the file\n * @param driveId - drive where file is stored\n * @param itemId - file id\n * @param identityType - type of client account\n * @param logger - used to log results of operation, including any error\n * @returns Promise which resolves to file link url when successful; otherwise, undefined.\n */\nexport async function getFileLink(\n getToken: TokenFetcher<OdspResourceTokenFetchOptions>,\n odspUrlParts: IOdspUrlParts,\n identityType: IdentityType,\n logger: ITelemetryLogger,\n): Promise<string> {\n const cacheKey = `${odspUrlParts.siteUrl}_${odspUrlParts.driveId}_${odspUrlParts.itemId}`;\n const maybeFileLinkCacheEntry = fileLinkCache.get(cacheKey);\n if (maybeFileLinkCacheEntry !== undefined) {\n return maybeFileLinkCacheEntry;\n }\n\n const valueGenerator = async function() {\n let result: string | undefined;\n let success = false;\n let retryAfterMs = 1000;\n do {\n try {\n result = await getFileLinkCore(getToken, odspUrlParts, identityType, logger);\n success = true;\n } catch (err) {\n // If it is not retriable, then just throw\n if (!canRetryOnError(err)) {\n // Delete from the cache to permit retrying later.\n fileLinkCache.delete(cacheKey);\n throw err;\n }\n // If the error is throttling error, then wait for the specified time before retrying.\n // If the waitTime is not specified, then we start with retrying immediately to max of 8s.\n retryAfterMs = getRetryDelayFromError(err) ?? Math.min(retryAfterMs * 2, 8000);\n await delay(retryAfterMs);\n }\n } while (!success);\n\n // We are guaranteed to run the getFileLinkCore at least once with successful result (which must be a string)\n assert(result !== undefined, 0x292 /* \"Unexpected undefined result from getFileLinkCore\" */);\n return result;\n };\n const fileLink = valueGenerator();\n fileLinkCache.set(cacheKey, fileLink);\n return fileLink;\n}\n\nasync function getFileLinkCore(\n getToken: TokenFetcher<OdspResourceTokenFetchOptions>,\n odspUrlParts: IOdspUrlParts,\n identityType: IdentityType,\n logger: ITelemetryLogger,\n): Promise<string> {\n const fileItem = await getFileItemLite(getToken, odspUrlParts, logger, identityType === \"Consumer\");\n\n // ODSP link requires extra call to return link that is resistant to file being renamed or moved to different folder\n return PerformanceEvent.timedExecAsync(\n logger,\n { eventName: \"odspFileLink\", requestName: \"getSharingInformation\" },\n async (event) => {\n let attempts = 0;\n let additionalProps;\n const fileLink = await getWithRetryForTokenRefresh(async (options) => {\n attempts++;\n const storageTokenFetcher = toInstrumentedOdspTokenFetcher(\n logger,\n odspUrlParts,\n getToken,\n true /* throwOnNullToken */,\n );\n const storageToken = await storageTokenFetcher(options, \"GetFileLinkCore\");\n assert(storageToken !== null,\n 0x2bb /* \"Instrumented token fetcher with throwOnNullToken = true should never return null\" */);\n\n const { url, headers } = getUrlAndHeadersWithAuth(\n `${odspUrlParts.siteUrl}/_api/web/GetFileByUrl(@a1)/ListItemAllFields/GetSharingInformation?@a1=${\n encodeURIComponent(`'${fileItem.webDavUrl}'`)\n }`,\n storageToken,\n false,\n );\n const requestInit = {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json;odata=verbose\",\n \"Accept\": \"application/json;odata=verbose\",\n ...headers,\n },\n };\n const response = await fetchHelper(url, requestInit);\n additionalProps = response.propsToLog;\n\n const sharingInfo = await response.content.json();\n const directUrl = sharingInfo?.d?.directUrl;\n if (typeof directUrl !== \"string\") {\n // This will retry once in getWithRetryForTokenRefresh\n throw new NonRetryableError(\n \"Malformed GetSharingInformation response\",\n DriverErrorType.incorrectServerResponse,\n { driverVersion });\n }\n return directUrl;\n });\n event.end({ ...additionalProps, attempts });\n return fileLink;\n },\n );\n}\n\n/**\n * This represents a lite version of file item containing only the webUrl and webDavUrl properties\n */\ninterface FileItemLite {\n webUrl: string;\n webDavUrl: string;\n}\n\nconst isFileItemLite = (maybeFileItemLite: any): maybeFileItemLite is FileItemLite => {\n if (typeof maybeFileItemLite.webUrl !== \"string\" || typeof maybeFileItemLite.webDavUrl !== \"string\") {\n return false;\n }\n return true;\n};\n\nasync function getFileItemLite(\n getToken: TokenFetcher<OdspResourceTokenFetchOptions>,\n odspUrlParts: IOdspUrlParts,\n logger: ITelemetryLogger,\n forceAccessTokenViaAuthorizationHeader: boolean,\n): Promise<FileItemLite> {\n return PerformanceEvent.timedExecAsync(\n logger,\n { eventName: \"odspFileLink\", requestName: \"getFileItemLite\" },\n async (event) => {\n let attempts = 0;\n let additionalProps;\n const fileItem = await getWithRetryForTokenRefresh(async (options) => {\n attempts++;\n const { siteUrl, driveId, itemId } = odspUrlParts;\n const storageTokenFetcher = toInstrumentedOdspTokenFetcher(\n logger,\n odspUrlParts,\n getToken,\n true /* throwOnNullToken */,\n );\n const storageToken = await storageTokenFetcher(options, \"GetFileItemLite\");\n assert(storageToken !== null,\n 0x2bc /* \"Instrumented token fetcher with throwOnNullToken =true should never return null\" */);\n\n const { url, headers } = getUrlAndHeadersWithAuth(\n `${siteUrl}/_api/v2.0/drives/${driveId}/items/${itemId}?select=webUrl,webDavUrl`,\n storageToken,\n forceAccessTokenViaAuthorizationHeader,\n );\n const requestInit = { method: \"GET\", headers };\n const response = await fetchHelper(url, requestInit);\n additionalProps = response.propsToLog;\n\n const responseJson = await response.content.json();\n if (!isFileItemLite(responseJson)) {\n // This will retry once in getWithRetryForTokenRefresh\n throw new NonRetryableError(\n \"Malformed getFileItemLite response\",\n DriverErrorType.incorrectServerResponse,\n { driverVersion });\n }\n return responseJson;\n });\n event.end({ ...additionalProps, attempts });\n return fileItem;\n },\n );\n}\n"]}
@@ -5,5 +5,5 @@
5
5
  * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
6
6
  */
7
7
  export declare const pkgName = "@fluidframework/odsp-driver";
8
- export declare const pkgVersion = "1.2.0-78837";
8
+ export declare const pkgVersion = "1.2.2";
9
9
  //# sourceMappingURL=packageVersion.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"packageVersion.d.ts","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,OAAO,gCAAgC,CAAC;AACrD,eAAO,MAAM,UAAU,gBAAgB,CAAC"}
1
+ {"version":3,"file":"packageVersion.d.ts","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,OAAO,gCAAgC,CAAC;AACrD,eAAO,MAAM,UAAU,UAAU,CAAC"}
@@ -5,5 +5,5 @@
5
5
  * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
6
6
  */
7
7
  export const pkgName = "@fluidframework/odsp-driver";
8
- export const pkgVersion = "1.2.0-78837";
8
+ export const pkgVersion = "1.2.2";
9
9
  //# sourceMappingURL=packageVersion.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,6BAA6B,CAAC;AACrD,MAAM,CAAC,MAAM,UAAU,GAAG,aAAa,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/odsp-driver\";\nexport const pkgVersion = \"1.2.0-78837\";\n"]}
1
+ {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,6BAA6B,CAAC;AACrD,MAAM,CAAC,MAAM,UAAU,GAAG,OAAO,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/odsp-driver\";\nexport const pkgVersion = \"1.2.2\";\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/odsp-driver",
3
- "version": "1.2.0-78837",
3
+ "version": "1.2.2",
4
4
  "description": "Socket storage implementation for SPO and ODC",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": {
@@ -62,16 +62,16 @@
62
62
  "dependencies": {
63
63
  "@fluidframework/common-definitions": "^0.20.1",
64
64
  "@fluidframework/common-utils": "^0.32.1",
65
- "@fluidframework/core-interfaces": "1.2.0-78837",
66
- "@fluidframework/driver-base": "1.2.0-78837",
67
- "@fluidframework/driver-definitions": "1.2.0-78837",
68
- "@fluidframework/driver-utils": "1.2.0-78837",
65
+ "@fluidframework/core-interfaces": "^1.2.2",
66
+ "@fluidframework/driver-base": "^1.2.2",
67
+ "@fluidframework/driver-definitions": "^1.2.2",
68
+ "@fluidframework/driver-utils": "^1.2.2",
69
69
  "@fluidframework/gitresources": "^0.1036.5000",
70
- "@fluidframework/odsp-doclib-utils": "1.2.0-78837",
71
- "@fluidframework/odsp-driver-definitions": "1.2.0-78837",
70
+ "@fluidframework/odsp-doclib-utils": "^1.2.2",
71
+ "@fluidframework/odsp-driver-definitions": "^1.2.2",
72
72
  "@fluidframework/protocol-base": "^0.1036.5000",
73
73
  "@fluidframework/protocol-definitions": "^0.1028.2000",
74
- "@fluidframework/telemetry-utils": "1.2.0-78837",
74
+ "@fluidframework/telemetry-utils": "^1.2.2",
75
75
  "abort-controller": "^3.0.0",
76
76
  "node-fetch": "^2.6.1",
77
77
  "socket.io-client": "^4.4.1",
@@ -81,8 +81,8 @@
81
81
  "@fluidframework/build-common": "^0.24.0",
82
82
  "@fluidframework/build-tools": "^0.2.74327",
83
83
  "@fluidframework/eslint-config-fluid": "^0.28.2000",
84
- "@fluidframework/mocha-test-setup": "1.2.0-78837",
85
- "@fluidframework/odsp-driver-previous": "npm:@fluidframework/odsp-driver@1.1.0",
84
+ "@fluidframework/mocha-test-setup": "^1.2.2",
85
+ "@fluidframework/odsp-driver-previous": "npm:@fluidframework/odsp-driver@1.2.1",
86
86
  "@microsoft/api-extractor": "^7.22.2",
87
87
  "@rushstack/eslint-config": "^2.5.1",
88
88
  "@types/mocha": "^9.1.1",
@@ -100,12 +100,7 @@
100
100
  "typescript-formatter": "7.1.0"
101
101
  },
102
102
  "typeValidation": {
103
- "version": "1.2.0",
104
- "broken": {
105
- "VariableDeclaration_OdcApiSiteOrigin": {
106
- "forwardCompat": false,
107
- "backCompat": false
108
- }
109
- }
103
+ "version": "1.2.2",
104
+ "broken": {}
110
105
  }
111
106
  }
@@ -81,9 +81,11 @@ function readTreeSection(node: NodeCore) {
81
81
  if (records.value !== undefined) {
82
82
  assertBlobCoreInstance(records.value, "Blob value should be BlobCore");
83
83
  snapshotTree.blobs[path] = records.value.toString();
84
- } else {
84
+ } else if (records.children !== undefined) {
85
85
  assertNodeCoreInstance(records.children, "Trees should be of type NodeCore");
86
86
  snapshotTree.trees[path] = readTreeSection(records.children);
87
+ } else {
88
+ snapshotTree.trees[path] = { blobs: {}, commits: {}, trees: {} };
87
89
  }
88
90
  if (records.unreferenced !== undefined) {
89
91
  assertBoolInstance(records.unreferenced, "Unreferenced flag should be bool");
@@ -60,9 +60,12 @@ function writeTreeSectionCore(treesNode: NodeCore, snapshotTree: ISnapshotTree)
60
60
  if (snapshotTree.unreferenced) {
61
61
  addBoolProperty(treeNode, "unreferenced", snapshotTree.unreferenced);
62
62
  }
63
- treeNode.addString("children", true);
64
- const childNode = treeNode.addNode("list");
65
- writeTreeSectionCore(childNode, value);
63
+ // Only write children prop if either blobs or trees are present.
64
+ if (Object.keys(value.blobs).length > 0 || Object.keys(value.trees).length > 0) {
65
+ treeNode.addString("children", true);
66
+ const childNode = treeNode.addNode("list");
67
+ writeTreeSectionCore(childNode, value);
68
+ }
66
69
  }
67
70
 
68
71
  if (snapshotTree.blobs) {
@@ -89,7 +89,7 @@ async function getFileLinkCore(
89
89
  // ODSP link requires extra call to return link that is resistant to file being renamed or moved to different folder
90
90
  return PerformanceEvent.timedExecAsync(
91
91
  logger,
92
- { eventName: "odspFileLink", requestName: "getSharingLink" },
92
+ { eventName: "odspFileLink", requestName: "getSharingInformation" },
93
93
  async (event) => {
94
94
  let attempts = 0;
95
95
  let additionalProps;
@@ -106,8 +106,8 @@ async function getFileLinkCore(
106
106
  0x2bb /* "Instrumented token fetcher with throwOnNullToken = true should never return null" */);
107
107
 
108
108
  const { url, headers } = getUrlAndHeadersWithAuth(
109
- `${odspUrlParts.siteUrl}/_api/web/GetFileByServerRelativeUrl(@a1)/Linkingurl?@a1=${
110
- encodeURIComponent(`'${new URL(fileItem.webDavUrl).pathname}'`)
109
+ `${odspUrlParts.siteUrl}/_api/web/GetFileByUrl(@a1)/ListItemAllFields/GetSharingInformation?@a1=${
110
+ encodeURIComponent(`'${fileItem.webDavUrl}'`)
111
111
  }`,
112
112
  storageToken,
113
113
  false,
@@ -124,15 +124,15 @@ async function getFileLinkCore(
124
124
  additionalProps = response.propsToLog;
125
125
 
126
126
  const sharingInfo = await response.content.json();
127
- const linkingUrl = sharingInfo?.d?.LinkingUrl;
128
- if (typeof linkingUrl !== "string") {
127
+ const directUrl = sharingInfo?.d?.directUrl;
128
+ if (typeof directUrl !== "string") {
129
129
  // This will retry once in getWithRetryForTokenRefresh
130
130
  throw new NonRetryableError(
131
- "Malformed GetSharingLink response",
131
+ "Malformed GetSharingInformation response",
132
132
  DriverErrorType.incorrectServerResponse,
133
133
  { driverVersion });
134
134
  }
135
- return linkingUrl;
135
+ return directUrl;
136
136
  });
137
137
  event.end({ ...additionalProps, attempts });
138
138
  return fileLink;
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/odsp-driver";
9
- export const pkgVersion = "1.2.0-78837";
9
+ export const pkgVersion = "1.2.2";