forked from vercel/next.js
/
utils.ts
107 lines (97 loc) · 2.23 KB
/
utils.ts
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
const allowedDisplayValues = ['auto', 'block', 'swap', 'fallback', 'optional']
const formatValues = (values: string[]) =>
values.map((val) => `\`${val}\``).join(', ')
const extToFormat = {
woff: 'woff',
woff2: 'woff2',
ttf: 'truetype',
otf: 'opentype',
eot: 'embedded-opentype',
}
type FontOptions = {
src: Array<{
path: string
weight?: string
style?: string
ext: string
format: string
}>
display: string
weight?: string
style?: string
fallback?: string[]
preload: boolean
variable?: string
adjustFontFallback?: string | false
declarations?: Array<{ prop: string; value: string }>
}
export function validateData(functionName: string, fontData: any): FontOptions {
if (functionName) {
throw new Error(`@next/font/local has no named exports`)
}
let {
src,
display = 'optional',
weight,
style,
fallback,
preload = true,
variable,
adjustFontFallback,
declarations,
} = fontData || ({} as any)
if (!allowedDisplayValues.includes(display)) {
throw new Error(
`Invalid display value \`${display}\`.\nAvailable display values: ${formatValues(
allowedDisplayValues
)}`
)
}
if (!src) {
throw new Error('Missing required `src` property')
}
if (!Array.isArray(src)) {
src = [{ path: src, weight, style }]
} else {
if (src.length === 0) {
throw new Error('Unexpected empty `src` array.')
}
}
src = src.map((fontFile: any) => {
const ext = /\.(woff|woff2|eot|ttf|otf)$/.exec(fontFile.path)?.[1]
if (!ext) {
throw new Error(`Unexpected file \`${fontFile.path}\``)
}
return {
...fontFile,
ext,
format: extToFormat[ext as 'woff' | 'woff2' | 'eot' | 'ttf' | 'otf'],
}
})
if (Array.isArray(declarations)) {
declarations.forEach((declaration) => {
if (
[
'font-family',
'src',
'font-display',
'font-weight',
'font-style',
].includes(declaration?.prop)
) {
throw new Error(`Invalid declaration prop: \`${declaration.prop}\``)
}
})
}
return {
src,
display,
weight,
style,
fallback,
preload,
variable,
adjustFontFallback,
declarations,
}
}