@fluidframework/odsp-driver 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. package/dist/checkUrl.d.ts +1 -1
  2. package/dist/checkUrl.js +1 -1
  3. package/dist/checkUrl.js.map +1 -1
  4. package/dist/constants.d.ts +1 -1
  5. package/dist/constants.d.ts.map +1 -1
  6. package/dist/constants.js +1 -1
  7. package/dist/constants.js.map +1 -1
  8. package/dist/contractsPublic.d.ts +1 -0
  9. package/dist/contractsPublic.d.ts.map +1 -1
  10. package/dist/contractsPublic.js.map +1 -1
  11. package/dist/getFileLink.js +0 -4
  12. package/dist/getFileLink.js.map +1 -1
  13. package/dist/localOdspDriver/localOdspDocumentService.d.ts +26 -0
  14. package/dist/localOdspDriver/localOdspDocumentService.d.ts.map +1 -0
  15. package/dist/localOdspDriver/localOdspDocumentService.js +39 -0
  16. package/dist/localOdspDriver/localOdspDocumentService.js.map +1 -0
  17. package/dist/localOdspDriver/localOdspDocumentServiceFactory.d.ts +24 -0
  18. package/dist/localOdspDriver/localOdspDocumentServiceFactory.d.ts.map +1 -0
  19. package/dist/localOdspDriver/localOdspDocumentServiceFactory.js +45 -0
  20. package/dist/localOdspDriver/localOdspDocumentServiceFactory.js.map +1 -0
  21. package/dist/localOdspDriver/localOdspDocumentStorageManager.d.ts +27 -0
  22. package/dist/localOdspDriver/localOdspDocumentStorageManager.d.ts.map +1 -0
  23. package/dist/localOdspDriver/localOdspDocumentStorageManager.js +66 -0
  24. package/dist/localOdspDriver/localOdspDocumentStorageManager.js.map +1 -0
  25. package/dist/odspDeltaStorageService.js.map +1 -1
  26. package/dist/odspDocumentService.d.ts.map +1 -1
  27. package/dist/odspDocumentService.js.map +1 -1
  28. package/dist/odspDocumentServiceFactory.d.ts +2 -1
  29. package/dist/odspDocumentServiceFactory.d.ts.map +1 -1
  30. package/dist/odspDocumentServiceFactory.js +7 -1
  31. package/dist/odspDocumentServiceFactory.js.map +1 -1
  32. package/dist/odspDocumentServiceFactoryCore.d.ts +3 -1
  33. package/dist/odspDocumentServiceFactoryCore.d.ts.map +1 -1
  34. package/dist/odspDocumentServiceFactoryCore.js.map +1 -1
  35. package/dist/odspDocumentStorageManager.d.ts +5 -23
  36. package/dist/odspDocumentStorageManager.d.ts.map +1 -1
  37. package/dist/odspDocumentStorageManager.js +52 -245
  38. package/dist/odspDocumentStorageManager.js.map +1 -1
  39. package/dist/odspDocumentStorageServiceBase.d.ts +58 -0
  40. package/dist/odspDocumentStorageServiceBase.d.ts.map +1 -0
  41. package/dist/odspDocumentStorageServiceBase.js +216 -0
  42. package/dist/odspDocumentStorageServiceBase.js.map +1 -0
  43. package/dist/odspDriverUrlResolver.js +1 -1
  44. package/dist/odspDriverUrlResolver.js.map +1 -1
  45. package/dist/odspDriverUrlResolverForShareLink.d.ts +8 -2
  46. package/dist/odspDriverUrlResolverForShareLink.d.ts.map +1 -1
  47. package/dist/odspDriverUrlResolverForShareLink.js +11 -3
  48. package/dist/odspDriverUrlResolverForShareLink.js.map +1 -1
  49. package/dist/odspFluidFileLink.d.ts.map +1 -1
  50. package/dist/odspFluidFileLink.js +27 -21
  51. package/dist/odspFluidFileLink.js.map +1 -1
  52. package/dist/packageVersion.d.ts +1 -1
  53. package/dist/packageVersion.js +1 -1
  54. package/dist/packageVersion.js.map +1 -1
  55. package/lib/checkUrl.d.ts +1 -1
  56. package/lib/checkUrl.js +1 -1
  57. package/lib/checkUrl.js.map +1 -1
  58. package/lib/constants.d.ts +1 -1
  59. package/lib/constants.d.ts.map +1 -1
  60. package/lib/constants.js +1 -1
  61. package/lib/constants.js.map +1 -1
  62. package/lib/contractsPublic.d.ts +1 -0
  63. package/lib/contractsPublic.d.ts.map +1 -1
  64. package/lib/contractsPublic.js.map +1 -1
  65. package/lib/getFileLink.js +0 -4
  66. package/lib/getFileLink.js.map +1 -1
  67. package/lib/localOdspDriver/localOdspDocumentService.d.ts +26 -0
  68. package/lib/localOdspDriver/localOdspDocumentService.d.ts.map +1 -0
  69. package/lib/localOdspDriver/localOdspDocumentService.js +35 -0
  70. package/lib/localOdspDriver/localOdspDocumentService.js.map +1 -0
  71. package/lib/localOdspDriver/localOdspDocumentServiceFactory.d.ts +24 -0
  72. package/lib/localOdspDriver/localOdspDocumentServiceFactory.d.ts.map +1 -0
  73. package/lib/localOdspDriver/localOdspDocumentServiceFactory.js +41 -0
  74. package/lib/localOdspDriver/localOdspDocumentServiceFactory.js.map +1 -0
  75. package/lib/localOdspDriver/localOdspDocumentStorageManager.d.ts +27 -0
  76. package/lib/localOdspDriver/localOdspDocumentStorageManager.d.ts.map +1 -0
  77. package/lib/localOdspDriver/localOdspDocumentStorageManager.js +62 -0
  78. package/lib/localOdspDriver/localOdspDocumentStorageManager.js.map +1 -0
  79. package/lib/odspDeltaStorageService.js.map +1 -1
  80. package/lib/odspDocumentService.d.ts.map +1 -1
  81. package/lib/odspDocumentService.js +1 -1
  82. package/lib/odspDocumentService.js.map +1 -1
  83. package/lib/odspDocumentServiceFactory.d.ts +2 -1
  84. package/lib/odspDocumentServiceFactory.d.ts.map +1 -1
  85. package/lib/odspDocumentServiceFactory.js +5 -0
  86. package/lib/odspDocumentServiceFactory.js.map +1 -1
  87. package/lib/odspDocumentServiceFactoryCore.d.ts +3 -1
  88. package/lib/odspDocumentServiceFactoryCore.d.ts.map +1 -1
  89. package/lib/odspDocumentServiceFactoryCore.js.map +1 -1
  90. package/lib/odspDocumentStorageManager.d.ts +5 -23
  91. package/lib/odspDocumentStorageManager.d.ts.map +1 -1
  92. package/lib/odspDocumentStorageManager.js +53 -246
  93. package/lib/odspDocumentStorageManager.js.map +1 -1
  94. package/lib/odspDocumentStorageServiceBase.d.ts +58 -0
  95. package/lib/odspDocumentStorageServiceBase.d.ts.map +1 -0
  96. package/lib/odspDocumentStorageServiceBase.js +212 -0
  97. package/lib/odspDocumentStorageServiceBase.js.map +1 -0
  98. package/lib/odspDriverUrlResolver.js +1 -1
  99. package/lib/odspDriverUrlResolver.js.map +1 -1
  100. package/lib/odspDriverUrlResolverForShareLink.d.ts +8 -2
  101. package/lib/odspDriverUrlResolverForShareLink.d.ts.map +1 -1
  102. package/lib/odspDriverUrlResolverForShareLink.js +11 -3
  103. package/lib/odspDriverUrlResolverForShareLink.js.map +1 -1
  104. package/lib/odspFluidFileLink.d.ts.map +1 -1
  105. package/lib/odspFluidFileLink.js +27 -21
  106. package/lib/odspFluidFileLink.js.map +1 -1
  107. package/lib/packageVersion.d.ts +1 -1
  108. package/lib/packageVersion.js +1 -1
  109. package/lib/packageVersion.js.map +1 -1
  110. package/package.json +17 -12
  111. package/src/checkUrl.ts +1 -1
  112. package/src/constants.ts +1 -1
  113. package/src/contractsPublic.ts +1 -0
  114. package/src/getFileLink.ts +0 -5
  115. package/src/localOdspDriver/localOdspDocumentService.ts +54 -0
  116. package/src/localOdspDriver/localOdspDocumentServiceFactory.ts +67 -0
  117. package/src/localOdspDriver/localOdspDocumentStorageManager.ts +83 -0
  118. package/src/odspDeltaStorageService.ts +1 -1
  119. package/src/odspDocumentService.ts +5 -1
  120. package/src/odspDocumentServiceFactory.ts +7 -3
  121. package/src/odspDocumentServiceFactoryCore.ts +1 -1
  122. package/src/odspDocumentStorageManager.ts +81 -312
  123. package/src/odspDocumentStorageServiceBase.ts +268 -0
  124. package/src/odspDriverUrlResolver.ts +1 -1
  125. package/src/odspDriverUrlResolverForShareLink.ts +13 -1
  126. package/src/odspFluidFileLink.ts +26 -22
  127. package/src/packageVersion.ts +1 -1
@@ -0,0 +1,58 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ import { IDocumentStorageService, ISummaryContext, LoaderCachingPolicy } from "@fluidframework/driver-definitions";
6
+ import * as api from "@fluidframework/protocol-definitions";
7
+ import { ISnapshotContents } from "./odspPublicUtils";
8
+ declare class BlobCache {
9
+ private blobCacheTimeout;
10
+ private deferBlobCacheClear;
11
+ private readonly _blobCache;
12
+ private readonly blobsEvicted;
13
+ private blobCacheTimeoutDuration;
14
+ private readonly purgeEnabled;
15
+ get value(): Map<string, ArrayBuffer>;
16
+ addBlobs(blobs: Map<string, ArrayBuffer>): void;
17
+ /**
18
+ * Schedule a timer for clearing the blob cache or defer the current one.
19
+ */
20
+ private scheduleClearBlobsCache;
21
+ getBlob(blobId: string): {
22
+ blobContent: ArrayBuffer | undefined;
23
+ evicted: boolean;
24
+ };
25
+ setBlob(blobId: string, blob: ArrayBuffer): Map<string, ArrayBuffer> | undefined;
26
+ }
27
+ export declare abstract class OdspDocumentStorageServiceBase implements IDocumentStorageService {
28
+ readonly policies: {
29
+ caching: LoaderCachingPolicy;
30
+ minBlobSize: number;
31
+ maximumCacheDurationMs: number;
32
+ };
33
+ protected readonly commitCache: Map<string, api.ISnapshotTree>;
34
+ private readonly attributesBlobHandles;
35
+ private _ops;
36
+ private _snapshotSequenceNumber;
37
+ protected readonly blobCache: BlobCache;
38
+ set ops(ops: api.ISequencedDocumentMessage[] | undefined);
39
+ get ops(): api.ISequencedDocumentMessage[] | undefined;
40
+ get snapshotSequenceNumber(): number | undefined;
41
+ get repositoryUrl(): string;
42
+ abstract createBlob(file: ArrayBufferLike): Promise<api.ICreateBlobResponse>;
43
+ private readBlobCore;
44
+ protected abstract fetchBlobFromStorage(blobId: string, evicted: boolean): Promise<ArrayBuffer>;
45
+ readBlob(blobId: string): Promise<ArrayBufferLike>;
46
+ getSnapshotTree(version?: api.IVersion, scenarioName?: string): Promise<api.ISnapshotTree | null>;
47
+ abstract getVersions(blobid: string | null, count: number, scenarioName?: string): Promise<api.IVersion[]>;
48
+ abstract uploadSummaryWithContext(summary: api.ISummaryTree, context: ISummaryContext): Promise<string>;
49
+ downloadSummary(commit: api.ISummaryHandle): Promise<api.ISummaryTree>;
50
+ protected setRootTree(id: string, tree: api.ISnapshotTree): void;
51
+ protected initBlobsCache(blobs: Map<string, ArrayBuffer>): void;
52
+ private readTree;
53
+ protected abstract fetchTreeFromSnapshot(id: string, scenarioName?: string): Promise<api.ISnapshotTree | undefined>;
54
+ private combineProtocolAndAppSnapshotTree;
55
+ protected initializeFromSnapshot(odspSnapshotCacheValue: ISnapshotContents): string | undefined;
56
+ }
57
+ export {};
58
+ //# sourceMappingURL=odspDocumentStorageServiceBase.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"odspDocumentStorageServiceBase.d.ts","sourceRoot":"","sources":["../src/odspDocumentStorageServiceBase.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,216 @@
1
+ "use strict";
2
+ /*!
3
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
4
+ * Licensed under the MIT License.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.OdspDocumentStorageServiceBase = void 0;
8
+ const common_utils_1 = require("@fluidframework/common-utils");
9
+ const driver_definitions_1 = require("@fluidframework/driver-definitions");
10
+ const epochTracker_1 = require("./epochTracker");
11
+ /* eslint-disable max-len */
12
+ class BlobCache {
13
+ constructor() {
14
+ // If the defer flag is set when the timeout fires, we'll reschedule rather than clear immediately
15
+ // This deferral approach is used (rather than clearing/resetting the timer) as current calling patterns trigger
16
+ // too many calls to setTimeout/clearTimeout.
17
+ this.deferBlobCacheClear = false;
18
+ this._blobCache = new Map();
19
+ // Tracks all blob IDs evicted from cache
20
+ this.blobsEvicted = new Set();
21
+ // Initial time-out to purge data from cache
22
+ // If this time out is very small, then we purge blobs from cache too soon and that results in a lot of
23
+ // requests to storage, which brings down perf and may trip protection limits causing 429s
24
+ this.blobCacheTimeoutDuration = 2 * 60 * 1000;
25
+ // SPO does not keep old snapshots around for long, so we are running chances of not
26
+ // being able to rehydrate data store / DDS in the future if we purge anything (and with blob de-duping,
27
+ // even if blob read by runtime, it could be read again in the future)
28
+ // So for now, purging is disabled.
29
+ this.purgeEnabled = false;
30
+ }
31
+ get value() {
32
+ return this._blobCache;
33
+ }
34
+ addBlobs(blobs) {
35
+ blobs.forEach((value, blobId) => {
36
+ this._blobCache.set(blobId, value);
37
+ });
38
+ // Reset the timer on cache set
39
+ this.scheduleClearBlobsCache();
40
+ }
41
+ /**
42
+ * Schedule a timer for clearing the blob cache or defer the current one.
43
+ */
44
+ scheduleClearBlobsCache() {
45
+ if (this.blobCacheTimeout !== undefined) {
46
+ // If we already have an outstanding timer, just signal that we should defer the clear
47
+ this.deferBlobCacheClear = true;
48
+ }
49
+ else if (this.purgeEnabled) {
50
+ // If we don't have an outstanding timer, set a timer
51
+ // When the timer runs out, we'll decide whether to proceed with the cache clear or reset the timer
52
+ const clearCacheOrDefer = () => {
53
+ this.blobCacheTimeout = undefined;
54
+ if (this.deferBlobCacheClear) {
55
+ this.deferBlobCacheClear = false;
56
+ this.scheduleClearBlobsCache();
57
+ }
58
+ else {
59
+ // NOTE: Slightly better algorithm here would be to purge either only big blobs,
60
+ // or sort them by size and purge enough big blobs to leave only 256Kb of small blobs in cache
61
+ // Purging is optimizing memory footprint. But count controls potential number of storage requests
62
+ // We want to optimize both - memory footprint and number of future requests to storage.
63
+ // Note that Container can realize data store or DDS on-demand at any point in time, so we do not
64
+ // control when blobs will be used.
65
+ this._blobCache.forEach((_, blobId) => this.blobsEvicted.add(blobId));
66
+ this._blobCache.clear();
67
+ }
68
+ };
69
+ this.blobCacheTimeout = setTimeout(clearCacheOrDefer, this.blobCacheTimeoutDuration);
70
+ // any future storage reads that get into the cache should be cleared from cache rather quickly -
71
+ // there is not much value in keeping them longer
72
+ this.blobCacheTimeoutDuration = 10 * 1000;
73
+ }
74
+ }
75
+ getBlob(blobId) {
76
+ // Reset the timer on attempted cache read
77
+ this.scheduleClearBlobsCache();
78
+ const blobContent = this._blobCache.get(blobId);
79
+ const evicted = this.blobsEvicted.has(blobId);
80
+ return { blobContent, evicted };
81
+ }
82
+ setBlob(blobId, blob) {
83
+ // This API is called as result of cache miss and reading blob from storage.
84
+ // Runtime never reads same blob twice.
85
+ // The only reason we may get read request for same blob is blob de-duping in summaries.
86
+ // Note that the bigger the size, the less likely blobs are the same, so there is very little benefit of caching big blobs.
87
+ // Images are the only exception - user may insert same image twice. But we currently do not de-dup them - only snapshot
88
+ // blobs are de-duped.
89
+ const size = blob.byteLength;
90
+ if (size < 256 * 1024) {
91
+ // Reset the timer on cache set
92
+ this.scheduleClearBlobsCache();
93
+ return this._blobCache.set(blobId, blob);
94
+ }
95
+ else {
96
+ // we evicted it here by not caching.
97
+ this.blobsEvicted.add(blobId);
98
+ }
99
+ }
100
+ }
101
+ class OdspDocumentStorageServiceBase {
102
+ constructor() {
103
+ this.policies = {
104
+ // By default, ODSP tells the container not to prefetch/cache.
105
+ caching: driver_definitions_1.LoaderCachingPolicy.NoCaching,
106
+ // ODSP storage works better if it has less number of blobs / edges
107
+ // Runtime creating many small blobs results in sub-optimal perf.
108
+ // 2K seems like the sweat spot:
109
+ // The smaller the number, less blobs we aggregate. Most storages are very likely to have notion
110
+ // of minimal "cluster" size, so having small blobs is wasteful
111
+ // At the same time increasing the limit ensure that more blobs with user content are aggregated,
112
+ // reducing possibility for de-duping of same blobs (i.e. .attributes rolled into aggregate blob
113
+ // are not reused across data stores, or even within data store, resulting in duplication of content)
114
+ // Note that duplication of content should not have significant impact for bytes over wire as
115
+ // compression of http payload mostly takes care of it, but it does impact storage size and in-memory sizes.
116
+ minBlobSize: 2048,
117
+ maximumCacheDurationMs: epochTracker_1.defaultCacheExpiryTimeoutMs,
118
+ };
119
+ this.commitCache = new Map();
120
+ this.attributesBlobHandles = new Set();
121
+ this.blobCache = new BlobCache();
122
+ }
123
+ set ops(ops) {
124
+ (0, common_utils_1.assert)(this._ops === undefined, 0x0a5 /* "Trying to set ops when they are already set!" */);
125
+ this._ops = ops;
126
+ }
127
+ get ops() {
128
+ return this._ops;
129
+ }
130
+ get snapshotSequenceNumber() {
131
+ return this._snapshotSequenceNumber;
132
+ }
133
+ get repositoryUrl() {
134
+ return "";
135
+ }
136
+ async readBlobCore(blobId) {
137
+ const { blobContent, evicted } = this.blobCache.getBlob(blobId);
138
+ return blobContent !== null && blobContent !== void 0 ? blobContent : this.fetchBlobFromStorage(blobId, evicted);
139
+ }
140
+ async readBlob(blobId) {
141
+ return this.readBlobCore(blobId);
142
+ }
143
+ async getSnapshotTree(version, scenarioName) {
144
+ let id;
145
+ if (!version || !version.id) {
146
+ const versions = await this.getVersions(null, 1, scenarioName);
147
+ if (!versions || versions.length === 0) {
148
+ return null;
149
+ }
150
+ id = versions[0].id;
151
+ }
152
+ else {
153
+ id = version.id;
154
+ }
155
+ const snapshotTree = await this.readTree(id, scenarioName);
156
+ if (!snapshotTree) {
157
+ return null;
158
+ }
159
+ if (snapshotTree.blobs) {
160
+ const attributesBlob = snapshotTree.blobs.attributes;
161
+ if (attributesBlob) {
162
+ this.attributesBlobHandles.add(attributesBlob);
163
+ }
164
+ }
165
+ // When we upload the container snapshot, we upload appTree in ".app" and protocol tree in ".protocol"
166
+ // So when we request the snapshot we get ".app" as tree and not as commit node as in the case just above.
167
+ const appTree = snapshotTree.trees[".app"];
168
+ const protocolTree = snapshotTree.trees[".protocol"];
169
+ return this.combineProtocolAndAppSnapshotTree(appTree, protocolTree);
170
+ }
171
+ async downloadSummary(commit) {
172
+ throw new Error("Not implemented yet");
173
+ }
174
+ setRootTree(id, tree) {
175
+ this.commitCache.set(id, tree);
176
+ }
177
+ initBlobsCache(blobs) {
178
+ this.blobCache.addBlobs(blobs);
179
+ }
180
+ async readTree(id, scenarioName) {
181
+ let tree = this.commitCache.get(id);
182
+ if (!tree) {
183
+ tree = await this.fetchTreeFromSnapshot(id, scenarioName);
184
+ }
185
+ return tree !== null && tree !== void 0 ? tree : null;
186
+ }
187
+ combineProtocolAndAppSnapshotTree(hierarchicalAppTree, hierarchicalProtocolTree) {
188
+ const summarySnapshotTree = {
189
+ blobs: Object.assign({}, hierarchicalAppTree.blobs),
190
+ trees: Object.assign(Object.assign({}, hierarchicalAppTree.trees), {
191
+ // the app tree could have a .protocol
192
+ // in that case we want to server protocol to override it
193
+ ".protocol": hierarchicalProtocolTree }),
194
+ };
195
+ return summarySnapshotTree;
196
+ }
197
+ initializeFromSnapshot(odspSnapshotCacheValue) {
198
+ this._snapshotSequenceNumber = odspSnapshotCacheValue.sequenceNumber;
199
+ const { snapshotTree, blobs, ops } = odspSnapshotCacheValue;
200
+ // id should be undefined in case of just ops in snapshot.
201
+ let id;
202
+ if (snapshotTree) {
203
+ id = snapshotTree.id;
204
+ (0, common_utils_1.assert)(id !== undefined, 0x221 /* "Root tree should contain the id" */);
205
+ this.setRootTree(id, snapshotTree);
206
+ }
207
+ if (blobs) {
208
+ this.initBlobsCache(blobs);
209
+ }
210
+ this.ops = ops;
211
+ return id;
212
+ }
213
+ }
214
+ exports.OdspDocumentStorageServiceBase = OdspDocumentStorageServiceBase;
215
+ /* eslint-enable max-len */
216
+ //# sourceMappingURL=odspDocumentStorageServiceBase.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"odspDocumentStorageServiceBase.js","sourceRoot":"","sources":["../src/odspDocumentStorageServiceBase.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,+DAAsD;AACtD,2EAAmH;AAEnH,iDAA6D;AAG7D,4BAA4B;AAE5B,MAAM,SAAS;IAAf;QAGI,kGAAkG;QAClG,gHAAgH;QAChH,6CAA6C;QACrC,wBAAmB,GAAY,KAAK,CAAC;QAE5B,eAAU,GAA6B,IAAI,GAAG,EAAE,CAAC;QAElE,yCAAyC;QACxB,iBAAY,GAAgB,IAAI,GAAG,EAAE,CAAC;QAEvD,4CAA4C;QAC5C,uGAAuG;QACvG,0FAA0F;QAClF,6BAAwB,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;QAEjD,oFAAoF;QACpF,wGAAwG;QACxG,sEAAsE;QACtE,mCAAmC;QAClB,iBAAY,GAAG,KAAK,CAAC;IAwE1C,CAAC;IAtEG,IAAW,KAAK;QACZ,OAAO,IAAI,CAAC,UAAU,CAAC;IAC3B,CAAC;IAEM,QAAQ,CAAC,KAA+B;QAC3C,KAAK,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;YAC5B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;QACH,+BAA+B;QAC/B,IAAI,CAAC,uBAAuB,EAAE,CAAC;IACnC,CAAC;IAED;;OAEG;IACK,uBAAuB;QAC3B,IAAI,IAAI,CAAC,gBAAgB,KAAK,SAAS,EAAE;YACrC,sFAAsF;YACtF,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC;SACnC;aAAM,IAAI,IAAI,CAAC,YAAY,EAAE;YAC1B,qDAAqD;YACrD,mGAAmG;YACnG,MAAM,iBAAiB,GAAG,GAAG,EAAE;gBAC3B,IAAI,CAAC,gBAAgB,GAAG,SAAS,CAAC;gBAClC,IAAI,IAAI,CAAC,mBAAmB,EAAE;oBAC1B,IAAI,CAAC,mBAAmB,GAAG,KAAK,CAAC;oBACjC,IAAI,CAAC,uBAAuB,EAAE,CAAC;iBAClC;qBAAM;oBACH,gFAAgF;oBAChF,8FAA8F;oBAC9F,kGAAkG;oBAClG,wFAAwF;oBACxF,iGAAiG;oBACjG,mCAAmC;oBACnC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;oBACtE,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;iBAC3B;YACL,CAAC,CAAC;YACF,IAAI,CAAC,gBAAgB,GAAG,UAAU,CAAC,iBAAiB,EAAE,IAAI,CAAC,wBAAwB,CAAC,CAAC;YACrF,iGAAiG;YACjG,iDAAiD;YACjD,IAAI,CAAC,wBAAwB,GAAG,EAAE,GAAG,IAAI,CAAC;SAC7C;IACL,CAAC;IAEM,OAAO,CAAC,MAAc;QACzB,0CAA0C;QAC1C,IAAI,CAAC,uBAAuB,EAAE,CAAC;QAC/B,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAChD,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC9C,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC;IACpC,CAAC;IAEM,OAAO,CAAC,MAAc,EAAE,IAAiB;QAC5C,4EAA4E;QAC5E,uCAAuC;QACvC,wFAAwF;QACxF,2HAA2H;QAC3H,wHAAwH;QACxH,sBAAsB;QACtB,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC;QAC7B,IAAI,IAAI,GAAG,GAAG,GAAG,IAAI,EAAE;YACnB,+BAA+B;YAC/B,IAAI,CAAC,uBAAuB,EAAE,CAAC;YAC/B,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;SAC5C;aAAM;YACH,qCAAqC;YACrC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;SACjC;IACL,CAAC;CACJ;AAED,MAAsB,8BAA8B;IAApD;QACa,aAAQ,GAAG;YAChB,8DAA8D;YAC9D,OAAO,EAAE,wCAAmB,CAAC,SAAS;YAEtC,mEAAmE;YACnE,iEAAiE;YACjE,gCAAgC;YAChC,gGAAgG;YAChG,+DAA+D;YAC/D,iGAAiG;YACjG,gGAAgG;YAChG,qGAAqG;YACrG,6FAA6F;YAC7F,4GAA4G;YAC5G,WAAW,EAAE,IAAI;YACjB,sBAAsB,EAAE,0CAA2B;SACtD,CAAC;QAEiB,gBAAW,GAAmC,IAAI,GAAG,EAAE,CAAC;QAE1D,0BAAqB,GAAgB,IAAI,GAAG,EAAE,CAAC;QAM7C,cAAS,GAAG,IAAI,SAAS,EAAE,CAAC;IAiInD,CAAC;IA/HG,IAAW,GAAG,CAAC,GAAgD;QAC3D,IAAA,qBAAM,EAAC,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,KAAK,CAAC,oDAAoD,CAAC,CAAC;QAC5F,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC;IACpB,CAAC;IAED,IAAW,GAAG;QACV,OAAO,IAAI,CAAC,IAAI,CAAC;IACrB,CAAC;IAED,IAAW,sBAAsB;QAC7B,OAAO,IAAI,CAAC,uBAAuB,CAAC;IACxC,CAAC;IAED,IAAW,aAAa;QACpB,OAAO,EAAE,CAAC;IACd,CAAC;IAIO,KAAK,CAAC,YAAY,CAAC,MAAc;QACrC,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAChE,OAAO,WAAW,aAAX,WAAW,cAAX,WAAW,GAAI,IAAI,CAAC,oBAAoB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrE,CAAC;IAIM,KAAK,CAAC,QAAQ,CAAC,MAAc;QAChC,OAAO,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;IACrC,CAAC;IAEM,KAAK,CAAC,eAAe,CAAC,OAAsB,EAAE,YAAqB;QACtE,IAAI,EAAU,CAAC;QACf,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE;YACzB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,EAAE,YAAY,CAAC,CAAC;YAC/D,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE;gBACpC,OAAO,IAAI,CAAC;aACf;YACD,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;SACvB;aAAM;YACH,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC;SACnB;QAED,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,YAAY,CAAC,CAAC;QAC3D,IAAI,CAAC,YAAY,EAAE;YACf,OAAO,IAAI,CAAC;SACf;QAED,IAAI,YAAY,CAAC,KAAK,EAAE;YACpB,MAAM,cAAc,GAAG,YAAY,CAAC,KAAK,CAAC,UAAU,CAAC;YACrD,IAAI,cAAc,EAAE;gBAChB,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;aAClD;SACJ;QAED,sGAAsG;QACtG,0GAA0G;QAC1G,MAAM,OAAO,GAAG,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAC3C,MAAM,YAAY,GAAG,YAAY,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAErD,OAAO,IAAI,CAAC,iCAAiC,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IACzE,CAAC;IAMM,KAAK,CAAC,eAAe,CAAC,MAA0B;QACnD,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;IAC3C,CAAC;IAES,WAAW,CAAC,EAAU,EAAE,IAAuB;QACrD,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;IACnC,CAAC;IAES,cAAc,CAAC,KAA+B;QACpD,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC;IAEO,KAAK,CAAC,QAAQ,CAAC,EAAU,EAAE,YAAqB;QACpD,IAAI,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACpC,IAAI,CAAC,IAAI,EAAE;YACP,IAAI,GAAG,MAAM,IAAI,CAAC,qBAAqB,CAAC,EAAE,EAAE,YAAY,CAAC,CAAC;SAC7D;QAED,OAAO,IAAI,aAAJ,IAAI,cAAJ,IAAI,GAAI,IAAI,CAAC;IACxB,CAAC;IAIO,iCAAiC,CACrC,mBAAsC,EACtC,wBAA2C;QAE3C,MAAM,mBAAmB,GAAsB;YAC3C,KAAK,oBACE,mBAAmB,CAAC,KAAK,CAC/B;YACD,KAAK,kCACE,mBAAmB,CAAC,KAAK;gBAC5B,sCAAsC;gBACtC,yDAAyD;gBACzD,WAAW,EAAE,wBAAwB,GACxC;SACJ,CAAC;QAEF,OAAO,mBAAmB,CAAC;IAC/B,CAAC;IAES,sBAAsB,CAAC,sBAAyC;QACtE,IAAI,CAAC,uBAAuB,GAAG,sBAAsB,CAAC,cAAc,CAAC;QACrE,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,sBAAsB,CAAC;QAE5D,0DAA0D;QAC1D,IAAI,EAAsB,CAAC;QAC3B,IAAI,YAAY,EAAE;YACd,EAAE,GAAG,YAAY,CAAC,EAAE,CAAC;YACrB,IAAA,qBAAM,EAAC,EAAE,KAAK,SAAS,EAAE,KAAK,CAAC,uCAAuC,CAAC,CAAC;YACxE,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,YAAY,CAAC,CAAC;SACtC;QAED,IAAI,KAAK,EAAE;YACP,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;SAC9B;QAED,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,OAAO,EAAE,CAAC;IACd,CAAC;CACJ;AA5JD,wEA4JC;AAED,2BAA2B","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 { IDocumentStorageService, ISummaryContext, LoaderCachingPolicy } from \"@fluidframework/driver-definitions\";\nimport * as api from \"@fluidframework/protocol-definitions\";\nimport { defaultCacheExpiryTimeoutMs } from \"./epochTracker\";\nimport { ISnapshotContents } from \"./odspPublicUtils\";\n\n/* eslint-disable max-len */\n\nclass BlobCache {\n // Save the timeout so we can cancel and reschedule it as needed\n private blobCacheTimeout: ReturnType<typeof setTimeout> | undefined;\n // If the defer flag is set when the timeout fires, we'll reschedule rather than clear immediately\n // This deferral approach is used (rather than clearing/resetting the timer) as current calling patterns trigger\n // too many calls to setTimeout/clearTimeout.\n private deferBlobCacheClear: boolean = false;\n\n private readonly _blobCache: Map<string, ArrayBuffer> = new Map();\n\n // Tracks all blob IDs evicted from cache\n private readonly blobsEvicted: Set<string> = new Set();\n\n // Initial time-out to purge data from cache\n // If this time out is very small, then we purge blobs from cache too soon and that results in a lot of\n // requests to storage, which brings down perf and may trip protection limits causing 429s\n private blobCacheTimeoutDuration = 2 * 60 * 1000;\n\n // SPO does not keep old snapshots around for long, so we are running chances of not\n // being able to rehydrate data store / DDS in the future if we purge anything (and with blob de-duping,\n // even if blob read by runtime, it could be read again in the future)\n // So for now, purging is disabled.\n private readonly purgeEnabled = false;\n\n public get value() {\n return this._blobCache;\n }\n\n public addBlobs(blobs: Map<string, ArrayBuffer>) {\n blobs.forEach((value, blobId) => {\n this._blobCache.set(blobId, value);\n });\n // Reset the timer on cache set\n this.scheduleClearBlobsCache();\n }\n\n /**\n * Schedule a timer for clearing the blob cache or defer the current one.\n */\n private scheduleClearBlobsCache() {\n if (this.blobCacheTimeout !== undefined) {\n // If we already have an outstanding timer, just signal that we should defer the clear\n this.deferBlobCacheClear = true;\n } else if (this.purgeEnabled) {\n // If we don't have an outstanding timer, set a timer\n // When the timer runs out, we'll decide whether to proceed with the cache clear or reset the timer\n const clearCacheOrDefer = () => {\n this.blobCacheTimeout = undefined;\n if (this.deferBlobCacheClear) {\n this.deferBlobCacheClear = false;\n this.scheduleClearBlobsCache();\n } else {\n // NOTE: Slightly better algorithm here would be to purge either only big blobs,\n // or sort them by size and purge enough big blobs to leave only 256Kb of small blobs in cache\n // Purging is optimizing memory footprint. But count controls potential number of storage requests\n // We want to optimize both - memory footprint and number of future requests to storage.\n // Note that Container can realize data store or DDS on-demand at any point in time, so we do not\n // control when blobs will be used.\n this._blobCache.forEach((_, blobId) => this.blobsEvicted.add(blobId));\n this._blobCache.clear();\n }\n };\n this.blobCacheTimeout = setTimeout(clearCacheOrDefer, this.blobCacheTimeoutDuration);\n // any future storage reads that get into the cache should be cleared from cache rather quickly -\n // there is not much value in keeping them longer\n this.blobCacheTimeoutDuration = 10 * 1000;\n }\n }\n\n public getBlob(blobId: string) {\n // Reset the timer on attempted cache read\n this.scheduleClearBlobsCache();\n const blobContent = this._blobCache.get(blobId);\n const evicted = this.blobsEvicted.has(blobId);\n return { blobContent, evicted };\n }\n\n public setBlob(blobId: string, blob: ArrayBuffer) {\n // This API is called as result of cache miss and reading blob from storage.\n // Runtime never reads same blob twice.\n // The only reason we may get read request for same blob is blob de-duping in summaries.\n // Note that the bigger the size, the less likely blobs are the same, so there is very little benefit of caching big blobs.\n // Images are the only exception - user may insert same image twice. But we currently do not de-dup them - only snapshot\n // blobs are de-duped.\n const size = blob.byteLength;\n if (size < 256 * 1024) {\n // Reset the timer on cache set\n this.scheduleClearBlobsCache();\n return this._blobCache.set(blobId, blob);\n } else {\n // we evicted it here by not caching.\n this.blobsEvicted.add(blobId);\n }\n }\n}\n\nexport abstract class OdspDocumentStorageServiceBase implements IDocumentStorageService {\n readonly policies = {\n // By default, ODSP tells the container not to prefetch/cache.\n caching: LoaderCachingPolicy.NoCaching,\n\n // ODSP storage works better if it has less number of blobs / edges\n // Runtime creating many small blobs results in sub-optimal perf.\n // 2K seems like the sweat spot:\n // The smaller the number, less blobs we aggregate. Most storages are very likely to have notion\n // of minimal \"cluster\" size, so having small blobs is wasteful\n // At the same time increasing the limit ensure that more blobs with user content are aggregated,\n // reducing possibility for de-duping of same blobs (i.e. .attributes rolled into aggregate blob\n // are not reused across data stores, or even within data store, resulting in duplication of content)\n // Note that duplication of content should not have significant impact for bytes over wire as\n // compression of http payload mostly takes care of it, but it does impact storage size and in-memory sizes.\n minBlobSize: 2048,\n maximumCacheDurationMs: defaultCacheExpiryTimeoutMs,\n };\n\n protected readonly commitCache: Map<string, api.ISnapshotTree> = new Map();\n\n private readonly attributesBlobHandles: Set<string> = new Set();\n\n private _ops: api.ISequencedDocumentMessage[] | undefined;\n\n private _snapshotSequenceNumber: number | undefined;\n\n protected readonly blobCache = new BlobCache();\n\n public set ops(ops: api.ISequencedDocumentMessage[] | undefined) {\n assert(this._ops === undefined, 0x0a5 /* \"Trying to set ops when they are already set!\" */);\n this._ops = ops;\n }\n\n public get ops(): api.ISequencedDocumentMessage[] | undefined {\n return this._ops;\n }\n\n public get snapshotSequenceNumber() {\n return this._snapshotSequenceNumber;\n }\n\n public get repositoryUrl(): string {\n return \"\";\n }\n\n public abstract createBlob(file: ArrayBufferLike): Promise<api.ICreateBlobResponse>;\n\n private async readBlobCore(blobId: string): Promise<ArrayBuffer> {\n const { blobContent, evicted } = this.blobCache.getBlob(blobId);\n return blobContent ?? this.fetchBlobFromStorage(blobId, evicted);\n }\n\n protected abstract fetchBlobFromStorage(blobId: string, evicted: boolean): Promise<ArrayBuffer>;\n\n public async readBlob(blobId: string): Promise<ArrayBufferLike> {\n return this.readBlobCore(blobId);\n }\n\n public async getSnapshotTree(version?: api.IVersion, scenarioName?: string): Promise<api.ISnapshotTree | null> {\n let id: string;\n if (!version || !version.id) {\n const versions = await this.getVersions(null, 1, scenarioName);\n if (!versions || versions.length === 0) {\n return null;\n }\n id = versions[0].id;\n } else {\n id = version.id;\n }\n\n const snapshotTree = await this.readTree(id, scenarioName);\n if (!snapshotTree) {\n return null;\n }\n\n if (snapshotTree.blobs) {\n const attributesBlob = snapshotTree.blobs.attributes;\n if (attributesBlob) {\n this.attributesBlobHandles.add(attributesBlob);\n }\n }\n\n // When we upload the container snapshot, we upload appTree in \".app\" and protocol tree in \".protocol\"\n // So when we request the snapshot we get \".app\" as tree and not as commit node as in the case just above.\n const appTree = snapshotTree.trees[\".app\"];\n const protocolTree = snapshotTree.trees[\".protocol\"];\n\n return this.combineProtocolAndAppSnapshotTree(appTree, protocolTree);\n }\n\n public abstract getVersions(blobid: string | null, count: number, scenarioName?: string): Promise<api.IVersion[]>;\n\n public abstract uploadSummaryWithContext(summary: api.ISummaryTree, context: ISummaryContext): Promise<string>;\n\n public async downloadSummary(commit: api.ISummaryHandle): Promise<api.ISummaryTree> {\n throw new Error(\"Not implemented yet\");\n }\n\n protected setRootTree(id: string, tree: api.ISnapshotTree) {\n this.commitCache.set(id, tree);\n }\n\n protected initBlobsCache(blobs: Map<string, ArrayBuffer>) {\n this.blobCache.addBlobs(blobs);\n }\n\n private async readTree(id: string, scenarioName?: string): Promise<api.ISnapshotTree | null> {\n let tree = this.commitCache.get(id);\n if (!tree) {\n tree = await this.fetchTreeFromSnapshot(id, scenarioName);\n }\n\n return tree ?? null;\n }\n\n protected abstract fetchTreeFromSnapshot(id: string, scenarioName?: string): Promise<api.ISnapshotTree | undefined>;\n\n private combineProtocolAndAppSnapshotTree(\n hierarchicalAppTree: api.ISnapshotTree,\n hierarchicalProtocolTree: api.ISnapshotTree,\n ) {\n const summarySnapshotTree: api.ISnapshotTree = {\n blobs: {\n ...hierarchicalAppTree.blobs,\n },\n trees: {\n ...hierarchicalAppTree.trees,\n // the app tree could have a .protocol\n // in that case we want to server protocol to override it\n \".protocol\": hierarchicalProtocolTree,\n },\n };\n\n return summarySnapshotTree;\n }\n\n protected initializeFromSnapshot(odspSnapshotCacheValue: ISnapshotContents): string | undefined {\n this._snapshotSequenceNumber = odspSnapshotCacheValue.sequenceNumber;\n const { snapshotTree, blobs, ops } = odspSnapshotCacheValue;\n\n // id should be undefined in case of just ops in snapshot.\n let id: string | undefined;\n if (snapshotTree) {\n id = snapshotTree.id;\n assert(id !== undefined, 0x221 /* \"Root tree should contain the id\" */);\n this.setRootTree(id, snapshotTree);\n }\n\n if (blobs) {\n this.initBlobsCache(blobs);\n }\n\n this.ops = ops;\n return id;\n }\n}\n\n/* eslint-enable max-len */\n"]}
@@ -92,7 +92,7 @@ class OdspDriverUrlResolver {
92
92
  fileName,
93
93
  summarizer: false,
94
94
  codeHint: {
95
- containerPackageName: packageName ? packageName : undefined,
95
+ containerPackageName: packageName !== null && packageName !== void 0 ? packageName : undefined,
96
96
  },
97
97
  fileVersion: undefined,
98
98
  shareLinkInfo,
@@ -1 +1 @@
1
- {"version":3,"file":"odspDriverUrlResolver.js","sourceRoot":"","sources":["../src/odspDriverUrlResolver.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 */\nimport { assert } from \"@fluidframework/common-utils\";\nimport { IRequest } from \"@fluidframework/core-interfaces\";\nimport {\n DriverErrorType,\n DriverHeader,\n IContainerPackageInfo,\n IResolvedUrl,\n IUrlResolver,\n} from \"@fluidframework/driver-definitions\";\nimport { IOdspResolvedUrl, ShareLinkTypes, ShareLinkInfoType } from \"@fluidframework/odsp-driver-definitions\";\nimport { NonRetryableError } from \"@fluidframework/driver-utils\";\nimport { createOdspUrl } from \"./createOdspUrl\";\nimport { getApiRoot } from \"./odspUrlHelper\";\nimport { getOdspResolvedUrl } from \"./odspUtils\";\nimport { getHashedDocumentId } from \"./odspPublicUtils\";\nimport { ClpCompliantAppHeader } from \"./contractsPublic\";\nimport { pkgVersion } from \"./packageVersion\";\n\nfunction getUrlBase(siteUrl: string, driveId: string, itemId: string, fileVersion?: string) {\n const siteOrigin = new URL(siteUrl).origin;\n const version = fileVersion ? `versions/${fileVersion}/` : \"\";\n return `${getApiRoot(siteOrigin)}/drives/${driveId}/items/${itemId}/${version}`;\n}\n\nfunction getSnapshotUrl(siteUrl: string, driveId: string, itemId: string, fileVersion?: string) {\n const urlBase = getUrlBase(siteUrl, driveId, itemId, fileVersion);\n return `${urlBase}opStream/snapshots`;\n}\n\nfunction getAttachmentPOSTUrl(siteUrl: string, driveId: string, itemId: string, fileVersion?: string) {\n const urlBase = getUrlBase(siteUrl, driveId, itemId, fileVersion);\n return `${urlBase}opStream/attachment`;\n}\n\nfunction getAttachmentGETUrl(siteUrl: string, driveId: string, itemId: string, fileVersion?: string) {\n const urlBase = getUrlBase(siteUrl, driveId, itemId, fileVersion);\n return `${urlBase}opStream/attachments`;\n}\n\nfunction getDeltaStorageUrl(siteUrl: string, driveId: string, itemId: string, fileVersion?: string) {\n const urlBase = getUrlBase(siteUrl, driveId, itemId, fileVersion);\n return `${urlBase}opStream`;\n}\n\n/**\n * Utility that enables us to handle paths provided with a beginning slash.\n * For example if a value of '/id1/id2' is provided, id1/id2 is returned.\n */\nfunction removeBeginningSlash(str: string): string {\n if (str.startsWith(\"/\")) {\n return str.substr(1);\n }\n\n return str;\n}\n\n/**\n * Resolver to resolve urls like the ones created by createOdspUrl which is driver inner\n * url format. Ex: `${siteUrl}?driveId=${driveId}&itemId=${itemId}&path=${path}`\n */\nexport class OdspDriverUrlResolver implements IUrlResolver {\n constructor() { }\n\n public async resolve(request: IRequest): Promise<IOdspResolvedUrl> {\n if (request.headers?.[DriverHeader.createNew]) {\n const [siteURL, queryString] = request.url.split(\"?\");\n\n const searchParams = new URLSearchParams(queryString);\n const fileName = request.headers[DriverHeader.createNew].fileName;\n const driveID = searchParams.get(\"driveId\");\n const filePath = searchParams.get(\"path\");\n const packageName = searchParams.get(\"containerPackageName\");\n const createLinkType = searchParams.get(\"createLinkType\");\n if (!(fileName && siteURL && driveID && filePath !== null && filePath !== undefined)) {\n throw new NonRetryableError(\n \"Proper new file params should be there!!\",\n DriverErrorType.genericError,\n { driverVersion: pkgVersion });\n }\n let shareLinkInfo: ShareLinkInfoType | undefined;\n if (createLinkType && createLinkType in ShareLinkTypes) {\n shareLinkInfo = {\n createLink: {\n type: ShareLinkTypes[createLinkType],\n },\n };\n }\n return {\n endpoints: {\n snapshotStorageUrl: \"\",\n attachmentGETStorageUrl: \"\",\n attachmentPOSTStorageUrl: \"\",\n deltaStorageUrl: \"\",\n },\n tokens: {},\n type: \"fluid\",\n odspResolvedUrl: true,\n id: \"odspCreateNew\",\n url: `fluid-odsp://${siteURL}?${queryString}&version=null`,\n siteUrl: siteURL,\n hashedDocumentId: \"\",\n driveId: driveID,\n itemId: \"\",\n fileName,\n summarizer: false,\n codeHint: {\n containerPackageName: packageName ? packageName : undefined,\n },\n fileVersion: undefined,\n shareLinkInfo,\n isClpCompliantApp: request.headers?.[ClpCompliantAppHeader.isClpCompliantApp],\n };\n }\n const { siteUrl, driveId, itemId, path, containerPackageName, fileVersion } = decodeOdspUrl(request.url);\n const hashedDocumentId = await getHashedDocumentId(driveId, itemId);\n assert(!hashedDocumentId.includes(\"/\"), 0x0a8 /* \"Docid should not contain slashes!!\" */);\n\n let documentUrl = `fluid-odsp://placeholder/placeholder/${hashedDocumentId}/${removeBeginningSlash(path)}`;\n\n if (request.url.length > 0) {\n // In case of any additional parameters add them back to the url\n const requestURL = new URL(request.url);\n const searchParams = requestURL.search;\n if (searchParams) {\n documentUrl += searchParams;\n }\n }\n\n const summarizer = !!request.headers?.[DriverHeader.summarizingClient];\n\n return {\n type: \"fluid\",\n odspResolvedUrl: true,\n endpoints: {\n snapshotStorageUrl: getSnapshotUrl(siteUrl, driveId, itemId, fileVersion),\n attachmentPOSTStorageUrl: getAttachmentPOSTUrl(siteUrl, driveId, itemId, fileVersion),\n attachmentGETStorageUrl: getAttachmentGETUrl(siteUrl, driveId, itemId, fileVersion),\n deltaStorageUrl: getDeltaStorageUrl(siteUrl, driveId, itemId, fileVersion),\n },\n id: hashedDocumentId,\n tokens: {},\n url: documentUrl,\n hashedDocumentId,\n siteUrl,\n driveId,\n itemId,\n fileName: \"\",\n summarizer,\n codeHint: {\n containerPackageName,\n },\n fileVersion,\n isClpCompliantApp: request.headers?.[ClpCompliantAppHeader.isClpCompliantApp],\n };\n }\n\n public async getAbsoluteUrl(\n resolvedUrl: IResolvedUrl,\n relativeUrl: string,\n packageInfoSource?: IContainerPackageInfo,\n ): Promise<string> {\n let dataStorePath = relativeUrl;\n if (dataStorePath.startsWith(\"/\")) {\n dataStorePath = dataStorePath.substr(1);\n }\n const odspResolvedUrl = getOdspResolvedUrl(resolvedUrl);\n // back-compat: GitHub #9653\n const isFluidPackage = (pkg: any) =>\n typeof pkg === \"object\"\n && typeof pkg?.name === \"string\"\n && typeof pkg?.fluid === \"object\";\n let containerPackageName;\n if (packageInfoSource && \"name\" in packageInfoSource) {\n containerPackageName = packageInfoSource.name;\n // packageInfoSource is cast to any as it is typed to IContainerPackageInfo instead of IFluidCodeDetails\n } else if (isFluidPackage((packageInfoSource as any)?.package)) {\n containerPackageName = (packageInfoSource as any)?.package.name;\n } else {\n containerPackageName = (packageInfoSource as any)?.package;\n }\n containerPackageName = containerPackageName ?? odspResolvedUrl.codeHint?.containerPackageName;\n\n return createOdspUrl({\n ... odspResolvedUrl,\n containerPackageName,\n dataStorePath,\n });\n }\n}\n\nfunction decodeOdspUrl(url: string): {\n siteUrl: string;\n driveId: string;\n itemId: string;\n path: string;\n containerPackageName?: string;\n fileVersion?: string;\n} {\n const [siteUrl, queryString] = url.split(\"?\");\n\n const searchParams = new URLSearchParams(queryString);\n\n const driveId = searchParams.get(\"driveId\");\n const itemId = searchParams.get(\"itemId\");\n const path = searchParams.get(\"path\");\n const containerPackageName = searchParams.get(\"containerPackageName\");\n const fileVersion = searchParams.get(\"fileVersion\");\n\n if (driveId === null) {\n throw new Error(\"ODSP URL did not contain a drive id\");\n }\n\n if (itemId === null) {\n throw new Error(\"ODSP Url did not contain an item id\");\n }\n\n if (path === null) {\n throw new Error(\"ODSP Url did not contain a path\");\n }\n\n return {\n siteUrl,\n driveId: decodeURIComponent(driveId),\n itemId: decodeURIComponent(itemId),\n path: decodeURIComponent(path),\n containerPackageName: containerPackageName ? decodeURIComponent(containerPackageName) : undefined,\n fileVersion: fileVersion ? decodeURIComponent(fileVersion) : undefined,\n };\n}\n"]}
1
+ {"version":3,"file":"odspDriverUrlResolver.js","sourceRoot":"","sources":["../src/odspDriverUrlResolver.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 */\nimport { assert } from \"@fluidframework/common-utils\";\nimport { IRequest } from \"@fluidframework/core-interfaces\";\nimport {\n DriverErrorType,\n DriverHeader,\n IContainerPackageInfo,\n IResolvedUrl,\n IUrlResolver,\n} from \"@fluidframework/driver-definitions\";\nimport { IOdspResolvedUrl, ShareLinkTypes, ShareLinkInfoType } from \"@fluidframework/odsp-driver-definitions\";\nimport { NonRetryableError } from \"@fluidframework/driver-utils\";\nimport { createOdspUrl } from \"./createOdspUrl\";\nimport { getApiRoot } from \"./odspUrlHelper\";\nimport { getOdspResolvedUrl } from \"./odspUtils\";\nimport { getHashedDocumentId } from \"./odspPublicUtils\";\nimport { ClpCompliantAppHeader } from \"./contractsPublic\";\nimport { pkgVersion } from \"./packageVersion\";\n\nfunction getUrlBase(siteUrl: string, driveId: string, itemId: string, fileVersion?: string) {\n const siteOrigin = new URL(siteUrl).origin;\n const version = fileVersion ? `versions/${fileVersion}/` : \"\";\n return `${getApiRoot(siteOrigin)}/drives/${driveId}/items/${itemId}/${version}`;\n}\n\nfunction getSnapshotUrl(siteUrl: string, driveId: string, itemId: string, fileVersion?: string) {\n const urlBase = getUrlBase(siteUrl, driveId, itemId, fileVersion);\n return `${urlBase}opStream/snapshots`;\n}\n\nfunction getAttachmentPOSTUrl(siteUrl: string, driveId: string, itemId: string, fileVersion?: string) {\n const urlBase = getUrlBase(siteUrl, driveId, itemId, fileVersion);\n return `${urlBase}opStream/attachment`;\n}\n\nfunction getAttachmentGETUrl(siteUrl: string, driveId: string, itemId: string, fileVersion?: string) {\n const urlBase = getUrlBase(siteUrl, driveId, itemId, fileVersion);\n return `${urlBase}opStream/attachments`;\n}\n\nfunction getDeltaStorageUrl(siteUrl: string, driveId: string, itemId: string, fileVersion?: string) {\n const urlBase = getUrlBase(siteUrl, driveId, itemId, fileVersion);\n return `${urlBase}opStream`;\n}\n\n/**\n * Utility that enables us to handle paths provided with a beginning slash.\n * For example if a value of '/id1/id2' is provided, id1/id2 is returned.\n */\nfunction removeBeginningSlash(str: string): string {\n if (str.startsWith(\"/\")) {\n return str.substr(1);\n }\n\n return str;\n}\n\n/**\n * Resolver to resolve urls like the ones created by createOdspUrl which is driver inner\n * url format. Ex: `${siteUrl}?driveId=${driveId}&itemId=${itemId}&path=${path}`\n */\nexport class OdspDriverUrlResolver implements IUrlResolver {\n constructor() { }\n\n public async resolve(request: IRequest): Promise<IOdspResolvedUrl> {\n if (request.headers?.[DriverHeader.createNew]) {\n const [siteURL, queryString] = request.url.split(\"?\");\n\n const searchParams = new URLSearchParams(queryString);\n const fileName = request.headers[DriverHeader.createNew].fileName;\n const driveID = searchParams.get(\"driveId\");\n const filePath = searchParams.get(\"path\");\n const packageName = searchParams.get(\"containerPackageName\");\n const createLinkType = searchParams.get(\"createLinkType\");\n if (!(fileName && siteURL && driveID && filePath !== null && filePath !== undefined)) {\n throw new NonRetryableError(\n \"Proper new file params should be there!!\",\n DriverErrorType.genericError,\n { driverVersion: pkgVersion });\n }\n let shareLinkInfo: ShareLinkInfoType | undefined;\n if (createLinkType && createLinkType in ShareLinkTypes) {\n shareLinkInfo = {\n createLink: {\n type: ShareLinkTypes[createLinkType],\n },\n };\n }\n return {\n endpoints: {\n snapshotStorageUrl: \"\",\n attachmentGETStorageUrl: \"\",\n attachmentPOSTStorageUrl: \"\",\n deltaStorageUrl: \"\",\n },\n tokens: {},\n type: \"fluid\",\n odspResolvedUrl: true,\n id: \"odspCreateNew\",\n url: `fluid-odsp://${siteURL}?${queryString}&version=null`,\n siteUrl: siteURL,\n hashedDocumentId: \"\",\n driveId: driveID,\n itemId: \"\",\n fileName,\n summarizer: false,\n codeHint: {\n containerPackageName: packageName ?? undefined,\n },\n fileVersion: undefined,\n shareLinkInfo,\n isClpCompliantApp: request.headers?.[ClpCompliantAppHeader.isClpCompliantApp],\n };\n }\n const { siteUrl, driveId, itemId, path, containerPackageName, fileVersion } = decodeOdspUrl(request.url);\n const hashedDocumentId = await getHashedDocumentId(driveId, itemId);\n assert(!hashedDocumentId.includes(\"/\"), 0x0a8 /* \"Docid should not contain slashes!!\" */);\n\n let documentUrl = `fluid-odsp://placeholder/placeholder/${hashedDocumentId}/${removeBeginningSlash(path)}`;\n\n if (request.url.length > 0) {\n // In case of any additional parameters add them back to the url\n const requestURL = new URL(request.url);\n const searchParams = requestURL.search;\n if (searchParams) {\n documentUrl += searchParams;\n }\n }\n\n const summarizer = !!request.headers?.[DriverHeader.summarizingClient];\n\n return {\n type: \"fluid\",\n odspResolvedUrl: true,\n endpoints: {\n snapshotStorageUrl: getSnapshotUrl(siteUrl, driveId, itemId, fileVersion),\n attachmentPOSTStorageUrl: getAttachmentPOSTUrl(siteUrl, driveId, itemId, fileVersion),\n attachmentGETStorageUrl: getAttachmentGETUrl(siteUrl, driveId, itemId, fileVersion),\n deltaStorageUrl: getDeltaStorageUrl(siteUrl, driveId, itemId, fileVersion),\n },\n id: hashedDocumentId,\n tokens: {},\n url: documentUrl,\n hashedDocumentId,\n siteUrl,\n driveId,\n itemId,\n fileName: \"\",\n summarizer,\n codeHint: {\n containerPackageName,\n },\n fileVersion,\n isClpCompliantApp: request.headers?.[ClpCompliantAppHeader.isClpCompliantApp],\n };\n }\n\n public async getAbsoluteUrl(\n resolvedUrl: IResolvedUrl,\n relativeUrl: string,\n packageInfoSource?: IContainerPackageInfo,\n ): Promise<string> {\n let dataStorePath = relativeUrl;\n if (dataStorePath.startsWith(\"/\")) {\n dataStorePath = dataStorePath.substr(1);\n }\n const odspResolvedUrl = getOdspResolvedUrl(resolvedUrl);\n // back-compat: GitHub #9653\n const isFluidPackage = (pkg: any) =>\n typeof pkg === \"object\"\n && typeof pkg?.name === \"string\"\n && typeof pkg?.fluid === \"object\";\n let containerPackageName;\n if (packageInfoSource && \"name\" in packageInfoSource) {\n containerPackageName = packageInfoSource.name;\n // packageInfoSource is cast to any as it is typed to IContainerPackageInfo instead of IFluidCodeDetails\n } else if (isFluidPackage((packageInfoSource as any)?.package)) {\n containerPackageName = (packageInfoSource as any)?.package.name;\n } else {\n containerPackageName = (packageInfoSource as any)?.package;\n }\n containerPackageName = containerPackageName ?? odspResolvedUrl.codeHint?.containerPackageName;\n\n return createOdspUrl({\n ... odspResolvedUrl,\n containerPackageName,\n dataStorePath,\n });\n }\n}\n\nfunction decodeOdspUrl(url: string): {\n siteUrl: string;\n driveId: string;\n itemId: string;\n path: string;\n containerPackageName?: string;\n fileVersion?: string;\n} {\n const [siteUrl, queryString] = url.split(\"?\");\n\n const searchParams = new URLSearchParams(queryString);\n\n const driveId = searchParams.get(\"driveId\");\n const itemId = searchParams.get(\"itemId\");\n const path = searchParams.get(\"path\");\n const containerPackageName = searchParams.get(\"containerPackageName\");\n const fileVersion = searchParams.get(\"fileVersion\");\n\n if (driveId === null) {\n throw new Error(\"ODSP URL did not contain a drive id\");\n }\n\n if (itemId === null) {\n throw new Error(\"ODSP Url did not contain an item id\");\n }\n\n if (path === null) {\n throw new Error(\"ODSP Url did not contain a path\");\n }\n\n return {\n siteUrl,\n driveId: decodeURIComponent(driveId),\n itemId: decodeURIComponent(itemId),\n path: decodeURIComponent(path),\n containerPackageName: containerPackageName ? decodeURIComponent(containerPackageName) : undefined,\n fileVersion: fileVersion ? decodeURIComponent(fileVersion) : undefined,\n };\n}\n"]}
@@ -23,6 +23,7 @@ export interface ShareLinkFetcherProps {
23
23
  */
24
24
  export declare class OdspDriverUrlResolverForShareLink implements IUrlResolver {
25
25
  private readonly appName?;
26
+ private readonly getContext?;
26
27
  private readonly logger;
27
28
  private readonly sharingLinkCache;
28
29
  private readonly shareLinkFetcherProps;
@@ -35,8 +36,10 @@ export declare class OdspDriverUrlResolverForShareLink implements IUrlResolver {
35
36
  * @param appName - application name hint that is encoded with url produced by getAbsoluteUrl() method.
36
37
  * This hint is used by link handling logic which determines which app to redirect to when user
37
38
  * navigates directly to the link.
39
+ * @param getContext - callback function which is used to get context for given resolved url. If context
40
+ * is returned then it will be embedded into url returned by getAbsoluteUrl() method.
38
41
  */
39
- constructor(shareLinkFetcherProps?: ShareLinkFetcherProps | undefined, logger?: ITelemetryBaseLogger, appName?: string | undefined);
42
+ constructor(shareLinkFetcherProps?: ShareLinkFetcherProps | undefined, logger?: ITelemetryBaseLogger, appName?: string | undefined, getContext?: ((resolvedUrl: IOdspResolvedUrl, dataStorePath: string) => Promise<string | undefined>) | undefined);
40
43
  /**
41
44
  * Takes an already generated data store url (from requestUrl) and appends a path to the
42
45
  * existing data store information.
@@ -53,7 +56,9 @@ export declare class OdspDriverUrlResolverForShareLink implements IUrlResolver {
53
56
  * Requests a driver + data store storage URL. Note that this method requires share link to be fetched
54
57
  * and it will throw in case share link fetcher props were not specified when instance was created.
55
58
  * @param resolvedUrl - The driver resolved URL
56
- * @param request - The relative data store path URL. For requesting a driver URL, this value should always be '/'
59
+ * @param dataStorePath - The relative data store path URL.
60
+ * For requesting a driver URL, this value should always be '/'
61
+ * @param packageInfoSource - optional, represents container package information to be included in url.
57
62
  */
58
63
  getAbsoluteUrl(resolvedUrl: IResolvedUrl, dataStorePath: string, packageInfoSource?: IContainerPackageInfo): Promise<string>;
59
64
  /**
@@ -62,6 +67,7 @@ export declare class OdspDriverUrlResolverForShareLink implements IUrlResolver {
62
67
  static createDocumentUrl(baseUrl: string, driverInfo: OdspFluidDataStoreLocator): string;
63
68
  /**
64
69
  * Crafts a supported data store nav param
70
+ * @deprecated encodeOdspFluidDataStoreLocator should be used instead
65
71
  */
66
72
  static createNavParam(locator: OdspFluidDataStoreLocator): string;
67
73
  }
@@ -1 +1 @@
1
- {"version":3,"file":"odspDriverUrlResolverForShareLink.d.ts","sourceRoot":"","sources":["../src/odspDriverUrlResolverForShareLink.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAC3D,OAAO,EACH,qBAAqB,EACrB,YAAY,EACZ,YAAY,EACf,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,oBAAoB,EAAoB,MAAM,oCAAoC,CAAC;AAC5F,OAAO,EACH,gBAAgB,EAChB,YAAY,EACZ,6BAA6B,EAC7B,YAAY,EACf,MAAM,yCAAyC,CAAC;AAOjD,OAAO,EAAE,yBAAyB,EAAqB,MAAM,mBAAmB,CAAC;AAMjF;;GAEG;AACH,MAAM,WAAW,qBAAqB;IAClC;;OAEG;IACH,YAAY,EAAE,YAAY,CAAC,6BAA6B,CAAC,CAAC;IAC1D;;OAEG;IACH,YAAY,EAAE,YAAY,CAAC;CAC9B;AAED;;;;GAIG;AACH,qBAAa,iCAAkC,YAAW,YAAY;IAkB9D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;IAjB7B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmB;IAC1C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAsC;IACvE,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAoC;IAE1E;;;;;;;;;OASG;gBAEC,qBAAqB,CAAC,EAAE,qBAAqB,GAAG,SAAS,EACzD,MAAM,CAAC,EAAE,oBAAoB,EACZ,OAAO,CAAC,oBAAQ;IAWrC;;;OAGG;IACI,mBAAmB,CAAC,UAAU,EAAE,GAAG,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAyBrF,OAAO,CAAC,MAAM;IAId;;OAEG;IACU,OAAO,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA+BlE,OAAO,CAAC,cAAc;YAQR,mBAAmB;IA8BjC;;;;;OAKG;IACU,cAAc,CACvB,WAAW,EAAE,YAAY,EACzB,aAAa,EAAE,MAAM,EACrB,iBAAiB,CAAC,EAAE,qBAAqB,GAC1C,OAAO,CAAC,MAAM,CAAC;IAiClB;;OAEG;WACW,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,yBAAyB;IAQtF;;OAEG;WACW,cAAc,CAAC,OAAO,EAAE,yBAAyB;CAGlE"}
1
+ {"version":3,"file":"odspDriverUrlResolverForShareLink.d.ts","sourceRoot":"","sources":["../src/odspDriverUrlResolverForShareLink.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAC3D,OAAO,EACH,qBAAqB,EACrB,YAAY,EACZ,YAAY,EACf,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,oBAAoB,EAAoB,MAAM,oCAAoC,CAAC;AAC5F,OAAO,EACH,gBAAgB,EAChB,YAAY,EACZ,6BAA6B,EAC7B,YAAY,EACf,MAAM,yCAAyC,CAAC;AAOjD,OAAO,EAAE,yBAAyB,EAAqB,MAAM,mBAAmB,CAAC;AAMjF;;GAEG;AACH,MAAM,WAAW,qBAAqB;IAClC;;OAEG;IACH,YAAY,EAAE,YAAY,CAAC,6BAA6B,CAAC,CAAC;IAC1D;;OAEG;IACH,YAAY,EAAE,YAAY,CAAC;CAC9B;AAED;;;;GAIG;AACH,qBAAa,iCAAkC,YAAW,YAAY;IAoB9D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;IACzB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC;IApBhC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmB;IAC1C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAsC;IACvE,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAoC;IAE1E;;;;;;;;;;;OAWG;gBAEC,qBAAqB,CAAC,EAAE,qBAAqB,GAAG,SAAS,EACzD,MAAM,CAAC,EAAE,oBAAoB,EACZ,OAAO,CAAC,oBAAQ,EAChB,UAAU,CAAC,iBACV,gBAAgB,iBAAiB,MAAM,KAAK,QAAQ,MAAM,GAAG,SAAS,CAAC,aAAA;IAW7F;;;OAGG;IACI,mBAAmB,CAAC,UAAU,EAAE,GAAG,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAyBrF,OAAO,CAAC,MAAM;IAId;;OAEG;IACU,OAAO,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA+BlE,OAAO,CAAC,cAAc;YAQR,mBAAmB;IA8BjC;;;;;;;OAOG;IACU,cAAc,CACvB,WAAW,EAAE,YAAY,EACzB,aAAa,EAAE,MAAM,EACrB,iBAAiB,CAAC,EAAE,qBAAqB,GAC1C,OAAO,CAAC,MAAM,CAAC;IAsClB;;OAEG;WACW,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,yBAAyB;IAQtF;;;OAGG;WACW,cAAc,CAAC,OAAO,EAAE,yBAAyB;CAGlE"}
@@ -27,9 +27,12 @@ class OdspDriverUrlResolverForShareLink {
27
27
  * @param appName - application name hint that is encoded with url produced by getAbsoluteUrl() method.
28
28
  * This hint is used by link handling logic which determines which app to redirect to when user
29
29
  * navigates directly to the link.
30
+ * @param getContext - callback function which is used to get context for given resolved url. If context
31
+ * is returned then it will be embedded into url returned by getAbsoluteUrl() method.
30
32
  */
31
- constructor(shareLinkFetcherProps, logger, appName) {
33
+ constructor(shareLinkFetcherProps, logger, appName, getContext) {
32
34
  this.appName = appName;
35
+ this.getContext = getContext;
33
36
  this.sharingLinkCache = new common_utils_1.PromiseCache();
34
37
  this.logger = (0, odspUtils_1.createOdspLogger)(logger);
35
38
  if (shareLinkFetcherProps) {
@@ -127,10 +130,12 @@ class OdspDriverUrlResolverForShareLink {
127
130
  * Requests a driver + data store storage URL. Note that this method requires share link to be fetched
128
131
  * and it will throw in case share link fetcher props were not specified when instance was created.
129
132
  * @param resolvedUrl - The driver resolved URL
130
- * @param request - The relative data store path URL. For requesting a driver URL, this value should always be '/'
133
+ * @param dataStorePath - The relative data store path URL.
134
+ * For requesting a driver URL, this value should always be '/'
135
+ * @param packageInfoSource - optional, represents container package information to be included in url.
131
136
  */
132
137
  async getAbsoluteUrl(resolvedUrl, dataStorePath, packageInfoSource) {
133
- var _a, _b, _c, _d;
138
+ var _a, _b, _c, _d, _e;
134
139
  const odspResolvedUrl = (0, odspUtils_1.getOdspResolvedUrl)(resolvedUrl);
135
140
  const shareLink = await this.getShareLinkPromise(odspResolvedUrl);
136
141
  const shareLinkUrl = new URL(shareLink);
@@ -150,6 +155,7 @@ class OdspDriverUrlResolverForShareLink {
150
155
  containerPackageName = (_c = packageInfoSource) === null || _c === void 0 ? void 0 : _c.package;
151
156
  }
152
157
  containerPackageName = containerPackageName !== null && containerPackageName !== void 0 ? containerPackageName : (_d = odspResolvedUrl.codeHint) === null || _d === void 0 ? void 0 : _d.containerPackageName;
158
+ const context = await ((_e = this.getContext) === null || _e === void 0 ? void 0 : _e.call(this, odspResolvedUrl, dataStorePath));
153
159
  (0, odspFluidFileLink_1.storeLocatorInOdspUrl)(shareLinkUrl, {
154
160
  siteUrl: odspResolvedUrl.siteUrl,
155
161
  driveId: odspResolvedUrl.driveId,
@@ -158,6 +164,7 @@ class OdspDriverUrlResolverForShareLink {
158
164
  appName: this.appName,
159
165
  containerPackageName,
160
166
  fileVersion: odspResolvedUrl.fileVersion,
167
+ context,
161
168
  });
162
169
  return shareLinkUrl.href;
163
170
  }
@@ -171,6 +178,7 @@ class OdspDriverUrlResolverForShareLink {
171
178
  }
172
179
  /**
173
180
  * Crafts a supported data store nav param
181
+ * @deprecated encodeOdspFluidDataStoreLocator should be used instead
174
182
  */
175
183
  static createNavParam(locator) {
176
184
  return (0, odspFluidFileLink_1.encodeOdspFluidDataStoreLocator)(locator);
@@ -1 +1 @@
1
- {"version":3,"file":"odspDriverUrlResolverForShareLink.js","sourceRoot":"","sources":["../src/odspDriverUrlResolverForShareLink.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 */\nimport { PromiseCache } from \"@fluidframework/common-utils\";\nimport { IRequest } from \"@fluidframework/core-interfaces\";\nimport {\n IContainerPackageInfo,\n IResolvedUrl,\n IUrlResolver,\n} from \"@fluidframework/driver-definitions\";\nimport { ITelemetryBaseLogger, ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport {\n IOdspResolvedUrl,\n IdentityType,\n OdspResourceTokenFetchOptions,\n TokenFetcher,\n} from \"@fluidframework/odsp-driver-definitions\";\nimport {\n getLocatorFromOdspUrl,\n storeLocatorInOdspUrl,\n encodeOdspFluidDataStoreLocator,\n locatorQueryParamName,\n} from \"./odspFluidFileLink\";\nimport { OdspFluidDataStoreLocator, SharingLinkHeader } from \"./contractsPublic\";\nimport { createOdspUrl } from \"./createOdspUrl\";\nimport { OdspDriverUrlResolver } from \"./odspDriverUrlResolver\";\nimport { getOdspResolvedUrl, createOdspLogger } from \"./odspUtils\";\nimport { getFileLink } from \"./getFileLink\";\n\n/**\n * Properties passed to the code responsible for fetching share link for a file.\n */\nexport interface ShareLinkFetcherProps {\n /**\n * Callback method that is used to fetch access token necessary to call API that produces share link\n */\n tokenFetcher: TokenFetcher<OdspResourceTokenFetchOptions>;\n /**\n * Identity type determining the shape of share link as it differs for Enterprise and Consumer users.\n */\n identityType: IdentityType;\n}\n\n/**\n * Resolver to resolve urls like the ones created by createOdspUrl which is driver inner\n * url format and the ones which have things like driveId, siteId, itemId etc encoded in nav param.\n * This resolver also handles share links and try to generate one for the use by the app.\n */\nexport class OdspDriverUrlResolverForShareLink implements IUrlResolver {\n private readonly logger: ITelemetryLogger;\n private readonly sharingLinkCache = new PromiseCache<string, string>();\n private readonly shareLinkFetcherProps: ShareLinkFetcherProps | undefined;\n\n /**\n * Creates url resolver instance\n * @param shareLinkFetcherProps - properties used when fetching share link.\n * Can be set as 'undefined' for cases where share link is not needed. Currently, only\n * getAbsoluteUrl() method requires share link.\n * @param logger - logger object that is used as telemetry sink\n * @param appName - application name hint that is encoded with url produced by getAbsoluteUrl() method.\n * This hint is used by link handling logic which determines which app to redirect to when user\n * navigates directly to the link.\n */\n public constructor(\n shareLinkFetcherProps?: ShareLinkFetcherProps | undefined,\n logger?: ITelemetryBaseLogger,\n private readonly appName?: string,\n ) {\n this.logger = createOdspLogger(logger);\n if (shareLinkFetcherProps) {\n this.shareLinkFetcherProps = {\n ...shareLinkFetcherProps,\n tokenFetcher: shareLinkFetcherProps.tokenFetcher,\n };\n }\n }\n\n /**\n * Takes an already generated data store url (from requestUrl) and appends a path to the\n * existing data store information.\n */\n public appendDataStorePath(requestUrl: URL, pathToAppend: string): string | undefined {\n const fluidInfo = getLocatorFromOdspUrl(requestUrl);\n\n if (!fluidInfo) {\n return undefined;\n }\n\n const parsingUrl = new URL(fluidInfo.dataStorePath, `${requestUrl.protocol}//${requestUrl.hostname}`);\n // Determine if the caller is passing a query parameter or path since processing will be different.\n if (pathToAppend.startsWith(\"/?\") || pathToAppend.startsWith(\"?\")) {\n const queryParams = new URLSearchParams(pathToAppend);\n queryParams.forEach((value: string, key: string) => {\n parsingUrl.searchParams.append(key, value);\n });\n fluidInfo.dataStorePath = `${parsingUrl.pathname}${parsingUrl.search}`;\n } else {\n fluidInfo.dataStorePath = `${parsingUrl.pathname}${\n parsingUrl.pathname.endsWith(\"/\") || pathToAppend.startsWith(\"/\") ? \"\" : \"/\"\n }${pathToAppend}/${parsingUrl.search}`;\n }\n storeLocatorInOdspUrl(requestUrl, fluidInfo);\n\n return requestUrl.href;\n }\n\n private getKey(resolvedUrl: IOdspResolvedUrl): string {\n return `${resolvedUrl.siteUrl},${resolvedUrl.driveId},${resolvedUrl.itemId}`;\n }\n\n /**\n * Resolves request URL into driver details\n */\n public async resolve(request: IRequest): Promise<IOdspResolvedUrl> {\n const requestToBeResolved = { headers: request.headers, url: request.url };\n const isSharingLinkToRedeem = requestToBeResolved.headers?.[SharingLinkHeader.isSharingLinkToRedeem];\n try {\n const url = new URL(request.url);\n\n const odspFluidInfo = getLocatorFromOdspUrl(url);\n if (odspFluidInfo) {\n requestToBeResolved.url = createOdspUrl(odspFluidInfo);\n }\n } catch {\n // If the locator throws some error, then try to resolve the request as it is.\n }\n\n const odspResolvedUrl = await new OdspDriverUrlResolver().resolve(requestToBeResolved);\n\n if (isSharingLinkToRedeem) {\n // We need to remove the nav param if set by host when setting the sharelink as otherwise the shareLinkId\n // when redeeming the share link during the redeem fallback for trees latest call becomes greater than\n // the eligible length.\n odspResolvedUrl.shareLinkInfo = Object.assign(odspResolvedUrl.shareLinkInfo || {},\n { sharingLinkToRedeem: this.removeNavParam(request.url) });\n }\n if (odspResolvedUrl.itemId) {\n // Kick start the sharing link request if we don't have it already as a performance optimization.\n // For detached create new, we don't have an item id yet and therefore cannot generate a share link\n this.getShareLinkPromise(odspResolvedUrl).catch(() => {});\n }\n return odspResolvedUrl;\n }\n\n private removeNavParam(link: string): string {\n const url = new URL(link);\n const params = new URLSearchParams(url.search);\n params.delete(locatorQueryParamName);\n url.search = params.toString();\n return url.href;\n }\n\n private async getShareLinkPromise(resolvedUrl: IOdspResolvedUrl): Promise<string> {\n if (this.shareLinkFetcherProps === undefined) {\n throw new Error(\"Failed to get share link because share link fetcher props are missing\");\n }\n\n if (!(resolvedUrl.siteUrl && resolvedUrl.driveId && resolvedUrl.itemId)) {\n throw new Error(\"Failed to get share link because necessary information is missing \" +\n \"(e.g. siteUrl, driveId or itemId)\");\n }\n\n const key = this.getKey(resolvedUrl);\n const cachedLinkPromise = this.sharingLinkCache.get(key);\n if (cachedLinkPromise) {\n return cachedLinkPromise;\n }\n const newLinkPromise = getFileLink(\n this.shareLinkFetcherProps.tokenFetcher,\n resolvedUrl,\n this.shareLinkFetcherProps.identityType,\n this.logger,\n ).catch((error) => {\n // This should imply that error is a non-retriable error.\n this.logger.sendErrorEvent({ eventName: \"FluidFileUrlError\" }, error);\n this.sharingLinkCache.remove(key);\n throw error;\n });\n this.sharingLinkCache.add(key, async () => newLinkPromise);\n return newLinkPromise;\n }\n\n /**\n * Requests a driver + data store storage URL. Note that this method requires share link to be fetched\n * and it will throw in case share link fetcher props were not specified when instance was created.\n * @param resolvedUrl - The driver resolved URL\n * @param request - The relative data store path URL. For requesting a driver URL, this value should always be '/'\n */\n public async getAbsoluteUrl(\n resolvedUrl: IResolvedUrl,\n dataStorePath: string,\n packageInfoSource?: IContainerPackageInfo,\n ): Promise<string> {\n const odspResolvedUrl = getOdspResolvedUrl(resolvedUrl);\n const shareLink = await this.getShareLinkPromise(odspResolvedUrl);\n const shareLinkUrl = new URL(shareLink);\n // back-compat: GitHub #9653\n const isFluidPackage = (pkg: any) =>\n typeof pkg === \"object\"\n && typeof pkg?.name === \"string\"\n && typeof pkg?.fluid === \"object\";\n let containerPackageName;\n if (packageInfoSource && \"name\" in packageInfoSource) {\n containerPackageName = packageInfoSource.name;\n // packageInfoSource is cast to any as it is typed to IContainerPackageInfo instead of IFluidCodeDetails\n } else if (isFluidPackage((packageInfoSource as any)?.package)) {\n containerPackageName = (packageInfoSource as any)?.package.name;\n } else {\n containerPackageName = (packageInfoSource as any)?.package;\n }\n containerPackageName = containerPackageName ?? odspResolvedUrl.codeHint?.containerPackageName;\n\n storeLocatorInOdspUrl(shareLinkUrl, {\n siteUrl: odspResolvedUrl.siteUrl,\n driveId: odspResolvedUrl.driveId,\n itemId: odspResolvedUrl.itemId,\n dataStorePath,\n appName: this.appName,\n containerPackageName,\n fileVersion: odspResolvedUrl.fileVersion,\n });\n\n return shareLinkUrl.href;\n }\n\n /**\n * Crafts a supported document/driver URL\n */\n public static createDocumentUrl(baseUrl: string, driverInfo: OdspFluidDataStoreLocator) {\n const url = new URL(baseUrl);\n\n storeLocatorInOdspUrl(url, driverInfo);\n\n return url.href;\n }\n\n /**\n * Crafts a supported data store nav param\n */\n public static createNavParam(locator: OdspFluidDataStoreLocator) {\n return encodeOdspFluidDataStoreLocator(locator);\n }\n}\n"]}
1
+ {"version":3,"file":"odspDriverUrlResolverForShareLink.js","sourceRoot":"","sources":["../src/odspDriverUrlResolverForShareLink.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 */\nimport { PromiseCache } from \"@fluidframework/common-utils\";\nimport { IRequest } from \"@fluidframework/core-interfaces\";\nimport {\n IContainerPackageInfo,\n IResolvedUrl,\n IUrlResolver,\n} from \"@fluidframework/driver-definitions\";\nimport { ITelemetryBaseLogger, ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport {\n IOdspResolvedUrl,\n IdentityType,\n OdspResourceTokenFetchOptions,\n TokenFetcher,\n} from \"@fluidframework/odsp-driver-definitions\";\nimport {\n getLocatorFromOdspUrl,\n storeLocatorInOdspUrl,\n encodeOdspFluidDataStoreLocator,\n locatorQueryParamName,\n} from \"./odspFluidFileLink\";\nimport { OdspFluidDataStoreLocator, SharingLinkHeader } from \"./contractsPublic\";\nimport { createOdspUrl } from \"./createOdspUrl\";\nimport { OdspDriverUrlResolver } from \"./odspDriverUrlResolver\";\nimport { getOdspResolvedUrl, createOdspLogger } from \"./odspUtils\";\nimport { getFileLink } from \"./getFileLink\";\n\n/**\n * Properties passed to the code responsible for fetching share link for a file.\n */\nexport interface ShareLinkFetcherProps {\n /**\n * Callback method that is used to fetch access token necessary to call API that produces share link\n */\n tokenFetcher: TokenFetcher<OdspResourceTokenFetchOptions>;\n /**\n * Identity type determining the shape of share link as it differs for Enterprise and Consumer users.\n */\n identityType: IdentityType;\n}\n\n/**\n * Resolver to resolve urls like the ones created by createOdspUrl which is driver inner\n * url format and the ones which have things like driveId, siteId, itemId etc encoded in nav param.\n * This resolver also handles share links and try to generate one for the use by the app.\n */\nexport class OdspDriverUrlResolverForShareLink implements IUrlResolver {\n private readonly logger: ITelemetryLogger;\n private readonly sharingLinkCache = new PromiseCache<string, string>();\n private readonly shareLinkFetcherProps: ShareLinkFetcherProps | undefined;\n\n /**\n * Creates url resolver instance\n * @param shareLinkFetcherProps - properties used when fetching share link.\n * Can be set as 'undefined' for cases where share link is not needed. Currently, only\n * getAbsoluteUrl() method requires share link.\n * @param logger - logger object that is used as telemetry sink\n * @param appName - application name hint that is encoded with url produced by getAbsoluteUrl() method.\n * This hint is used by link handling logic which determines which app to redirect to when user\n * navigates directly to the link.\n * @param getContext - callback function which is used to get context for given resolved url. If context\n * is returned then it will be embedded into url returned by getAbsoluteUrl() method.\n */\n public constructor(\n shareLinkFetcherProps?: ShareLinkFetcherProps | undefined,\n logger?: ITelemetryBaseLogger,\n private readonly appName?: string,\n private readonly getContext?:\n (resolvedUrl: IOdspResolvedUrl, dataStorePath: string) => Promise<string | undefined>,\n ) {\n this.logger = createOdspLogger(logger);\n if (shareLinkFetcherProps) {\n this.shareLinkFetcherProps = {\n ...shareLinkFetcherProps,\n tokenFetcher: shareLinkFetcherProps.tokenFetcher,\n };\n }\n }\n\n /**\n * Takes an already generated data store url (from requestUrl) and appends a path to the\n * existing data store information.\n */\n public appendDataStorePath(requestUrl: URL, pathToAppend: string): string | undefined {\n const fluidInfo = getLocatorFromOdspUrl(requestUrl);\n\n if (!fluidInfo) {\n return undefined;\n }\n\n const parsingUrl = new URL(fluidInfo.dataStorePath, `${requestUrl.protocol}//${requestUrl.hostname}`);\n // Determine if the caller is passing a query parameter or path since processing will be different.\n if (pathToAppend.startsWith(\"/?\") || pathToAppend.startsWith(\"?\")) {\n const queryParams = new URLSearchParams(pathToAppend);\n queryParams.forEach((value: string, key: string) => {\n parsingUrl.searchParams.append(key, value);\n });\n fluidInfo.dataStorePath = `${parsingUrl.pathname}${parsingUrl.search}`;\n } else {\n fluidInfo.dataStorePath = `${parsingUrl.pathname}${\n parsingUrl.pathname.endsWith(\"/\") || pathToAppend.startsWith(\"/\") ? \"\" : \"/\"\n }${pathToAppend}/${parsingUrl.search}`;\n }\n storeLocatorInOdspUrl(requestUrl, fluidInfo);\n\n return requestUrl.href;\n }\n\n private getKey(resolvedUrl: IOdspResolvedUrl): string {\n return `${resolvedUrl.siteUrl},${resolvedUrl.driveId},${resolvedUrl.itemId}`;\n }\n\n /**\n * Resolves request URL into driver details\n */\n public async resolve(request: IRequest): Promise<IOdspResolvedUrl> {\n const requestToBeResolved = { headers: request.headers, url: request.url };\n const isSharingLinkToRedeem = requestToBeResolved.headers?.[SharingLinkHeader.isSharingLinkToRedeem];\n try {\n const url = new URL(request.url);\n\n const odspFluidInfo = getLocatorFromOdspUrl(url);\n if (odspFluidInfo) {\n requestToBeResolved.url = createOdspUrl(odspFluidInfo);\n }\n } catch {\n // If the locator throws some error, then try to resolve the request as it is.\n }\n\n const odspResolvedUrl = await new OdspDriverUrlResolver().resolve(requestToBeResolved);\n\n if (isSharingLinkToRedeem) {\n // We need to remove the nav param if set by host when setting the sharelink as otherwise the shareLinkId\n // when redeeming the share link during the redeem fallback for trees latest call becomes greater than\n // the eligible length.\n odspResolvedUrl.shareLinkInfo = Object.assign(odspResolvedUrl.shareLinkInfo || {},\n { sharingLinkToRedeem: this.removeNavParam(request.url) });\n }\n if (odspResolvedUrl.itemId) {\n // Kick start the sharing link request if we don't have it already as a performance optimization.\n // For detached create new, we don't have an item id yet and therefore cannot generate a share link\n this.getShareLinkPromise(odspResolvedUrl).catch(() => {});\n }\n return odspResolvedUrl;\n }\n\n private removeNavParam(link: string): string {\n const url = new URL(link);\n const params = new URLSearchParams(url.search);\n params.delete(locatorQueryParamName);\n url.search = params.toString();\n return url.href;\n }\n\n private async getShareLinkPromise(resolvedUrl: IOdspResolvedUrl): Promise<string> {\n if (this.shareLinkFetcherProps === undefined) {\n throw new Error(\"Failed to get share link because share link fetcher props are missing\");\n }\n\n if (!(resolvedUrl.siteUrl && resolvedUrl.driveId && resolvedUrl.itemId)) {\n throw new Error(\"Failed to get share link because necessary information is missing \" +\n \"(e.g. siteUrl, driveId or itemId)\");\n }\n\n const key = this.getKey(resolvedUrl);\n const cachedLinkPromise = this.sharingLinkCache.get(key);\n if (cachedLinkPromise) {\n return cachedLinkPromise;\n }\n const newLinkPromise = getFileLink(\n this.shareLinkFetcherProps.tokenFetcher,\n resolvedUrl,\n this.shareLinkFetcherProps.identityType,\n this.logger,\n ).catch((error) => {\n // This should imply that error is a non-retriable error.\n this.logger.sendErrorEvent({ eventName: \"FluidFileUrlError\" }, error);\n this.sharingLinkCache.remove(key);\n throw error;\n });\n this.sharingLinkCache.add(key, async () => newLinkPromise);\n return newLinkPromise;\n }\n\n /**\n * Requests a driver + data store storage URL. Note that this method requires share link to be fetched\n * and it will throw in case share link fetcher props were not specified when instance was created.\n * @param resolvedUrl - The driver resolved URL\n * @param dataStorePath - The relative data store path URL.\n * For requesting a driver URL, this value should always be '/'\n * @param packageInfoSource - optional, represents container package information to be included in url.\n */\n public async getAbsoluteUrl(\n resolvedUrl: IResolvedUrl,\n dataStorePath: string,\n packageInfoSource?: IContainerPackageInfo,\n ): Promise<string> {\n const odspResolvedUrl = getOdspResolvedUrl(resolvedUrl);\n\n const shareLink = await this.getShareLinkPromise(odspResolvedUrl);\n const shareLinkUrl = new URL(shareLink);\n\n // back-compat: GitHub #9653\n const isFluidPackage = (pkg: any) =>\n typeof pkg === \"object\"\n && typeof pkg?.name === \"string\"\n && typeof pkg?.fluid === \"object\";\n let containerPackageName;\n if (packageInfoSource && \"name\" in packageInfoSource) {\n containerPackageName = packageInfoSource.name;\n // packageInfoSource is cast to any as it is typed to IContainerPackageInfo instead of IFluidCodeDetails\n } else if (isFluidPackage((packageInfoSource as any)?.package)) {\n containerPackageName = (packageInfoSource as any)?.package.name;\n } else {\n containerPackageName = (packageInfoSource as any)?.package;\n }\n containerPackageName = containerPackageName ?? odspResolvedUrl.codeHint?.containerPackageName;\n\n const context = await this.getContext?.(odspResolvedUrl, dataStorePath);\n\n storeLocatorInOdspUrl(shareLinkUrl, {\n siteUrl: odspResolvedUrl.siteUrl,\n driveId: odspResolvedUrl.driveId,\n itemId: odspResolvedUrl.itemId,\n dataStorePath,\n appName: this.appName,\n containerPackageName,\n fileVersion: odspResolvedUrl.fileVersion,\n context,\n });\n\n return shareLinkUrl.href;\n }\n\n /**\n * Crafts a supported document/driver URL\n */\n public static createDocumentUrl(baseUrl: string, driverInfo: OdspFluidDataStoreLocator) {\n const url = new URL(baseUrl);\n\n storeLocatorInOdspUrl(url, driverInfo);\n\n return url.href;\n }\n\n /**\n * Crafts a supported data store nav param\n * @deprecated encodeOdspFluidDataStoreLocator should be used instead\n */\n public static createNavParam(locator: OdspFluidDataStoreLocator) {\n return encodeOdspFluidDataStoreLocator(locator);\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"odspFluidFileLink.d.ts","sourceRoot":"","sources":["../src/odspFluidFileLink.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAa9D;;;;GAIG;AACH,wBAAgB,+BAA+B,CAAC,OAAO,EAAE,yBAAyB,GAAG,MAAM,CAuB1F;AAyDD,eAAO,MAAM,qBAAqB,QAAQ,CAAC;AAE3C;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,yBAAyB,QAKjF;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,GAAG,GAAG,yBAAyB,GAAG,SAAS,CAYrF"}
1
+ {"version":3,"file":"odspFluidFileLink.d.ts","sourceRoot":"","sources":["../src/odspFluidFileLink.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAc9D;;;;GAIG;AACH,wBAAgB,+BAA+B,CAAC,OAAO,EAAE,yBAAyB,GAAG,MAAM,CAwB1F;AA2DD,eAAO,MAAM,qBAAqB,QAAQ,CAAC;AAE3C;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,yBAAyB,QAKjF;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,GAAG,GAAG,yBAAyB,GAAG,SAAS,CAYrF"}