forked from angular/angular-cli
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfetch-patch.ts
More file actions
72 lines (60 loc) · 2 KB
/
fetch-patch.ts
File metadata and controls
72 lines (60 loc) · 2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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
68
69
70
71
72
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import { lookup as lookupMimeType } from 'mrmime';
import { readFile } from 'node:fs/promises';
import { extname } from 'node:path';
import { workerData } from 'node:worker_threads';
/**
* This is passed as workerData when setting up the worker via the `piscina` package.
*/
const { assetFiles } = workerData as {
assetFiles: Record</** Destination */ string, /** Source */ string>;
};
const assetsCache: Map<string, { headers: undefined | Record<string, string>; content: Buffer }> =
new Map();
export function patchFetchToLoadInMemoryAssets(baseURL: URL): void {
const originalFetch = globalThis.fetch;
const patchedFetch: typeof fetch = async (input, init) => {
let url: URL;
if (input instanceof URL) {
url = input;
} else if (typeof input === 'string') {
url = new URL(input);
} else if (typeof input === 'object' && 'url' in input) {
url = new URL(input.url);
} else {
return originalFetch(input, init);
}
const { hostname } = url;
const pathname = decodeURIComponent(url.pathname);
if (hostname !== baseURL.hostname || !assetFiles[pathname]) {
// Only handle relative requests or files that are in assets.
return originalFetch(input, init);
}
const cachedAsset = assetsCache.get(pathname);
if (cachedAsset) {
const { content, headers } = cachedAsset;
return new Response(content, {
headers,
});
}
const extension = extname(pathname);
const mimeType = lookupMimeType(extension);
const content = await readFile(assetFiles[pathname]);
const headers = mimeType
? {
'Content-Type': mimeType,
}
: undefined;
assetsCache.set(pathname, { headers, content });
return new Response(content, {
headers,
});
};
globalThis.fetch = patchedFetch;
}