Skip to content

Commit

Permalink
fix(local): deduplicate found fonts
Browse files Browse the repository at this point in the history
  • Loading branch information
danielroe committed Mar 7, 2024
1 parent 1b93761 commit a44c4c4
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 12 deletions.
30 changes: 18 additions & 12 deletions src/providers/local.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,18 +63,13 @@ export default {
...(isDefaultStyle && isDefaultWeight) ? [[subset]] : [],
...(isDefaultStyle && isDefaultWeight && isDefaultSubset) ? [[]] : []
]
for (const family of [fontFamily, fontFamily.replace(NON_WORD_RE, '-'), fontFamily.replace(NON_WORD_RE, '')]) {
for (const option of options) {
const resolved = lookupFont([family, ...option].join('-')) || lookupFont([family, ...option].join(''))
if (resolved) {
fonts.push({
src: resolved,
weight,
style,
})
break
}
}
const resolved = findFirst([fontFamily, fontFamily.replace(NON_WORD_RE, '-'), fontFamily.replace(NON_WORD_RE, '')], options)
if (resolved) {
fonts.push({
src: [...new Set(resolved)],
weight,
style,
})
}
}
}
Expand All @@ -93,6 +88,17 @@ const NON_WORD_RE = /[^\w\d]+/g

export const isFontFile = (id: string) => FONT_RE.test(id)

function findFirst (families: string[], options: Array<string | number>[]) {
for (const family of families) {
for (const option of options) {
const resolved = lookupFont([family, ...option].join('-')) || lookupFont([family, ...option].join(''))
if (resolved) {
return resolved
}
}
}
}

function generateSlugs (path: string) {
const name = filename(path)
return [...new Set([
Expand Down
75 changes: 75 additions & 0 deletions test/providers/local.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { fileURLToPath } from 'node:url'
import fsp from 'node:fs/promises'

import type { Nuxt } from '@nuxt/schema'
import { describe, expect, it } from 'vitest'
import { dirname, join } from 'pathe'

import localProvider from '../../src/providers/local'

describe('local font provider', () => {
it('should scan for font files', async () => {
const cleanup = await createFixture('scanning', [
'font.ttf',
'font.woff',
'font.woff2',
'font.eot',
'font.otf',
'font.txt',
].flatMap(l => [`public/${l}`, `layer/public/${l}`]))
const provider = await setupFixture(['scanning', 'scanning/layer'])
const faces = provider.resolveFontFaces('font', {
fallbacks: [],
weights: ['normal'],
styles: ['normal'],
subsets: ['latin']
})
expect(faces).toMatchInlineSnapshot(`
{
"fonts": [
{
"src": [
"/font.eot",
"/font.otf",
"/font.ttf",
"/font.woff",
"/font.woff2",
],
"style": "normal",
"weight": "normal",
},
],
}
`)
await cleanup()
})
})

/** test utilities */

const fixturePath = fileURLToPath(new URL('../../node_modules/.cache/test/fixtures', import.meta.url))

async function createFixture (slug: string, files: string[]) {
await fsp.rm(join(fixturePath, slug), { recursive: true, force: true })
for (const file of files) {
const path = join(fixturePath, slug, file)
await fsp.mkdir(dirname(path), { recursive: true })
await fsp.writeFile(path, '')
}
return () => fsp.rm(join(fixturePath, slug), { recursive: true, force: true })
}

type DeepPartial<T> = {
[P in keyof T]?: DeepPartial<T[P]>
}

async function setupFixture (layers: string[]) {
const mockNuxt = {
options: {
_layers: layers.map(l => ({ cwd: join(fixturePath, l), config: { srcDir: join(fixturePath, l) } }))
},
hook: () => {},
} satisfies DeepPartial<Nuxt> as unknown as Nuxt
await localProvider.setup({}, mockNuxt)
return localProvider
}

0 comments on commit a44c4c4

Please sign in to comment.