@fluidframework/driver-utils 2.0.0-internal.3.0.5 → 2.0.0-internal.3.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.js +17 -19
- package/.mocharc.js +2 -2
- package/api-extractor.json +2 -2
- package/dist/blobAggregationStorage.d.ts +2 -2
- package/dist/blobAggregationStorage.d.ts.map +1 -1
- package/dist/blobAggregationStorage.js +11 -6
- package/dist/blobAggregationStorage.js.map +1 -1
- package/dist/blobCacheStorageService.d.ts.map +1 -1
- package/dist/blobCacheStorageService.js.map +1 -1
- package/dist/buildSnapshotTree.d.ts.map +1 -1
- package/dist/buildSnapshotTree.js.map +1 -1
- package/dist/documentStorageServiceProxy.d.ts.map +1 -1
- package/dist/documentStorageServiceProxy.js.map +1 -1
- package/dist/emptyDocumentDeltaStorageService.d.ts.map +1 -1
- package/dist/emptyDocumentDeltaStorageService.js.map +1 -1
- package/dist/error.d.ts.map +1 -1
- package/dist/error.js.map +1 -1
- package/dist/fluidResolvedUrl.d.ts.map +1 -1
- package/dist/fluidResolvedUrl.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/insecureUrlResolver.d.ts.map +1 -1
- package/dist/insecureUrlResolver.js +2 -1
- package/dist/insecureUrlResolver.js.map +1 -1
- package/dist/mapWithExpiration.d.ts.map +1 -1
- package/dist/mapWithExpiration.js +5 -3
- package/dist/mapWithExpiration.js.map +1 -1
- package/dist/messageRecognition.d.ts.map +1 -1
- package/dist/messageRecognition.js.map +1 -1
- package/dist/multiDocumentServiceFactory.d.ts.map +1 -1
- package/dist/multiDocumentServiceFactory.js.map +1 -1
- package/dist/multiUrlResolver.d.ts.map +1 -1
- package/dist/multiUrlResolver.js.map +1 -1
- package/dist/network.d.ts +1 -1
- package/dist/network.d.ts.map +1 -1
- package/dist/network.js +4 -3
- package/dist/network.js.map +1 -1
- package/dist/networkUtils.d.ts.map +1 -1
- package/dist/networkUtils.js +2 -3
- package/dist/networkUtils.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/parallelRequests.d.ts.map +1 -1
- package/dist/parallelRequests.js +19 -9
- package/dist/parallelRequests.js.map +1 -1
- package/dist/prefetchDocumentStorageService.d.ts.map +1 -1
- package/dist/prefetchDocumentStorageService.js.map +1 -1
- package/dist/rateLimiter.d.ts.map +1 -1
- package/dist/rateLimiter.js.map +1 -1
- package/dist/readAndParse.d.ts.map +1 -1
- package/dist/readAndParse.js.map +1 -1
- package/dist/runWithRetry.d.ts.map +1 -1
- package/dist/runWithRetry.js.map +1 -1
- package/dist/summaryForCreateNew.d.ts.map +1 -1
- package/dist/summaryForCreateNew.js.map +1 -1
- package/dist/treeConversions.d.ts.map +1 -1
- package/dist/treeConversions.js +1 -4
- package/dist/treeConversions.js.map +1 -1
- package/dist/treeUtils.d.ts +10 -10
- package/dist/treeUtils.d.ts.map +1 -1
- package/dist/treeUtils.js +10 -10
- package/dist/treeUtils.js.map +1 -1
- package/lib/blobAggregationStorage.d.ts +2 -2
- package/lib/blobAggregationStorage.d.ts.map +1 -1
- package/lib/blobAggregationStorage.js +11 -6
- package/lib/blobAggregationStorage.js.map +1 -1
- package/lib/blobCacheStorageService.d.ts.map +1 -1
- package/lib/blobCacheStorageService.js.map +1 -1
- package/lib/buildSnapshotTree.d.ts.map +1 -1
- package/lib/buildSnapshotTree.js.map +1 -1
- package/lib/documentStorageServiceProxy.d.ts.map +1 -1
- package/lib/documentStorageServiceProxy.js.map +1 -1
- package/lib/emptyDocumentDeltaStorageService.d.ts.map +1 -1
- package/lib/emptyDocumentDeltaStorageService.js.map +1 -1
- package/lib/error.d.ts.map +1 -1
- package/lib/error.js.map +1 -1
- package/lib/fluidResolvedUrl.d.ts.map +1 -1
- package/lib/fluidResolvedUrl.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/insecureUrlResolver.d.ts.map +1 -1
- package/lib/insecureUrlResolver.js +2 -1
- package/lib/insecureUrlResolver.js.map +1 -1
- package/lib/mapWithExpiration.d.ts.map +1 -1
- package/lib/mapWithExpiration.js +5 -3
- package/lib/mapWithExpiration.js.map +1 -1
- package/lib/messageRecognition.d.ts.map +1 -1
- package/lib/messageRecognition.js +1 -1
- package/lib/messageRecognition.js.map +1 -1
- package/lib/multiDocumentServiceFactory.d.ts.map +1 -1
- package/lib/multiDocumentServiceFactory.js.map +1 -1
- package/lib/multiUrlResolver.d.ts.map +1 -1
- package/lib/multiUrlResolver.js.map +1 -1
- package/lib/network.d.ts +1 -1
- package/lib/network.d.ts.map +1 -1
- package/lib/network.js +4 -3
- package/lib/network.js.map +1 -1
- package/lib/networkUtils.d.ts.map +1 -1
- package/lib/networkUtils.js +2 -3
- package/lib/networkUtils.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/parallelRequests.d.ts.map +1 -1
- package/lib/parallelRequests.js +19 -9
- package/lib/parallelRequests.js.map +1 -1
- package/lib/prefetchDocumentStorageService.d.ts.map +1 -1
- package/lib/prefetchDocumentStorageService.js.map +1 -1
- package/lib/rateLimiter.d.ts.map +1 -1
- package/lib/rateLimiter.js.map +1 -1
- package/lib/readAndParse.d.ts.map +1 -1
- package/lib/readAndParse.js.map +1 -1
- package/lib/runWithRetry.d.ts.map +1 -1
- package/lib/runWithRetry.js.map +1 -1
- package/lib/summaryForCreateNew.d.ts.map +1 -1
- package/lib/summaryForCreateNew.js.map +1 -1
- package/lib/treeConversions.d.ts.map +1 -1
- package/lib/treeConversions.js +4 -7
- package/lib/treeConversions.js.map +1 -1
- package/lib/treeUtils.d.ts +10 -10
- package/lib/treeUtils.d.ts.map +1 -1
- package/lib/treeUtils.js +11 -11
- package/lib/treeUtils.js.map +1 -1
- package/package.json +128 -127
- package/prettier.config.cjs +1 -1
- package/src/blobAggregationStorage.ts +374 -322
- package/src/blobCacheStorageService.ts +20 -17
- package/src/buildSnapshotTree.ts +54 -51
- package/src/documentStorageServiceProxy.ts +49 -43
- package/src/emptyDocumentDeltaStorageService.ts +11 -10
- package/src/error.ts +5 -7
- package/src/fluidResolvedUrl.ts +9 -6
- package/src/index.ts +5 -1
- package/src/insecureUrlResolver.ts +127 -116
- package/src/mapWithExpiration.ts +111 -104
- package/src/messageRecognition.ts +25 -19
- package/src/multiDocumentServiceFactory.ts +73 -62
- package/src/multiUrlResolver.ts +26 -29
- package/src/network.ts +114 -112
- package/src/networkUtils.ts +37 -34
- package/src/packageVersion.ts +1 -1
- package/src/parallelRequests.ts +571 -509
- package/src/prefetchDocumentStorageService.ts +76 -74
- package/src/rateLimiter.ts +29 -29
- package/src/readAndParse.ts +7 -4
- package/src/runWithRetry.ts +105 -94
- package/src/summaryForCreateNew.ts +27 -24
- package/src/treeConversions.ts +48 -70
- package/src/treeUtils.ts +70 -74
- package/tsconfig.esnext.json +6 -6
- package/tsconfig.json +8 -12
|
@@ -3,30 +3,33 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
IDocumentStorageService,
|
|
8
|
+
IDocumentStorageServicePolicies,
|
|
9
|
+
} from "@fluidframework/driver-definitions";
|
|
7
10
|
import { DocumentStorageServiceProxy } from "./documentStorageServiceProxy";
|
|
8
11
|
|
|
9
12
|
/**
|
|
10
13
|
* IDocumentStorageService adapter with pre-cached blobs.
|
|
11
14
|
*/
|
|
12
15
|
export class BlobCacheStorageService extends DocumentStorageServiceProxy {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
constructor(
|
|
17
|
+
internalStorageService: IDocumentStorageService,
|
|
18
|
+
private readonly blobs: Map<string, ArrayBufferLike>,
|
|
19
|
+
) {
|
|
20
|
+
super(internalStorageService);
|
|
21
|
+
}
|
|
19
22
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
+
public get policies(): IDocumentStorageServicePolicies | undefined {
|
|
24
|
+
return this.internalStorageService.policies;
|
|
25
|
+
}
|
|
23
26
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
public async readBlob(id: string): Promise<ArrayBufferLike> {
|
|
28
|
+
const blob = this.blobs.get(id);
|
|
29
|
+
if (blob !== undefined) {
|
|
30
|
+
return blob;
|
|
31
|
+
}
|
|
29
32
|
|
|
30
|
-
|
|
31
|
-
|
|
33
|
+
return this.internalStorageService.readBlob(id);
|
|
34
|
+
}
|
|
32
35
|
}
|
package/src/buildSnapshotTree.ts
CHANGED
|
@@ -6,57 +6,60 @@
|
|
|
6
6
|
import { assert, stringToBuffer } from "@fluidframework/common-utils";
|
|
7
7
|
import * as git from "@fluidframework/gitresources";
|
|
8
8
|
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
FileMode,
|
|
10
|
+
ISnapshotTree,
|
|
11
|
+
ITreeEntry,
|
|
12
|
+
TreeEntry,
|
|
13
13
|
} from "@fluidframework/protocol-definitions";
|
|
14
14
|
import { buildHierarchy } from "@fluidframework/protocol-base";
|
|
15
15
|
import { v4 as uuid } from "uuid";
|
|
16
16
|
|
|
17
17
|
function flattenCore(
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
path: string,
|
|
19
|
+
treeEntries: ITreeEntry[],
|
|
20
|
+
blobMap: Map<string, ArrayBufferLike>,
|
|
21
21
|
): git.ITreeEntry[] {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
const entries: git.ITreeEntry[] = [];
|
|
23
|
+
for (const treeEntry of treeEntries) {
|
|
24
|
+
const subPath = `${path}${treeEntry.path}`;
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
26
|
+
if (treeEntry.type === TreeEntry.Blob) {
|
|
27
|
+
const blob = treeEntry.value;
|
|
28
|
+
const buffer = stringToBuffer(blob.contents, blob.encoding);
|
|
29
|
+
const id = uuid();
|
|
30
|
+
blobMap.set(id, buffer);
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
32
|
+
const entry: git.ITreeEntry = {
|
|
33
|
+
mode: FileMode[treeEntry.mode],
|
|
34
|
+
path: subPath,
|
|
35
|
+
sha: id,
|
|
36
|
+
size: 0,
|
|
37
|
+
type: "blob",
|
|
38
|
+
url: "",
|
|
39
|
+
};
|
|
40
|
+
entries.push(entry);
|
|
41
|
+
} else if (treeEntry.type === TreeEntry.Tree) {
|
|
42
|
+
assert(
|
|
43
|
+
treeEntry.type === TreeEntry.Tree,
|
|
44
|
+
0x101 /* "Unexpected tree entry type on flatten!" */,
|
|
45
|
+
);
|
|
46
|
+
const t = treeEntry.value;
|
|
47
|
+
const entry: git.ITreeEntry = {
|
|
48
|
+
mode: FileMode[treeEntry.mode],
|
|
49
|
+
path: subPath,
|
|
50
|
+
sha: "",
|
|
51
|
+
size: -1,
|
|
52
|
+
type: "tree",
|
|
53
|
+
url: "",
|
|
54
|
+
};
|
|
55
|
+
entries.push(entry);
|
|
53
56
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
57
|
+
const subTreeEntries = flattenCore(`${subPath}/`, t.entries, blobMap);
|
|
58
|
+
entries.push(...subTreeEntries);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
58
61
|
|
|
59
|
-
|
|
62
|
+
return entries;
|
|
60
63
|
}
|
|
61
64
|
|
|
62
65
|
/**
|
|
@@ -67,12 +70,12 @@ function flattenCore(
|
|
|
67
70
|
* @returns A flatten with of the ITreeEntry
|
|
68
71
|
*/
|
|
69
72
|
function flatten(tree: ITreeEntry[], blobMap: Map<string, ArrayBufferLike>): git.ITree {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
73
|
+
const entries = flattenCore("", tree, blobMap);
|
|
74
|
+
return {
|
|
75
|
+
sha: "",
|
|
76
|
+
tree: entries,
|
|
77
|
+
url: "",
|
|
78
|
+
};
|
|
76
79
|
}
|
|
77
80
|
|
|
78
81
|
/**
|
|
@@ -84,9 +87,9 @@ function flatten(tree: ITreeEntry[], blobMap: Map<string, ArrayBufferLike>): git
|
|
|
84
87
|
* @returns the hierarchical tree
|
|
85
88
|
*/
|
|
86
89
|
export function buildSnapshotTree(
|
|
87
|
-
|
|
88
|
-
|
|
90
|
+
entries: ITreeEntry[],
|
|
91
|
+
blobMap: Map<string, ArrayBufferLike>,
|
|
89
92
|
): ISnapshotTree {
|
|
90
|
-
|
|
91
|
-
|
|
93
|
+
const flattened = flatten(entries, blobMap);
|
|
94
|
+
return buildHierarchy(flattened);
|
|
92
95
|
}
|
|
@@ -4,62 +4,68 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
FetchSource,
|
|
8
|
+
IDocumentStorageService,
|
|
9
|
+
IDocumentStorageServicePolicies,
|
|
10
|
+
ISummaryContext,
|
|
11
11
|
} from "@fluidframework/driver-definitions";
|
|
12
12
|
import {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
ICreateBlobResponse,
|
|
14
|
+
ISnapshotTree,
|
|
15
|
+
ISummaryHandle,
|
|
16
|
+
ISummaryTree,
|
|
17
|
+
IVersion,
|
|
18
18
|
} from "@fluidframework/protocol-definitions";
|
|
19
19
|
|
|
20
20
|
export class DocumentStorageServiceProxy implements IDocumentStorageService {
|
|
21
|
-
|
|
21
|
+
private _policies: IDocumentStorageServicePolicies | undefined;
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
public set policies(policies: IDocumentStorageServicePolicies | undefined) {
|
|
24
|
+
this._policies = policies;
|
|
25
|
+
}
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
public get policies() {
|
|
28
|
+
return this._policies ?? this.internalStorageService.policies;
|
|
29
|
+
}
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
public get repositoryUrl(): string {
|
|
32
|
+
return this.internalStorageService.repositoryUrl;
|
|
33
|
+
}
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
constructor(protected readonly internalStorageService: IDocumentStorageService) {}
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
public async getSnapshotTree(
|
|
38
|
+
version?: IVersion,
|
|
39
|
+
scenarioName?: string,
|
|
40
|
+
): Promise<ISnapshotTree | null> {
|
|
41
|
+
return this.internalStorageService.getSnapshotTree(version, scenarioName);
|
|
42
|
+
}
|
|
40
43
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
44
|
+
public async getVersions(
|
|
45
|
+
versionId: string | null,
|
|
46
|
+
count: number,
|
|
47
|
+
scenarioName?: string,
|
|
48
|
+
fetchSource?: FetchSource,
|
|
49
|
+
): Promise<IVersion[]> {
|
|
50
|
+
return this.internalStorageService.getVersions(versionId, count, scenarioName, fetchSource);
|
|
51
|
+
}
|
|
49
52
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
+
public async uploadSummaryWithContext(
|
|
54
|
+
summary: ISummaryTree,
|
|
55
|
+
context: ISummaryContext,
|
|
56
|
+
): Promise<string> {
|
|
57
|
+
return this.internalStorageService.uploadSummaryWithContext(summary, context);
|
|
58
|
+
}
|
|
53
59
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
60
|
+
public async downloadSummary(handle: ISummaryHandle): Promise<ISummaryTree> {
|
|
61
|
+
return this.internalStorageService.downloadSummary(handle);
|
|
62
|
+
}
|
|
57
63
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
64
|
+
public async createBlob(file: ArrayBufferLike): Promise<ICreateBlobResponse> {
|
|
65
|
+
return this.internalStorageService.createBlob(file);
|
|
66
|
+
}
|
|
61
67
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
68
|
+
public async readBlob(blobId: string): Promise<ArrayBufferLike> {
|
|
69
|
+
return this.internalStorageService.readBlob(blobId);
|
|
70
|
+
}
|
|
65
71
|
}
|
|
@@ -11,14 +11,15 @@ import { Queue } from "./parallelRequests";
|
|
|
11
11
|
* Implementation of IDocumentDeltaStorageService that will always return an empty message queue when fetching messages
|
|
12
12
|
*/
|
|
13
13
|
export class EmptyDocumentDeltaStorageService implements IDocumentDeltaStorageService {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
14
|
+
public fetchMessages(
|
|
15
|
+
from: number,
|
|
16
|
+
_to: number | undefined,
|
|
17
|
+
_abortSignal?: AbortSignal,
|
|
18
|
+
_cachedOnly?: boolean,
|
|
19
|
+
_fetchReason?: string,
|
|
20
|
+
): IStream<ISequencedDocumentMessage[]> {
|
|
21
|
+
const queue = new Queue<ISequencedDocumentMessage[]>();
|
|
22
|
+
queue.pushDone();
|
|
23
|
+
return queue;
|
|
24
|
+
}
|
|
24
25
|
}
|
package/src/error.ts
CHANGED
|
@@ -8,12 +8,10 @@ import { IFluidErrorBase, LoggingError } from "@fluidframework/telemetry-utils";
|
|
|
8
8
|
|
|
9
9
|
/** Error indicating an API is being used improperly resulting in an invalid operation. */
|
|
10
10
|
export class UsageError extends LoggingError implements IDriverErrorBase, IFluidErrorBase {
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
readonly errorType = DriverErrorType.usageError;
|
|
12
|
+
readonly canRetry = false;
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
super(message, { usageError: true });
|
|
18
|
-
}
|
|
14
|
+
constructor(message: string) {
|
|
15
|
+
super(message, { usageError: true });
|
|
16
|
+
}
|
|
19
17
|
}
|
package/src/fluidResolvedUrl.ts
CHANGED
|
@@ -5,11 +5,14 @@
|
|
|
5
5
|
|
|
6
6
|
import { IResolvedUrl, IFluidResolvedUrl } from "@fluidframework/driver-definitions";
|
|
7
7
|
|
|
8
|
-
export const isFluidResolvedUrl =
|
|
9
|
-
|
|
8
|
+
export const isFluidResolvedUrl = (
|
|
9
|
+
resolved: IResolvedUrl | undefined,
|
|
10
|
+
): resolved is IFluidResolvedUrl => resolved?.type === "fluid";
|
|
10
11
|
|
|
11
|
-
export function ensureFluidResolvedUrl(
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
export function ensureFluidResolvedUrl(
|
|
13
|
+
resolved: IResolvedUrl | undefined,
|
|
14
|
+
): asserts resolved is IFluidResolvedUrl {
|
|
15
|
+
if (!isFluidResolvedUrl(resolved)) {
|
|
16
|
+
throw new Error(`resolved is not a Fluid url. Type: ${resolved?.type}`);
|
|
17
|
+
}
|
|
15
18
|
}
|
package/src/index.ts
CHANGED
|
@@ -59,4 +59,8 @@ export {
|
|
|
59
59
|
getQuorumValuesFromProtocolSummary,
|
|
60
60
|
} from "./summaryForCreateNew";
|
|
61
61
|
export { convertSummaryTreeToSnapshotITree } from "./treeConversions";
|
|
62
|
-
export {
|
|
62
|
+
export {
|
|
63
|
+
convertSnapshotAndBlobsToSummaryTree,
|
|
64
|
+
ISummaryTreeAssemblerProps,
|
|
65
|
+
SummaryTreeAssembler,
|
|
66
|
+
} from "./treeUtils";
|
|
@@ -7,10 +7,10 @@ import { parse } from "url";
|
|
|
7
7
|
import { assert } from "@fluidframework/common-utils";
|
|
8
8
|
import { IRequest } from "@fluidframework/core-interfaces";
|
|
9
9
|
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
IFluidResolvedUrl,
|
|
11
|
+
IResolvedUrl,
|
|
12
|
+
IUrlResolver,
|
|
13
|
+
DriverHeader,
|
|
14
14
|
} from "@fluidframework/driver-definitions";
|
|
15
15
|
import Axios from "axios";
|
|
16
16
|
|
|
@@ -29,128 +29,139 @@ import Axios from "axios";
|
|
|
29
29
|
* works or a router inside of a single page app framework.
|
|
30
30
|
*/
|
|
31
31
|
export class InsecureUrlResolver implements IUrlResolver {
|
|
32
|
-
|
|
32
|
+
private readonly cache = new Map<string, Promise<IResolvedUrl>>();
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
34
|
+
constructor(
|
|
35
|
+
private readonly hostUrl: string,
|
|
36
|
+
private readonly ordererUrl: string,
|
|
37
|
+
private readonly storageUrl: string,
|
|
38
|
+
private readonly tenantId: string,
|
|
39
|
+
private readonly bearer: string,
|
|
40
|
+
private readonly isForNodeTest: boolean = false,
|
|
41
|
+
) {}
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
43
|
+
public async resolve(request: IRequest): Promise<IResolvedUrl | undefined> {
|
|
44
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
45
|
+
if (request.headers?.[DriverHeader.createNew]) {
|
|
46
|
+
const [, queryString] = request.url.split("?");
|
|
47
|
+
const searchParams = new URLSearchParams(queryString);
|
|
48
|
+
const fileName = searchParams.get("fileName");
|
|
49
|
+
return this.resolveHelper(fileName);
|
|
50
|
+
}
|
|
51
|
+
const parsedUrl = new URL(request.url);
|
|
52
|
+
// If hosts match then we use the local tenant information. Otherwise we make a REST call out to the hosting
|
|
53
|
+
// service using our bearer token.
|
|
54
|
+
if (this.isForNodeTest) {
|
|
55
|
+
const [, documentId, tmpRelativePath] = parsedUrl.pathname.substr(1).split("/");
|
|
56
|
+
const relativePath = tmpRelativePath === undefined ? "" : tmpRelativePath;
|
|
57
|
+
return this.resolveHelper(documentId, relativePath, parsedUrl.search);
|
|
58
|
+
} else if (parsedUrl.host === window.location.host) {
|
|
59
|
+
const fullPath = parsedUrl.pathname.substr(1);
|
|
60
|
+
const documentId = fullPath.split("/")[0];
|
|
61
|
+
const documentRelativePath = fullPath.slice(documentId.length);
|
|
62
|
+
return this.resolveHelper(documentId, documentRelativePath);
|
|
63
|
+
} else {
|
|
64
|
+
const maybeResolvedUrl = this.cache.get(request.url);
|
|
65
|
+
if (maybeResolvedUrl) {
|
|
66
|
+
return maybeResolvedUrl;
|
|
67
|
+
}
|
|
68
68
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
69
|
+
const headers = {
|
|
70
|
+
Authorization: `Bearer ${this.bearer}`,
|
|
71
|
+
};
|
|
72
|
+
const resolvedP = Axios.post<IResolvedUrl>(
|
|
73
|
+
`${this.hostUrl}/api/v1/load`,
|
|
74
|
+
{
|
|
75
|
+
url: request.url,
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
headers,
|
|
79
|
+
},
|
|
80
|
+
);
|
|
81
|
+
this.cache.set(
|
|
82
|
+
request.url,
|
|
83
|
+
resolvedP.then((resolved) => resolved.data),
|
|
84
|
+
);
|
|
81
85
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
86
|
+
return this.cache.get(request.url);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
85
89
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
90
|
+
private resolveHelper(
|
|
91
|
+
documentId: string | null,
|
|
92
|
+
documentRelativePath: string = "",
|
|
93
|
+
queryParams: string = "",
|
|
94
|
+
) {
|
|
95
|
+
const encodedTenantId = encodeURIComponent(this.tenantId);
|
|
96
|
+
const host = new URL(this.ordererUrl).host;
|
|
97
|
+
// when the document ID is not provided we need to resolve a special create new document URL.
|
|
98
|
+
// the actual container ID will be generated by the driver.
|
|
99
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
100
|
+
if (!documentId) {
|
|
101
|
+
const createNewResponse: IFluidResolvedUrl = {
|
|
102
|
+
endpoints: {
|
|
103
|
+
deltaStorageUrl: `${this.ordererUrl}/deltas/${encodedTenantId}/new`,
|
|
104
|
+
ordererUrl: this.ordererUrl,
|
|
105
|
+
storageUrl: `${this.storageUrl}/repos/${encodedTenantId}`,
|
|
106
|
+
},
|
|
107
|
+
// document ID is ignored by the driver for new container requests
|
|
108
|
+
id: "",
|
|
109
|
+
tokens: {},
|
|
110
|
+
type: "fluid",
|
|
111
|
+
url: `fluid://${host}/${encodedTenantId}/new`,
|
|
112
|
+
};
|
|
113
|
+
return createNewResponse;
|
|
114
|
+
}
|
|
115
|
+
const encodedDocId = encodeURIComponent(documentId);
|
|
116
|
+
const relativePath =
|
|
117
|
+
!documentRelativePath || documentRelativePath.startsWith("/")
|
|
118
|
+
? documentRelativePath
|
|
119
|
+
: `/${documentRelativePath}`;
|
|
120
|
+
const documentUrl = `fluid://${host}/${encodedTenantId}/${encodedDocId}${relativePath}${queryParams}`;
|
|
111
121
|
|
|
112
|
-
|
|
113
|
-
|
|
122
|
+
const deltaStorageUrl = `${this.ordererUrl}/deltas/${encodedTenantId}/${encodedDocId}`;
|
|
123
|
+
const storageUrl = `${this.storageUrl}/repos/${encodedTenantId}`;
|
|
114
124
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
125
|
+
const response: IFluidResolvedUrl = {
|
|
126
|
+
endpoints: {
|
|
127
|
+
deltaStorageUrl,
|
|
128
|
+
ordererUrl: this.ordererUrl,
|
|
129
|
+
storageUrl,
|
|
130
|
+
},
|
|
131
|
+
id: documentId,
|
|
132
|
+
tokens: {},
|
|
133
|
+
type: "fluid",
|
|
134
|
+
url: documentUrl,
|
|
135
|
+
};
|
|
136
|
+
return response;
|
|
137
|
+
}
|
|
128
138
|
|
|
129
|
-
|
|
130
|
-
|
|
139
|
+
public async getAbsoluteUrl(resolvedUrl: IResolvedUrl, relativeUrl: string): Promise<string> {
|
|
140
|
+
const fluidResolvedUrl = resolvedUrl as IFluidResolvedUrl;
|
|
131
141
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
142
|
+
const parsedUrl = parse(fluidResolvedUrl.url);
|
|
143
|
+
const [, , documentId] = parsedUrl.pathname?.split("/") ?? [];
|
|
144
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
145
|
+
assert(!!documentId, 0x273 /* "Invalid document id from parsed URL" */);
|
|
136
146
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
147
|
+
let url = relativeUrl;
|
|
148
|
+
if (url.startsWith("/")) {
|
|
149
|
+
url = url.substr(1);
|
|
150
|
+
}
|
|
141
151
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
152
|
+
return `${this.hostUrl}/${encodeURIComponent(this.tenantId)}/${encodeURIComponent(
|
|
153
|
+
documentId,
|
|
154
|
+
)}/${url}`;
|
|
155
|
+
}
|
|
145
156
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
157
|
+
public createCreateNewRequest(fileName?: string): IRequest {
|
|
158
|
+
const createNewRequest: IRequest = {
|
|
159
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
160
|
+
url: fileName ? `${this.hostUrl}?fileName=${fileName}` : this.hostUrl,
|
|
161
|
+
headers: {
|
|
162
|
+
[DriverHeader.createNew]: true,
|
|
163
|
+
},
|
|
164
|
+
};
|
|
165
|
+
return createNewRequest;
|
|
166
|
+
}
|
|
156
167
|
}
|