summaryrefslogtreecommitdiff
path: root/packages/astro/src/assets/fonts/implementations/font-fetcher.ts
blob: af70bd1300f934920f3e44d7b13f0d4b68023f50 (plain) (blame)
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
import { isAbsolute } from 'node:path';
import type { Storage } from 'unstorage';
import type { ErrorHandler, FontFetcher } from '../definitions.js';
import { cache } from '../utils.js';

export function createCachedFontFetcher({
	storage,
	errorHandler,
	fetch,
	readFile,
}: {
	storage: Storage;
	errorHandler: ErrorHandler;
	fetch: (url: string) => Promise<Response>;
	readFile: (url: string) => Promise<Buffer>;
}): FontFetcher {
	return {
		async fetch(hash, url) {
			return await cache(storage, hash, async () => {
				try {
					if (isAbsolute(url)) {
						return await readFile(url);
					}
					// TODO: find a way to pass headers
					// https://github.com/unjs/unifont/issues/143
					const response = await fetch(url);
					if (!response.ok) {
						throw new Error(`Response was not successful, received status code ${response.status}`);
					}
					return Buffer.from(await response.arrayBuffer());
				} catch (cause) {
					throw errorHandler.handle({
						type: 'cannot-fetch-font-file',
						data: { url },
						cause,
					});
				}
			});
		},
	};
}