From 6cfe02c4eb2d30e93c5f3046bcb8ebc55187f58c Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Wed, 20 Mar 2024 14:26:13 +0000 Subject: [PATCH] feat: support system proxy when fetching fonts/metadata resolves https://github.com/nuxt/fonts/issues/76 --- package.json | 5 +++-- pnpm-lock.yaml | 9 ++++++--- src/assets.ts | 2 +- src/fetch.ts | 26 ++++++++++++++++++++++++++ src/providers/adobe.ts | 4 ++-- src/providers/bunny.ts | 4 ++-- src/providers/fontshare.ts | 5 +++-- src/providers/fontsource.ts | 2 +- src/providers/google.ts | 6 +++--- 9 files changed, 47 insertions(+), 16 deletions(-) create mode 100644 src/fetch.ts diff --git a/package.json b/package.json index 8c28122..76687f4 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "jiti": "^1.21.0", "magic-regexp": "^0.8.0", "magic-string": "^0.30.8", - "ofetch": "^1.3.3", + "node-fetch-native": "^1.6.2", "ohash": "^1.1.3", "pathe": "^1.1.2", "sirv": "^2.0.4", @@ -74,6 +74,7 @@ "consola": "^3.2.3", "eslint": "^8.57.0", "execa": "^8.0.1", + "ofetch": "^1.3.3", "nitropack": "^2.9.4", "nuxt": "^3.11.1", "nuxt-fonts-devtools": "latest", @@ -89,4 +90,4 @@ "resolutions": { "@nuxt/fonts": "workspace:*" } -} \ No newline at end of file +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1342308..3579580 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -47,9 +47,9 @@ importers: magic-string: specifier: ^0.30.8 version: 0.30.8 - ofetch: - specifier: ^1.3.3 - version: 1.3.3 + node-fetch-native: + specifier: ^1.6.2 + version: 1.6.2 ohash: specifier: ^1.1.3 version: 1.1.3 @@ -117,6 +117,9 @@ importers: nuxt-fonts-devtools: specifier: latest version: link:client + ofetch: + specifier: ^1.3.3 + version: 1.3.3 playwright-core: specifier: ^1.42.1 version: 1.42.1 diff --git a/src/assets.ts b/src/assets.ts index 9aeced7..cb9e447 100644 --- a/src/assets.ts +++ b/src/assets.ts @@ -1,7 +1,7 @@ import fsp from 'node:fs/promises' import { addDevServerHandler, useNuxt } from '@nuxt/kit' import { eventHandler, createError, lazyEventHandler } from 'h3' -import { fetch } from 'ofetch' +import { fetch } from 'node-fetch-native/proxy' import chalk from 'chalk' import { defu } from 'defu' import type { NitroConfig } from 'nitropack' diff --git a/src/fetch.ts b/src/fetch.ts new file mode 100644 index 0000000..8607798 --- /dev/null +++ b/src/fetch.ts @@ -0,0 +1,26 @@ +import defu from 'defu' +import { fetch } from 'node-fetch-native/proxy' +import { joinURL, withQuery } from 'ufo' + +interface Mini$FetchOptions extends RequestInit { + baseURL?: string + responseType?: 'json' | 'arrayBuffer' + query?: Record +} + +const mini$fetch = (url: string, options?: Mini$FetchOptions) => { + if (options?.baseURL) { + url = joinURL(options.baseURL, url) + } + if (options?.query) { + url = withQuery(url, options.query) + } + return fetch(url, options) + .then(r => options?.responseType === 'json' ? r.json() : options?.responseType === 'arrayBuffer' ? r.arrayBuffer() : r.text()) as Promise +} + +export const $fetch = Object.assign(mini$fetch, { + create: (defaults?: Mini$FetchOptions) => (url: string, options?: Mini$FetchOptions) => mini$fetch(url, defu(options, defaults)) +}) + +export { fetch } diff --git a/src/providers/adobe.ts b/src/providers/adobe.ts index 299b182..ab052f9 100644 --- a/src/providers/adobe.ts +++ b/src/providers/adobe.ts @@ -1,9 +1,9 @@ -import { $fetch } from 'ofetch' import { hash } from 'ohash' import type { FontProvider, ResolveFontFacesOptions } from '../types' import { extractFontFaceData, addLocalFallbacks } from '../css/parse' import { cachedData } from '../cache' +import { $fetch } from '../fetch' import { logger } from '../logger' interface ProviderOption { @@ -106,7 +106,7 @@ async function getFontDetails (family: string, variants: ResolveFontFacesOptions styles.push(style) } if (styles.length === 0) { continue } - const css = await fontCSSAPI(`${fonts.kits[kit]!.id}.css`) + const css = await fontCSSAPI(`${fonts.kits[kit]!.id}.css`) // Adobe uses slugs instead of names in its CSS to define its font faces, // so we need to first transform names into slugs. diff --git a/src/providers/bunny.ts b/src/providers/bunny.ts index bdaf9f7..40fdcf9 100644 --- a/src/providers/bunny.ts +++ b/src/providers/bunny.ts @@ -1,9 +1,9 @@ -import { $fetch } from 'ofetch' import { hash } from 'ohash' import type { FontProvider, ResolveFontFacesOptions } from '../types' import { extractFontFaceData, addLocalFallbacks } from '../css/parse' import { cachedData } from '../cache' +import { $fetch } from '../fetch' import { logger } from '../logger' export default { @@ -75,7 +75,7 @@ async function getFontDetails (family: string, variants: ResolveFontFacesOptions const resolvedVariants = weights.flatMap(w => [...styles].map(s => `${w}${s}`)) - const css = await fontAPI('/css', { + const css = await fontAPI('/css', { query: { family: id + ':' + resolvedVariants.join(',') } diff --git a/src/providers/fontshare.ts b/src/providers/fontshare.ts index aea04ee..300d31b 100644 --- a/src/providers/fontshare.ts +++ b/src/providers/fontshare.ts @@ -1,9 +1,9 @@ -import { $fetch } from 'ofetch' import { hash } from 'ohash' import type { FontProvider, ResolveFontFacesOptions } from '../types' import { extractFontFaceData, addLocalFallbacks } from '../css/parse' import { cachedData } from '../cache' +import { $fetch } from '../fetch' import { logger } from '../logger' export default { @@ -69,6 +69,7 @@ async function initialiseFontMeta () { let chunk do { chunk = await fontAPI<{ fonts: FontshareFontMeta[], has_more: boolean }>('/fonts', { + responseType: 'json', query: { offset, limit: 100 @@ -105,7 +106,7 @@ async function getFontDetails (family: string, variants: ResolveFontFacesOptions if (numbers.length === 0) return [] - const css = await fontAPI(`/css?f[]=${font.slug + '@' + numbers.join(',')}`) + const css = await fontAPI(`/css?f[]=${font.slug + '@' + numbers.join(',')}`) // TODO: support subsets and axes return addLocalFallbacks(family, extractFontFaceData(css)) diff --git a/src/providers/fontsource.ts b/src/providers/fontsource.ts index 80ba6dc..86fbae2 100644 --- a/src/providers/fontsource.ts +++ b/src/providers/fontsource.ts @@ -1,9 +1,9 @@ -import { $fetch } from 'ofetch' import { hash } from 'ohash' import type { FontProvider, NormalizedFontFaceData, ResolveFontFacesOptions } from '../types' import { addLocalFallbacks } from '../css/parse' import { cachedData } from '../cache' +import { $fetch } from '../fetch' import { logger } from '../logger' export default { diff --git a/src/providers/google.ts b/src/providers/google.ts index d7f1d7b..8e1814d 100644 --- a/src/providers/google.ts +++ b/src/providers/google.ts @@ -1,9 +1,9 @@ -import { $fetch } from 'ofetch' import { hash } from 'ohash' import type { FontProvider, ResolveFontFacesOptions } from '../types' import { extractFontFaceData, addLocalFallbacks } from '../css/parse' import { cachedData } from '../cache' +import { $fetch } from '../fetch' import { logger } from '../logger' export default { @@ -46,7 +46,7 @@ interface FontIndexMeta { let fonts: FontIndexMeta[] async function fetchFontMetadata () { - return await $fetch<{ familyMetadataList: FontIndexMeta[] }>('https://fonts.google.com/metadata/fonts') + return await $fetch<{ familyMetadataList: FontIndexMeta[] }>('https://fonts.google.com/metadata/fonts', { responseType: 'json' }) .then(r => r.familyMetadataList) } @@ -84,7 +84,7 @@ async function getFontDetails (family: string, variants: ResolveFontFacesOptions let css = '' for (const extension in userAgents) { - css += await $fetch('/css2', { + css += await $fetch('/css2', { baseURL: 'https://fonts.googleapis.com', headers: { 'user-agent': userAgents[extension as keyof typeof userAgents] }, query: {