1
1
import * as fs from 'node:fs'
2
- import { readFile , writeFile } from 'node:fs/promises'
2
+ import { readFile } from 'node:fs/promises'
3
3
import {
4
4
type AddComponentOptions ,
5
5
addComponent ,
@@ -19,11 +19,13 @@ import type { SatoriOptions } from 'satori'
19
19
import { installNuxtSiteConfig } from 'nuxt-site-config-kit'
20
20
import { isDevelopment } from 'std-env'
21
21
import { hash } from 'ohash'
22
- import { basename , join , relative } from 'pathe'
22
+ import { basename , isAbsolute , join , relative } from 'pathe'
23
23
import type { ResvgRenderOptions } from '@resvg/resvg-js'
24
24
import type { SharpOptions } from 'sharp'
25
25
import { defu } from 'defu'
26
26
import { readPackageJSON } from 'pkg-types'
27
+ import { createStorage } from 'unstorage'
28
+ import fsDriver from 'unstorage/drivers/fs'
27
29
import type {
28
30
CompatibilityFlagEnvOverrides ,
29
31
FontConfig ,
@@ -45,7 +47,7 @@ import { setupGenerateHandler } from './build/generate'
45
47
import { setupPrerenderHandler } from './build/prerender'
46
48
import { setupBuildHandler } from './build/build'
47
49
import { checkLocalChrome , checkPlaywrightDependency , downloadFont , isUndefinedOrTruthy } from './util'
48
- import { normaliseFontInput } from './runtime/utils. pure'
50
+ import { normaliseFontInput } from './runtime/pure'
49
51
50
52
export interface ModuleOptions {
51
53
/**
@@ -260,45 +262,48 @@ export default defineNuxtModule<ModuleOptions>({
260
262
addServerPlugin ( resolve ( './runtime/nitro/plugins/nuxt-content' ) )
261
263
262
264
// default font is inter
263
- if ( ! config . fonts . length )
264
- config . fonts = [ 'Inter:400' , 'Inter:700' ]
265
-
266
- if ( preset === 'cloudflare' || preset === 'cloudflare-module' ) {
267
- config . fonts = config . fonts . filter ( ( f ) => {
268
- if ( typeof f !== 'string' && f . path ) {
269
- logger . warn ( `The ${ f . name } :${ f . weight } font was skipped because remote fonts are not available in Cloudflare Workers, please use a Google Font.` )
270
- return false
271
- }
272
- return true
273
- } )
265
+ if ( ! config . fonts . length ) {
266
+ config . fonts = [
267
+ { name : 'Inter' , weight : 400 , path : resolve ( './assets/Inter-400.ttf.base64' ) } ,
268
+ { name : 'Inter' , weight : 700 , path : resolve ( './assets/Inter-700.ttf.base64' ) } ,
269
+ ]
274
270
}
275
- const serverFontsDir = resolve ( './runtime/nitro/fonts' )
276
- config . fonts = await Promise . all ( normaliseFontInput ( config . fonts )
271
+
272
+ const serverFontsDir = resolve ( nuxt . options . buildDir , 'cache' , `nuxt-og-image@${ version } ` , '_fonts' )
273
+ // mkdir@
274
+ const fontStorage = createStorage ( {
275
+ driver : fsDriver ( {
276
+ base : serverFontsDir ,
277
+ } ) ,
278
+ } )
279
+ config . fonts = ( await Promise . all ( normaliseFontInput ( config . fonts )
277
280
. map ( async ( f ) => {
278
281
if ( ! f . key && ! f . path ) {
279
- if ( await downloadFont ( f , serverFontsDir , config . googleFontMirror ) ) {
282
+ if ( preset === 'stackblitz' ) {
283
+ logger . warn ( `The ${ f . name } :${ f . weight } font was skipped because remote fonts are not available in StackBlitz, please use a local font.` )
284
+ return false
285
+ }
286
+ if ( await downloadFont ( f , fontStorage , config . googleFontMirror ) ) {
280
287
// move file to serverFontsDir
281
288
f . key = `nuxt-og-image:fonts:${ f . name } -${ f . weight } .ttf.base64`
282
289
}
290
+ else {
291
+ logger . warn ( `Failed to download font ${ f . name } :${ f . weight } . You may be offline or behind a firewall blocking Google. Consider setting \`googleFontMirror: true\`.` )
292
+ return false
293
+ }
283
294
}
284
295
else if ( f . path ) {
285
- // move to assets folder as base64 and set key
286
- const fontPath = join ( nuxt . options . rootDir , nuxt . options . dir . public , f . path )
287
- const fontData = await readFile ( fontPath , 'base64' )
296
+ // resolve relative paths from public dir
297
+ if ( ! isAbsolute ( f . path ) ) {
298
+ // move to assets folder as base64 and set key
299
+ f . path = join ( nuxt . options . rootDir , nuxt . options . dir . public , f . path )
300
+ }
301
+ const fontData = await readFile ( f . path , 'base64' )
288
302
f . key = `nuxt-og-image:fonts:${ f . name } -${ f . weight } .ttf.base64`
289
- await writeFile ( resolve ( serverFontsDir , `${ basename ( f . path ) } .base64` ) , fontData )
303
+ await fontStorage . setItem ( `${ basename ( f . path ) } .base64` , fontData )
290
304
}
291
305
return f
292
- } ) )
293
- config . fonts = config . fonts . map ( ( f ) => {
294
- if ( preset === 'stackblitz' ) {
295
- if ( typeof f === 'string' || ( ! f . path && ! f . key ) ) {
296
- logger . warn ( `The ${ typeof f === 'string' ? f : `${ f . name } :${ f . weight } ` } font was skipped because remote fonts are not available in StackBlitz, please use a local font.` )
297
- return false
298
- }
299
- }
300
- return f
301
- } ) . filter ( Boolean ) as InputFontConfig [ ]
306
+ } ) ) ) . filter ( Boolean ) as InputFontConfig [ ]
302
307
303
308
// bundle fonts within nitro runtime
304
309
nuxt . options . nitro . serverAssets = nuxt . options . nitro . serverAssets || [ ]
@@ -459,6 +464,9 @@ declare module '#nuxt-og-image/components' {
459
464
${ componentImports }
460
465
}
461
466
}
467
+ declare module '#nuxt-og-image/unocss-config' {
468
+ export type theme = any
469
+ }
462
470
`
463
471
} )
464
472
0 commit comments