nuxt-og-image 5.1.13 → 6.0.0-beta.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/bin/cli.mjs +2 -0
- package/dist/chunks/css-classes.cjs +307 -0
- package/dist/chunks/css-classes.mjs +303 -0
- package/dist/chunks/css-provider.cjs +14 -0
- package/dist/chunks/css-provider.mjs +12 -0
- package/dist/chunks/uno.cjs +123 -0
- package/dist/chunks/uno.mjs +118 -0
- package/dist/cli.cjs +478 -0
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.mjs +461 -0
- package/dist/client/200.html +1 -1
- package/dist/client/404.html +1 -1
- package/dist/client/_fonts/0xp3SbCWC1OhX7q1-uF6kilMZFm-alJNkUtkLTPCy_A-tN9KwPUWhhXvtqh74sU9FIkI4W6hsbm85r0X24hjOfM.woff2 +0 -0
- package/dist/client/_fonts/1ZTlEDqU4DtwDJiND8f6qaugUpa0RIDvQl-v7iM6l54-995OEiyou9G2dJsMNn9aLuHTFlgwosm_9gD5SQUWR40.woff +0 -0
- package/dist/client/_fonts/1ZTlEDqU4DtwDJiND8f6qaugUpa0RIDvQl-v7iM6l54-D6hedAgqRfOCLZzaShnyeAvlEnMzk4Wm7g9WDKWFHIc.woff +0 -0
- package/dist/client/_fonts/1ZTlEDqU4DtwDJiND8f6qaugUpa0RIDvQl-v7iM6l54-vrK12kZ24WGUghky9YxsOZpLH8Tt4jMU8XIvzgLQ6DU.woff +0 -0
- package/dist/client/_fonts/4HA9tc4y8BVQeLXvLn3JgQqilAj1xrAnUSprQGHIPSw-ZPswEL_UDOYaxTLQDUySPjoOHDxhD83pD19HMfKfK9s.woff2 +0 -0
- package/dist/client/_fonts/Bmul3LaKlc7BUKqJHE_UmEoF40Sg_2ga52yJjwyDcKs-TnYmYl1DNYkiWMu0Vx49DakCPBuiCCj9zoLIuQjUdKY.woff2 +0 -0
- package/dist/client/_fonts/DfgmjWGpWte3Q3a54Nevr_BYmMM5YEJXRI1CdI2VwO0-ox5RadQfCyVTmKl_hubTaIJjtRw9oaQz2GDBeZR6l1M.woff2 +0 -0
- package/dist/client/_fonts/LK8hREFNeTe-EIzvbfgusJBg3CJ7Q7NFgYIiGb2LZ8-qiyWl0ATLJjOsRPZC_7a8mTMFxEMKEv6JTK_kHtMzbM.woff2 +0 -0
- package/dist/client/_fonts/Lc_5lWuBuZcZ166p1-s-mnGkMJwIYJE_QDCkws8iCkI-r45Qbm2hCykrfOZ0kowz__uTTTUOPDN9hz34QcRNTY4.woff2 +0 -0
- package/dist/client/_fonts/UBlOS9e0BmJuiF5yVs0YcJrFWaa-iN8zx9TP_lmKs8c-iH3Naewt5UjJ0AQ38QZs4lkEo4zdjMIVkLs4y7EiwIE.woff2 +0 -0
- package/dist/client/_fonts/gRxGIWazSFZVyzU0s62U9IArK3RJLkOoUmXx0C8Npsw-kMFNQG6iwjw2nvqS3ut9jMSVn__HlJ28slvxjE4hYfc.woff2 +0 -0
- package/dist/client/_fonts/hIKtJJBMNYGPUppSYZpyuF6c24cKhBkhsgaCTgzYgqw-jRJyBPlfGDXClyrgfO6GK_Pfs1RmTsB-wWX6MOgpsRA.woff2 +0 -0
- package/dist/client/_fonts/iEvApgDRmzKzNqOYocBTrmcHZmuGAJloawKDP1S0nyE-T3oc_9We24QGwfw5naik4cM0g7VxylWVaQwKm4dy3cw.woff2 +0 -0
- package/dist/client/_fonts/kokcBTWRechd97ZdVUpUxrOFbsRt8whO21yA1vQ6iJ8-O7CCbVvFgg_MFLTdyFF9FMeMvIoEmxJLubqVDYTUoWY.woff2 +0 -0
- package/dist/client/_fonts/oFzdhjQtZFydTZ757bmiVFXgReR2bBSYm_CjQ7B1Jjs-F6oFbDhOWKYJbgrlC93wkLkPlIV7mzgvqwqEDxQMeHA.woff2 +0 -0
- package/dist/client/_nuxt/0kYTU2a7.js +2 -0
- package/dist/client/_nuxt/BBvImjI6.js +3 -0
- package/dist/client/_nuxt/BMajWU4Q.js +2 -0
- package/dist/client/_nuxt/BUylUlrk.js +1 -0
- package/dist/client/_nuxt/BUzwbfnX.js +1 -0
- package/dist/client/_nuxt/CA8OCsNm.js +3864 -0
- package/dist/client/_nuxt/Ce8yDyoA.js +1 -0
- package/dist/client/_nuxt/CiQnSy_v.js +1 -0
- package/dist/client/_nuxt/D9eL2h5z.js +1 -0
- package/dist/client/_nuxt/DVnX3Z-O.js +1 -0
- package/dist/client/_nuxt/DjZxf_BC.js +1 -0
- package/dist/client/_nuxt/E3Kc5QfQ.js +1 -0
- package/dist/client/_nuxt/E8AZ6HoH.js +1 -0
- package/dist/client/_nuxt/IFrameLoader.Dg-moXnW.css +1 -0
- package/dist/client/_nuxt/OSectionBlock.BVHnMsIr.css +1 -0
- package/dist/client/_nuxt/PONEy9N-.js +1 -0
- package/dist/client/_nuxt/YkGyFdfd.js +184 -0
- package/dist/client/_nuxt/builds/latest.json +1 -1
- package/dist/client/_nuxt/builds/meta/a06e3266-ba0a-4e03-b47a-d6b5db57c89e.json +1 -0
- package/dist/client/_nuxt/entry.Dk6lX-P7.css +2 -0
- package/dist/client/_nuxt/error-404.5HU6rnuR.css +1 -0
- package/dist/client/_nuxt/error-500.CFwtvM7B.css +1 -0
- package/dist/client/_nuxt/pages.-2MlM8jh.css +1 -0
- package/dist/client/_nuxt/templates.DxDxFWm_.css +1 -0
- package/dist/client/_payload.json +1 -0
- package/dist/client/debug/_payload.json +1 -0
- package/dist/client/debug/index.html +1 -0
- package/dist/client/docs/_payload.json +1 -0
- package/dist/client/docs/index.html +1 -0
- package/dist/client/index.html +1 -1
- package/dist/client/templates/_payload.json +1 -0
- package/dist/client/templates/index.html +1 -0
- package/dist/module.cjs +34 -1027
- package/dist/module.d.cts +68 -25
- package/dist/module.d.mts +68 -25
- package/dist/module.d.ts +68 -25
- package/dist/module.json +1 -1
- package/dist/module.mjs +30 -1009
- package/dist/runtime/app/components/Templates/Community/Brutalist.satori.d.vue.ts +14 -0
- package/dist/runtime/app/components/Templates/Community/Brutalist.satori.vue +50 -0
- package/dist/runtime/app/components/Templates/Community/Brutalist.satori.vue.d.ts +14 -0
- package/dist/runtime/app/components/Templates/Community/{Frame.vue.d.ts → Frame.satori.d.vue.ts} +2 -2
- package/dist/runtime/app/components/Templates/Community/Frame.satori.vue +71 -0
- package/dist/runtime/app/components/Templates/Community/{Frame.d.vue.ts → Frame.satori.vue.d.ts} +2 -2
- package/dist/runtime/app/components/Templates/Community/Newspaper.satori.d.vue.ts +12 -0
- package/dist/runtime/app/components/Templates/Community/Newspaper.satori.vue +70 -0
- package/dist/runtime/app/components/Templates/Community/Newspaper.satori.vue.d.ts +12 -0
- package/dist/runtime/app/components/Templates/Community/Nuxt.satori.d.vue.ts +12 -0
- package/dist/runtime/app/components/Templates/Community/{Nuxt.vue → Nuxt.satori.vue} +4 -4
- package/dist/runtime/app/components/Templates/Community/Nuxt.satori.vue.d.ts +12 -0
- package/dist/runtime/app/components/Templates/Community/NuxtSeo.satori.d.vue.ts +12 -0
- package/dist/runtime/app/components/Templates/Community/NuxtSeo.satori.vue +66 -0
- package/dist/runtime/app/components/Templates/Community/NuxtSeo.satori.vue.d.ts +12 -0
- package/dist/runtime/app/components/Templates/Community/NuxtSeo.takumi.d.vue.ts +12 -0
- package/dist/runtime/app/components/Templates/Community/NuxtSeo.takumi.vue +72 -0
- package/dist/runtime/app/components/Templates/Community/NuxtSeo.takumi.vue.d.ts +12 -0
- package/dist/runtime/app/components/Templates/Community/Pergel.satori.d.vue.ts +12 -0
- package/dist/runtime/app/components/Templates/Community/{Pergel.vue → Pergel.satori.vue} +14 -11
- package/dist/runtime/app/components/Templates/Community/Pergel.satori.vue.d.ts +12 -0
- package/dist/runtime/app/components/Templates/Community/Retro.satori.d.vue.ts +12 -0
- package/dist/runtime/app/components/Templates/Community/Retro.satori.vue +64 -0
- package/dist/runtime/app/components/Templates/Community/Retro.satori.vue.d.ts +12 -0
- package/dist/runtime/app/components/Templates/Community/SaaS.satori.d.vue.ts +12 -0
- package/dist/runtime/app/components/Templates/Community/SaaS.satori.vue +60 -0
- package/dist/runtime/app/components/Templates/Community/SaaS.satori.vue.d.ts +12 -0
- package/dist/runtime/app/components/Templates/Community/SimpleBlog.satori.d.vue.ts +9 -0
- package/dist/runtime/app/components/Templates/Community/SimpleBlog.satori.vue +38 -0
- package/dist/runtime/app/components/Templates/Community/SimpleBlog.satori.vue.d.ts +9 -0
- package/dist/runtime/app/components/Templates/Community/{UnJs.d.vue.ts → UnJs.satori.d.vue.ts} +2 -2
- package/dist/runtime/app/components/Templates/Community/{UnJs.vue → UnJs.satori.vue} +41 -33
- package/dist/runtime/app/components/Templates/Community/{UnJs.vue.d.ts → UnJs.satori.vue.d.ts} +2 -2
- package/dist/runtime/app/components/Templates/Community/WithEmoji.satori.d.vue.ts +13 -0
- package/dist/runtime/app/components/Templates/Community/WithEmoji.satori.vue +27 -0
- package/dist/runtime/app/components/Templates/Community/WithEmoji.satori.vue.d.ts +13 -0
- package/dist/runtime/app/composables/_defineOgImageRaw.d.ts +6 -0
- package/dist/runtime/app/composables/_defineOgImageRaw.js +84 -0
- package/dist/runtime/app/composables/defineOgImage.d.ts +14 -2
- package/dist/runtime/app/composables/defineOgImage.js +13 -42
- package/dist/runtime/app/composables/defineOgImageComponent.d.ts +5 -1
- package/dist/runtime/app/composables/defineOgImageComponent.js +4 -5
- package/dist/runtime/app/composables/defineOgImageScreenshot.d.ts +1 -1
- package/dist/runtime/app/composables/defineOgImageScreenshot.js +2 -2
- package/dist/runtime/app/composables/mock.d.ts +7 -4
- package/dist/runtime/app/composables/mock.js +4 -4
- package/dist/runtime/app/utils/plugins.js +22 -28
- package/dist/runtime/app/utils.d.ts +15 -1
- package/dist/runtime/app/utils.js +74 -46
- package/dist/runtime/public/_og-fonts/inter-400-latin.ttf +0 -0
- package/dist/runtime/public/_og-fonts/inter-700-latin.ttf +0 -0
- package/dist/runtime/pure.d.ts +7 -0
- package/dist/runtime/pure.js +106 -0
- package/dist/runtime/server/og-image/bindings/chromium/on-demand.js +14 -22
- package/dist/runtime/server/og-image/bindings/css-inline/wasm-fs.d.ts +3 -2
- package/dist/runtime/server/og-image/bindings/css-inline/wasm.d.ts +3 -2
- package/dist/runtime/server/og-image/bindings/font-assets/cloudflare.d.ts +3 -0
- package/dist/runtime/server/og-image/bindings/font-assets/cloudflare.js +23 -0
- package/dist/runtime/server/og-image/bindings/font-assets/dev-prerender.d.ts +3 -0
- package/dist/runtime/server/og-image/bindings/font-assets/dev-prerender.js +63 -0
- package/dist/runtime/server/og-image/bindings/font-assets/node.d.ts +3 -0
- package/dist/runtime/server/og-image/bindings/font-assets/node.js +14 -0
- package/dist/runtime/server/og-image/bindings/resvg/node-dev.d.ts +5 -0
- package/dist/runtime/server/og-image/bindings/resvg/node-dev.js +70 -0
- package/dist/runtime/server/og-image/bindings/satori/0-15-wasm.d.ts +6 -0
- package/dist/runtime/server/og-image/bindings/satori/0-15-wasm.js +10 -0
- package/dist/runtime/server/og-image/bindings/satori/wasm.js +2 -2
- package/dist/runtime/server/og-image/bindings/takumi/node.d.ts +6 -0
- package/dist/runtime/server/og-image/bindings/takumi/node.js +5 -0
- package/dist/runtime/server/og-image/bindings/takumi/wasm.d.ts +6 -0
- package/dist/runtime/server/og-image/bindings/takumi/wasm.js +6 -0
- package/dist/runtime/server/og-image/cache/buildCache.d.ts +16 -0
- package/dist/runtime/server/og-image/cache/buildCache.js +48 -0
- package/dist/runtime/server/og-image/cache/lru.d.ts +2 -2
- package/dist/runtime/server/og-image/cache/lru.js +3 -3
- package/dist/runtime/server/og-image/cache/mock.d.ts +1 -2
- package/dist/runtime/server/og-image/cache/mock.js +0 -1
- package/dist/runtime/server/og-image/chromium/screenshot.js +4 -3
- package/dist/runtime/server/og-image/context.d.ts +2 -3
- package/dist/runtime/server/og-image/context.js +58 -205
- package/dist/runtime/server/og-image/devtools.d.ts +10 -0
- package/dist/runtime/server/og-image/devtools.js +74 -0
- package/dist/runtime/server/og-image/fonts.d.ts +13 -0
- package/dist/runtime/server/og-image/fonts.js +59 -0
- package/dist/runtime/server/og-image/instances.d.ts +1 -0
- package/dist/runtime/server/og-image/instances.js +5 -0
- package/dist/runtime/server/og-image/satori/instances.d.ts +1 -36
- package/dist/runtime/server/og-image/satori/plugins/emojis.js +127 -4
- package/dist/runtime/server/og-image/satori/plugins/encoding.js +11 -1
- package/dist/runtime/server/og-image/satori/plugins/flex.js +1 -1
- package/dist/runtime/server/og-image/satori/plugins/imageSrc.js +5 -1
- package/dist/runtime/server/og-image/satori/plugins/twClasses.js +55 -0
- package/dist/runtime/server/og-image/satori/renderer.js +16 -53
- package/dist/runtime/server/og-image/satori/transforms/emojis/emoji-names-minimal.d.ts +1 -0
- package/dist/runtime/server/og-image/satori/transforms/emojis/emoji-names-minimal.js +223 -0
- package/dist/runtime/server/og-image/satori/transforms/emojis/emoji-utils.d.ts +45 -0
- package/dist/runtime/server/og-image/satori/transforms/emojis/emoji-utils.js +13 -0
- package/dist/runtime/server/og-image/satori/transforms/emojis/fetch.d.ts +6 -0
- package/dist/runtime/server/og-image/satori/transforms/emojis/fetch.js +39 -0
- package/dist/runtime/server/og-image/satori/transforms/emojis/index.d.ts +7 -0
- package/dist/runtime/server/og-image/satori/transforms/emojis/index.js +64 -0
- package/dist/runtime/server/og-image/satori/transforms/emojis/local.d.ts +26 -0
- package/dist/runtime/server/og-image/satori/transforms/emojis/local.js +38 -0
- package/dist/runtime/server/og-image/satori/transforms/emojis/noop.d.ts +4 -0
- package/dist/runtime/server/og-image/satori/transforms/emojis/noop.js +3 -0
- package/dist/runtime/server/og-image/satori/utils.js +6 -5
- package/dist/runtime/server/og-image/satori/vnodes.js +67 -9
- package/dist/runtime/server/og-image/takumi/instances.d.ts +1 -0
- package/dist/runtime/server/og-image/takumi/instances.js +6 -0
- package/dist/runtime/server/og-image/takumi/nodes.d.ts +12 -0
- package/dist/runtime/server/og-image/takumi/nodes.js +95 -0
- package/dist/runtime/server/og-image/takumi/renderer.d.ts +3 -0
- package/dist/runtime/server/og-image/takumi/renderer.js +93 -0
- package/dist/runtime/server/og-image/templates/html.js +46 -30
- package/dist/runtime/server/plugins/prerender.d.ts +1 -1
- package/dist/runtime/server/plugins/prerender.js +17 -7
- package/dist/runtime/server/routes/debug.json.d.ts +2 -0
- package/dist/runtime/server/routes/debug.json.js +7 -3
- package/dist/runtime/server/util/auto-eject.d.ts +4 -0
- package/dist/runtime/server/util/auto-eject.js +33 -0
- package/dist/runtime/server/util/eventHandlers.d.ts +0 -1
- package/dist/runtime/server/util/eventHandlers.js +23 -87
- package/dist/runtime/server/util/options.d.ts +7 -2
- package/dist/runtime/server/util/options.js +79 -12
- package/dist/runtime/server/utils.d.ts +6 -2
- package/dist/runtime/server/utils.js +12 -8
- package/dist/runtime/shared/urlEncoding.d.ts +64 -0
- package/dist/runtime/shared/urlEncoding.js +194 -0
- package/dist/runtime/shared.d.ts +4 -9
- package/dist/runtime/shared.js +32 -50
- package/dist/runtime/types.d.ts +88 -28
- package/dist/shared/nuxt-og-image.DJ4fZgE4.cjs +3550 -0
- package/dist/shared/nuxt-og-image.vDJ3zH1b.mjs +3525 -0
- package/dist/types.d.mts +2 -0
- package/package.json +112 -46
- package/types/virtual.d.ts +20 -1
- package/dist/client/_nuxt/B3LgXoKV.js +0 -2
- package/dist/client/_nuxt/B8PEiB0p.js +0 -1
- package/dist/client/_nuxt/CPsbVDfV.js +0 -1
- package/dist/client/_nuxt/CVO1_9PV.js +0 -1
- package/dist/client/_nuxt/CjQm5wk3.js +0 -4029
- package/dist/client/_nuxt/Cp-IABpG.js +0 -1
- package/dist/client/_nuxt/D0TMZt8T.js +0 -1
- package/dist/client/_nuxt/D0r3Knsf.js +0 -1
- package/dist/client/_nuxt/builds/meta/eb2c0390-3125-4af7-b189-e76a7dfe3017.json +0 -1
- package/dist/client/_nuxt/entry.cdy4VsCK.css +0 -1
- package/dist/client/_nuxt/error-404.Cu4JbXd7.css +0 -1
- package/dist/client/_nuxt/error-500.B79uceR7.css +0 -1
- package/dist/runtime/app/components/OgImage/OgImage.d.ts +0 -3
- package/dist/runtime/app/components/OgImage/OgImage.js +0 -10
- package/dist/runtime/app/components/Templates/Community/BrandedLogo.d.vue.ts +0 -13
- package/dist/runtime/app/components/Templates/Community/BrandedLogo.vue +0 -22
- package/dist/runtime/app/components/Templates/Community/BrandedLogo.vue.d.ts +0 -13
- package/dist/runtime/app/components/Templates/Community/Frame.vue +0 -58
- package/dist/runtime/app/components/Templates/Community/Nuxt.d.vue.ts +0 -12
- package/dist/runtime/app/components/Templates/Community/Nuxt.vue.d.ts +0 -12
- package/dist/runtime/app/components/Templates/Community/NuxtSeo.d.vue.ts +0 -15
- package/dist/runtime/app/components/Templates/Community/NuxtSeo.vue +0 -103
- package/dist/runtime/app/components/Templates/Community/NuxtSeo.vue.d.ts +0 -15
- package/dist/runtime/app/components/Templates/Community/Pergel.d.vue.ts +0 -12
- package/dist/runtime/app/components/Templates/Community/Pergel.vue.d.ts +0 -12
- package/dist/runtime/app/components/Templates/Community/SimpleBlog.d.vue.ts +0 -9
- package/dist/runtime/app/components/Templates/Community/SimpleBlog.vue +0 -27
- package/dist/runtime/app/components/Templates/Community/SimpleBlog.vue.d.ts +0 -9
- package/dist/runtime/app/components/Templates/Community/Wave.d.vue.ts +0 -11
- package/dist/runtime/app/components/Templates/Community/Wave.vue +0 -28
- package/dist/runtime/app/components/Templates/Community/Wave.vue.d.ts +0 -11
- package/dist/runtime/app/components/Templates/Community/WithEmoji.d.vue.ts +0 -13
- package/dist/runtime/app/components/Templates/Community/WithEmoji.vue +0 -21
- package/dist/runtime/app/components/Templates/Community/WithEmoji.vue.d.ts +0 -13
- package/dist/runtime/assets/Inter-normal-400.ttf.base64 +0 -1
- package/dist/runtime/assets/Inter-normal-700.ttf.base64 +0 -1
- package/dist/runtime/server/og-image/satori/font.d.ts +0 -3
- package/dist/runtime/server/og-image/satori/font.js +0 -40
- package/dist/runtime/server/og-image/satori/plugins/unocss.js +0 -55
- package/dist/runtime/server/og-image/satori/transforms/emojis.d.ts +0 -3
- package/dist/runtime/server/og-image/satori/transforms/emojis.js +0 -3595
- package/dist/runtime/server/plugins/__zero-runtime/nuxt-content-v2.d.ts +0 -2
- package/dist/runtime/server/plugins/__zero-runtime/nuxt-content-v2.js +0 -9
- package/dist/runtime/server/plugins/nuxt-content-v2.d.ts +0 -2
- package/dist/runtime/server/plugins/nuxt-content-v2.js +0 -5
- package/dist/runtime/server/routes/__zero-runtime/font.d.ts +0 -2
- package/dist/runtime/server/routes/__zero-runtime/font.js +0 -8
- package/dist/runtime/server/routes/font.d.ts +0 -2
- package/dist/runtime/server/routes/font.js +0 -3
- package/dist/runtime/server/util/plugins.d.ts +0 -2
- package/dist/runtime/server/util/plugins.js +0 -56
- /package/dist/runtime/server/og-image/satori/plugins/{unocss.d.ts → twClasses.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -28,7 +28,7 @@ need this module.
|
|
|
28
28
|
|
|
29
29
|
- ✨ Create an `og:image` using the built-in templates or make your own with Vue components
|
|
30
30
|
- 🎨 Design and test your `og:image` in the Nuxt DevTools OG Image Playground with full HMR
|
|
31
|
-
- ▲ Render using [Satori](https://github.com/vercel/satori): Tailwind / UnoCSS with your theme, Google fonts, 6 emoji families
|
|
31
|
+
- ▲ Render using [Satori](https://github.com/vercel/satori) or [Takumi](https://github.com/kane50613/takumi): Tailwind / UnoCSS with your theme, Google fonts, 6 emoji families and more!
|
|
32
32
|
- 🤖 Or prerender using the Browser: Supporting painless, complex templates
|
|
33
33
|
- 📸 Feeling lazy? Just generate screenshots for every page: hide elements, wait for animations, and more
|
|
34
34
|
- ⚙️ Works on the edge: Vercel Edge, Netlify Edge and Cloudflare Workers
|
package/bin/cli.mjs
ADDED
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const fs = require('node:fs');
|
|
4
|
+
const promises = require('node:fs/promises');
|
|
5
|
+
const pathe = require('pathe');
|
|
6
|
+
const module$1 = require('../shared/nuxt-og-image.DJ4fZgE4.cjs');
|
|
7
|
+
require('@nuxt/kit');
|
|
8
|
+
require('defu');
|
|
9
|
+
require('jiti');
|
|
10
|
+
require('nuxt-site-config/kit');
|
|
11
|
+
require('ohash');
|
|
12
|
+
require('pkg-types');
|
|
13
|
+
require('std-env');
|
|
14
|
+
require('node:crypto');
|
|
15
|
+
require('../../dist/runtime/logger.js');
|
|
16
|
+
require('chrome-launcher');
|
|
17
|
+
require('exsolve');
|
|
18
|
+
require('tailwindcss/colors');
|
|
19
|
+
require('culori');
|
|
20
|
+
require('node:path');
|
|
21
|
+
require('@nuxt/devtools-kit');
|
|
22
|
+
require('node:url');
|
|
23
|
+
require('magic-string');
|
|
24
|
+
require('strip-literal');
|
|
25
|
+
require('ufo');
|
|
26
|
+
require('unplugin');
|
|
27
|
+
require('ofetch');
|
|
28
|
+
require('../../dist/runtime/server/og-image/satori/transforms/emojis/emoji-utils.js');
|
|
29
|
+
require('@vue/compiler-sfc');
|
|
30
|
+
require('magicast');
|
|
31
|
+
require('magicast/helpers');
|
|
32
|
+
require('nypm');
|
|
33
|
+
|
|
34
|
+
let parseSfc;
|
|
35
|
+
async function loadParser() {
|
|
36
|
+
if (!parseSfc)
|
|
37
|
+
parseSfc = (await import('@vue/compiler-sfc')).parse;
|
|
38
|
+
return parseSfc;
|
|
39
|
+
}
|
|
40
|
+
const FONT_WEIGHT_CLASSES = {
|
|
41
|
+
"font-thin": 100,
|
|
42
|
+
"font-extralight": 200,
|
|
43
|
+
"font-light": 300,
|
|
44
|
+
"font-normal": 400,
|
|
45
|
+
"font-medium": 500,
|
|
46
|
+
"font-semibold": 600,
|
|
47
|
+
"font-bold": 700,
|
|
48
|
+
"font-extrabold": 800,
|
|
49
|
+
"font-black": 900
|
|
50
|
+
};
|
|
51
|
+
const INLINE_FONT_WEIGHT_REGEX = /font-weight:\s*(\d+)/g;
|
|
52
|
+
const ELEMENT_NODE = 1;
|
|
53
|
+
const ATTRIBUTE_NODE = 6;
|
|
54
|
+
const DIRECTIVE_NODE = 7;
|
|
55
|
+
async function extractClassesFromVue(code) {
|
|
56
|
+
const parse = await loadParser();
|
|
57
|
+
const { descriptor } = parse(code);
|
|
58
|
+
if (!descriptor.template?.ast)
|
|
59
|
+
return [];
|
|
60
|
+
const classes = [];
|
|
61
|
+
module$1.walkTemplateAst(descriptor.template.ast.children, (node) => {
|
|
62
|
+
if (node.type !== ELEMENT_NODE)
|
|
63
|
+
return;
|
|
64
|
+
const el = node;
|
|
65
|
+
for (const prop of el.props) {
|
|
66
|
+
if (prop.type === ATTRIBUTE_NODE && prop.name === "class" && prop.value) {
|
|
67
|
+
for (const cls of prop.value.content.split(/\s+/)) {
|
|
68
|
+
if (cls && !cls.includes("{") && !cls.includes("$"))
|
|
69
|
+
classes.push(cls);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (prop.type === DIRECTIVE_NODE && prop.name === "bind" && prop.arg?.type === 4 && prop.arg.content === "class") {
|
|
73
|
+
const expr = prop.exp;
|
|
74
|
+
if (expr?.type === 4) {
|
|
75
|
+
const content = expr.content;
|
|
76
|
+
extractClassesFromExpression(content, classes);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
return classes;
|
|
82
|
+
}
|
|
83
|
+
function extractClassesFromExpression(expr, classes) {
|
|
84
|
+
for (const match of expr.matchAll(/['"`]([\w:.\-/]+)['"`]/g)) {
|
|
85
|
+
const cls = match[1];
|
|
86
|
+
if (cls && !cls.includes("{") && !cls.includes("$") && !cls.includes("/"))
|
|
87
|
+
classes.push(cls);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
async function scanComponentClasses(components, logger, cacheDir) {
|
|
91
|
+
const classes = /* @__PURE__ */ new Set();
|
|
92
|
+
const cacheFile = cacheDir ? pathe.join(cacheDir, "cache", "og-image", "css-classes.json") : null;
|
|
93
|
+
let cache = { files: {} };
|
|
94
|
+
if (cacheFile && fs.existsSync(cacheFile)) {
|
|
95
|
+
cache = await promises.readFile(cacheFile, "utf-8").then((c) => JSON.parse(c)).catch(() => ({ files: {} }));
|
|
96
|
+
}
|
|
97
|
+
const seenKeys = /* @__PURE__ */ new Set();
|
|
98
|
+
const seenPaths = /* @__PURE__ */ new Set();
|
|
99
|
+
let cacheHits = 0;
|
|
100
|
+
let cacheMisses = 0;
|
|
101
|
+
for (const component of components) {
|
|
102
|
+
if (!component.path)
|
|
103
|
+
continue;
|
|
104
|
+
if (seenPaths.has(component.path))
|
|
105
|
+
continue;
|
|
106
|
+
seenPaths.add(component.path);
|
|
107
|
+
const cacheKey = component.hash || component.path;
|
|
108
|
+
seenKeys.add(cacheKey);
|
|
109
|
+
const cached = cache.files[cacheKey];
|
|
110
|
+
if (cached) {
|
|
111
|
+
cacheHits++;
|
|
112
|
+
for (const cls of cached)
|
|
113
|
+
classes.add(cls);
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
cacheMisses++;
|
|
117
|
+
logger?.debug(`CSS: Scanning component ${component.path}`);
|
|
118
|
+
const content = await promises.readFile(component.path, "utf-8").catch(() => null);
|
|
119
|
+
if (!content) {
|
|
120
|
+
cache.files[cacheKey] = [];
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
const fileClasses = await extractClassesFromVue(content);
|
|
124
|
+
cache.files[cacheKey] = fileClasses;
|
|
125
|
+
for (const cls of fileClasses)
|
|
126
|
+
classes.add(cls);
|
|
127
|
+
}
|
|
128
|
+
for (const key of Object.keys(cache.files)) {
|
|
129
|
+
if (!seenKeys.has(key))
|
|
130
|
+
delete cache.files[key];
|
|
131
|
+
}
|
|
132
|
+
if (cacheFile) {
|
|
133
|
+
const cacheParent = pathe.join(cacheDir, "cache", "og-image");
|
|
134
|
+
fs.mkdirSync(cacheParent, { recursive: true });
|
|
135
|
+
await promises.writeFile(cacheFile, JSON.stringify(cache));
|
|
136
|
+
}
|
|
137
|
+
if (cacheHits > 0 || cacheMisses > 0)
|
|
138
|
+
logger?.debug(`CSS: Class cache - ${cacheHits} hits, ${cacheMisses} misses`);
|
|
139
|
+
return classes;
|
|
140
|
+
}
|
|
141
|
+
function filterProcessableClasses(classes) {
|
|
142
|
+
const processable = [];
|
|
143
|
+
const responsivePrefixes = ["sm:", "md:", "lg:", "xl:", "2xl:"];
|
|
144
|
+
for (const cls of classes) {
|
|
145
|
+
if (responsivePrefixes.some((p) => cls.startsWith(p))) {
|
|
146
|
+
const baseClass = cls.replace(/^(sm|md|lg|xl|2xl):/, "");
|
|
147
|
+
if (baseClass)
|
|
148
|
+
processable.push(baseClass);
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
if (cls.includes("hover:") || cls.includes("focus:") || cls.includes("active:"))
|
|
152
|
+
continue;
|
|
153
|
+
if (cls.startsWith("dark:"))
|
|
154
|
+
continue;
|
|
155
|
+
processable.push(cls);
|
|
156
|
+
}
|
|
157
|
+
return [...new Set(processable)];
|
|
158
|
+
}
|
|
159
|
+
async function extractFontRequirementsFromVue(code) {
|
|
160
|
+
const parse = await loadParser();
|
|
161
|
+
const { descriptor } = parse(code);
|
|
162
|
+
const weights = /* @__PURE__ */ new Set();
|
|
163
|
+
const styles = /* @__PURE__ */ new Set(["normal"]);
|
|
164
|
+
let isComplete = true;
|
|
165
|
+
if (!descriptor.template?.ast)
|
|
166
|
+
return { weights, styles, isComplete };
|
|
167
|
+
module$1.walkTemplateAst(descriptor.template.ast.children, (node) => {
|
|
168
|
+
if (node.type !== ELEMENT_NODE)
|
|
169
|
+
return;
|
|
170
|
+
const el = node;
|
|
171
|
+
for (const prop of el.props) {
|
|
172
|
+
if (prop.type === ATTRIBUTE_NODE && prop.name === "class" && prop.value) {
|
|
173
|
+
for (const cls of prop.value.content.split(/\s+/)) {
|
|
174
|
+
extractFontWeightFromClass(cls, weights, styles);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
if (prop.type === ATTRIBUTE_NODE && prop.name === "style" && prop.value) {
|
|
178
|
+
extractFontWeightFromStyle(prop.value.content, weights, styles);
|
|
179
|
+
}
|
|
180
|
+
if (prop.type === DIRECTIVE_NODE && prop.name === "bind" && prop.arg?.type === 4) {
|
|
181
|
+
const argContent = prop.arg.content;
|
|
182
|
+
const expr = prop.exp;
|
|
183
|
+
if (argContent === "class" && expr?.type === 4) {
|
|
184
|
+
const content = expr.content;
|
|
185
|
+
if (content.includes("props.") || content.includes("$props") || /\bfont(?:Weight|-weight)\b/i.test(content)) {
|
|
186
|
+
isComplete = false;
|
|
187
|
+
}
|
|
188
|
+
for (const match of content.matchAll(/['"`]([\w:.\-]+)['"`]/g)) {
|
|
189
|
+
extractFontWeightFromClass(match[1], weights, styles);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
if (argContent === "style" && expr?.type === 4) {
|
|
193
|
+
const content = expr.content;
|
|
194
|
+
if (/font-?weight/i.test(content) && (content.includes("props.") || content.includes("$props") || content.includes("?"))) {
|
|
195
|
+
isComplete = false;
|
|
196
|
+
}
|
|
197
|
+
extractFontWeightFromStyle(content, weights, styles);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
return { weights, styles, isComplete };
|
|
203
|
+
}
|
|
204
|
+
function extractFontWeightFromClass(cls, weights, styles) {
|
|
205
|
+
const baseClass = cls.replace(/^(?:sm:|md:|lg:|xl:|2xl:|dark:|hover:|focus:|active:)+/, "");
|
|
206
|
+
const weight = FONT_WEIGHT_CLASSES[baseClass];
|
|
207
|
+
if (weight !== void 0) {
|
|
208
|
+
weights.add(weight);
|
|
209
|
+
}
|
|
210
|
+
if (baseClass === "italic") {
|
|
211
|
+
styles.add("italic");
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
function extractFontWeightFromStyle(style, weights, styles) {
|
|
215
|
+
for (const match of style.matchAll(INLINE_FONT_WEIGHT_REGEX)) {
|
|
216
|
+
const weight = Number.parseInt(match[1], 10);
|
|
217
|
+
if (weight >= 100 && weight <= 900) {
|
|
218
|
+
weights.add(weight);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
if (/font-style:\s*italic/i.test(style)) {
|
|
222
|
+
styles.add("italic");
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
async function scanFontRequirements(components, logger, cacheDir) {
|
|
226
|
+
const allWeights = /* @__PURE__ */ new Set();
|
|
227
|
+
const allStyles = /* @__PURE__ */ new Set(["normal"]);
|
|
228
|
+
let isComplete = true;
|
|
229
|
+
const componentMap = {};
|
|
230
|
+
const cacheFile = cacheDir ? pathe.join(cacheDir, "cache", "og-image", "font-requirements.json") : null;
|
|
231
|
+
let cache = { files: {} };
|
|
232
|
+
if (cacheFile && fs.existsSync(cacheFile)) {
|
|
233
|
+
cache = await promises.readFile(cacheFile, "utf-8").then((c) => JSON.parse(c)).catch(() => ({ files: {} }));
|
|
234
|
+
}
|
|
235
|
+
const seenKeys = /* @__PURE__ */ new Set();
|
|
236
|
+
const seenPaths = /* @__PURE__ */ new Set();
|
|
237
|
+
for (const component of components) {
|
|
238
|
+
if (!component.path)
|
|
239
|
+
continue;
|
|
240
|
+
if (seenPaths.has(component.path))
|
|
241
|
+
continue;
|
|
242
|
+
seenPaths.add(component.path);
|
|
243
|
+
const cacheKey = component.hash || component.path;
|
|
244
|
+
seenKeys.add(cacheKey);
|
|
245
|
+
const cached = cache.files[cacheKey];
|
|
246
|
+
if (cached) {
|
|
247
|
+
for (const w of cached.weights) allWeights.add(w);
|
|
248
|
+
for (const s of cached.styles) allStyles.add(s);
|
|
249
|
+
if (!cached.isComplete)
|
|
250
|
+
isComplete = false;
|
|
251
|
+
const compWeights2 = cached.weights.length ? [...cached.weights] : [400];
|
|
252
|
+
if (!compWeights2.includes(400))
|
|
253
|
+
compWeights2.push(400);
|
|
254
|
+
componentMap[component.pascalName] = {
|
|
255
|
+
weights: compWeights2.sort((a, b) => a - b),
|
|
256
|
+
styles: [...cached.styles],
|
|
257
|
+
isComplete: cached.isComplete
|
|
258
|
+
};
|
|
259
|
+
continue;
|
|
260
|
+
}
|
|
261
|
+
const content = await promises.readFile(component.path, "utf-8").catch(() => null);
|
|
262
|
+
if (!content) {
|
|
263
|
+
cache.files[cacheKey] = { weights: [], styles: ["normal"], isComplete: true };
|
|
264
|
+
componentMap[component.pascalName] = { weights: [400], styles: ["normal"], isComplete: true };
|
|
265
|
+
continue;
|
|
266
|
+
}
|
|
267
|
+
const result = await extractFontRequirementsFromVue(content);
|
|
268
|
+
cache.files[cacheKey] = {
|
|
269
|
+
weights: [...result.weights],
|
|
270
|
+
styles: [...result.styles],
|
|
271
|
+
isComplete: result.isComplete
|
|
272
|
+
};
|
|
273
|
+
for (const w of result.weights) allWeights.add(w);
|
|
274
|
+
for (const s of result.styles) allStyles.add(s);
|
|
275
|
+
if (!result.isComplete)
|
|
276
|
+
isComplete = false;
|
|
277
|
+
const compWeights = [...result.weights];
|
|
278
|
+
if (!compWeights.includes(400))
|
|
279
|
+
compWeights.push(400);
|
|
280
|
+
componentMap[component.pascalName] = {
|
|
281
|
+
weights: compWeights.sort((a, b) => a - b),
|
|
282
|
+
styles: [...result.styles],
|
|
283
|
+
isComplete: result.isComplete
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
for (const key of Object.keys(cache.files)) {
|
|
287
|
+
if (!seenKeys.has(key))
|
|
288
|
+
delete cache.files[key];
|
|
289
|
+
}
|
|
290
|
+
if (cacheFile) {
|
|
291
|
+
const cacheParent = pathe.join(cacheDir, "cache", "og-image");
|
|
292
|
+
fs.mkdirSync(cacheParent, { recursive: true });
|
|
293
|
+
await promises.writeFile(cacheFile, JSON.stringify(cache));
|
|
294
|
+
}
|
|
295
|
+
allWeights.add(400);
|
|
296
|
+
const weights = [...allWeights].sort((a, b) => a - b);
|
|
297
|
+
const styles = [...allStyles];
|
|
298
|
+
logger?.debug(`Fonts: Detected weights [${weights.join(", ")}], styles [${styles.join(", ")}]${isComplete ? "" : " (incomplete analysis)"}`);
|
|
299
|
+
return {
|
|
300
|
+
global: { weights, styles, isComplete },
|
|
301
|
+
components: componentMap
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
exports.filterProcessableClasses = filterProcessableClasses;
|
|
306
|
+
exports.scanComponentClasses = scanComponentClasses;
|
|
307
|
+
exports.scanFontRequirements = scanFontRequirements;
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
import { existsSync, mkdirSync } from 'node:fs';
|
|
2
|
+
import { readFile, writeFile } from 'node:fs/promises';
|
|
3
|
+
import { join } from 'pathe';
|
|
4
|
+
import { w as walkTemplateAst } from '../shared/nuxt-og-image.vDJ3zH1b.mjs';
|
|
5
|
+
import '@nuxt/kit';
|
|
6
|
+
import 'defu';
|
|
7
|
+
import 'jiti';
|
|
8
|
+
import 'nuxt-site-config/kit';
|
|
9
|
+
import 'ohash';
|
|
10
|
+
import 'pkg-types';
|
|
11
|
+
import 'std-env';
|
|
12
|
+
import 'node:crypto';
|
|
13
|
+
import '../../dist/runtime/logger.js';
|
|
14
|
+
import 'chrome-launcher';
|
|
15
|
+
import 'exsolve';
|
|
16
|
+
import 'tailwindcss/colors';
|
|
17
|
+
import 'culori';
|
|
18
|
+
import 'node:path';
|
|
19
|
+
import '@nuxt/devtools-kit';
|
|
20
|
+
import 'node:url';
|
|
21
|
+
import 'magic-string';
|
|
22
|
+
import 'strip-literal';
|
|
23
|
+
import 'ufo';
|
|
24
|
+
import 'unplugin';
|
|
25
|
+
import 'ofetch';
|
|
26
|
+
import '../../dist/runtime/server/og-image/satori/transforms/emojis/emoji-utils.js';
|
|
27
|
+
import '@vue/compiler-sfc';
|
|
28
|
+
import 'magicast';
|
|
29
|
+
import 'magicast/helpers';
|
|
30
|
+
import 'nypm';
|
|
31
|
+
|
|
32
|
+
let parseSfc;
|
|
33
|
+
async function loadParser() {
|
|
34
|
+
if (!parseSfc)
|
|
35
|
+
parseSfc = (await import('@vue/compiler-sfc')).parse;
|
|
36
|
+
return parseSfc;
|
|
37
|
+
}
|
|
38
|
+
const FONT_WEIGHT_CLASSES = {
|
|
39
|
+
"font-thin": 100,
|
|
40
|
+
"font-extralight": 200,
|
|
41
|
+
"font-light": 300,
|
|
42
|
+
"font-normal": 400,
|
|
43
|
+
"font-medium": 500,
|
|
44
|
+
"font-semibold": 600,
|
|
45
|
+
"font-bold": 700,
|
|
46
|
+
"font-extrabold": 800,
|
|
47
|
+
"font-black": 900
|
|
48
|
+
};
|
|
49
|
+
const INLINE_FONT_WEIGHT_REGEX = /font-weight:\s*(\d+)/g;
|
|
50
|
+
const ELEMENT_NODE = 1;
|
|
51
|
+
const ATTRIBUTE_NODE = 6;
|
|
52
|
+
const DIRECTIVE_NODE = 7;
|
|
53
|
+
async function extractClassesFromVue(code) {
|
|
54
|
+
const parse = await loadParser();
|
|
55
|
+
const { descriptor } = parse(code);
|
|
56
|
+
if (!descriptor.template?.ast)
|
|
57
|
+
return [];
|
|
58
|
+
const classes = [];
|
|
59
|
+
walkTemplateAst(descriptor.template.ast.children, (node) => {
|
|
60
|
+
if (node.type !== ELEMENT_NODE)
|
|
61
|
+
return;
|
|
62
|
+
const el = node;
|
|
63
|
+
for (const prop of el.props) {
|
|
64
|
+
if (prop.type === ATTRIBUTE_NODE && prop.name === "class" && prop.value) {
|
|
65
|
+
for (const cls of prop.value.content.split(/\s+/)) {
|
|
66
|
+
if (cls && !cls.includes("{") && !cls.includes("$"))
|
|
67
|
+
classes.push(cls);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
if (prop.type === DIRECTIVE_NODE && prop.name === "bind" && prop.arg?.type === 4 && prop.arg.content === "class") {
|
|
71
|
+
const expr = prop.exp;
|
|
72
|
+
if (expr?.type === 4) {
|
|
73
|
+
const content = expr.content;
|
|
74
|
+
extractClassesFromExpression(content, classes);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
return classes;
|
|
80
|
+
}
|
|
81
|
+
function extractClassesFromExpression(expr, classes) {
|
|
82
|
+
for (const match of expr.matchAll(/['"`]([\w:.\-/]+)['"`]/g)) {
|
|
83
|
+
const cls = match[1];
|
|
84
|
+
if (cls && !cls.includes("{") && !cls.includes("$") && !cls.includes("/"))
|
|
85
|
+
classes.push(cls);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
async function scanComponentClasses(components, logger, cacheDir) {
|
|
89
|
+
const classes = /* @__PURE__ */ new Set();
|
|
90
|
+
const cacheFile = cacheDir ? join(cacheDir, "cache", "og-image", "css-classes.json") : null;
|
|
91
|
+
let cache = { files: {} };
|
|
92
|
+
if (cacheFile && existsSync(cacheFile)) {
|
|
93
|
+
cache = await readFile(cacheFile, "utf-8").then((c) => JSON.parse(c)).catch(() => ({ files: {} }));
|
|
94
|
+
}
|
|
95
|
+
const seenKeys = /* @__PURE__ */ new Set();
|
|
96
|
+
const seenPaths = /* @__PURE__ */ new Set();
|
|
97
|
+
let cacheHits = 0;
|
|
98
|
+
let cacheMisses = 0;
|
|
99
|
+
for (const component of components) {
|
|
100
|
+
if (!component.path)
|
|
101
|
+
continue;
|
|
102
|
+
if (seenPaths.has(component.path))
|
|
103
|
+
continue;
|
|
104
|
+
seenPaths.add(component.path);
|
|
105
|
+
const cacheKey = component.hash || component.path;
|
|
106
|
+
seenKeys.add(cacheKey);
|
|
107
|
+
const cached = cache.files[cacheKey];
|
|
108
|
+
if (cached) {
|
|
109
|
+
cacheHits++;
|
|
110
|
+
for (const cls of cached)
|
|
111
|
+
classes.add(cls);
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
cacheMisses++;
|
|
115
|
+
logger?.debug(`CSS: Scanning component ${component.path}`);
|
|
116
|
+
const content = await readFile(component.path, "utf-8").catch(() => null);
|
|
117
|
+
if (!content) {
|
|
118
|
+
cache.files[cacheKey] = [];
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
const fileClasses = await extractClassesFromVue(content);
|
|
122
|
+
cache.files[cacheKey] = fileClasses;
|
|
123
|
+
for (const cls of fileClasses)
|
|
124
|
+
classes.add(cls);
|
|
125
|
+
}
|
|
126
|
+
for (const key of Object.keys(cache.files)) {
|
|
127
|
+
if (!seenKeys.has(key))
|
|
128
|
+
delete cache.files[key];
|
|
129
|
+
}
|
|
130
|
+
if (cacheFile) {
|
|
131
|
+
const cacheParent = join(cacheDir, "cache", "og-image");
|
|
132
|
+
mkdirSync(cacheParent, { recursive: true });
|
|
133
|
+
await writeFile(cacheFile, JSON.stringify(cache));
|
|
134
|
+
}
|
|
135
|
+
if (cacheHits > 0 || cacheMisses > 0)
|
|
136
|
+
logger?.debug(`CSS: Class cache - ${cacheHits} hits, ${cacheMisses} misses`);
|
|
137
|
+
return classes;
|
|
138
|
+
}
|
|
139
|
+
function filterProcessableClasses(classes) {
|
|
140
|
+
const processable = [];
|
|
141
|
+
const responsivePrefixes = ["sm:", "md:", "lg:", "xl:", "2xl:"];
|
|
142
|
+
for (const cls of classes) {
|
|
143
|
+
if (responsivePrefixes.some((p) => cls.startsWith(p))) {
|
|
144
|
+
const baseClass = cls.replace(/^(sm|md|lg|xl|2xl):/, "");
|
|
145
|
+
if (baseClass)
|
|
146
|
+
processable.push(baseClass);
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
if (cls.includes("hover:") || cls.includes("focus:") || cls.includes("active:"))
|
|
150
|
+
continue;
|
|
151
|
+
if (cls.startsWith("dark:"))
|
|
152
|
+
continue;
|
|
153
|
+
processable.push(cls);
|
|
154
|
+
}
|
|
155
|
+
return [...new Set(processable)];
|
|
156
|
+
}
|
|
157
|
+
async function extractFontRequirementsFromVue(code) {
|
|
158
|
+
const parse = await loadParser();
|
|
159
|
+
const { descriptor } = parse(code);
|
|
160
|
+
const weights = /* @__PURE__ */ new Set();
|
|
161
|
+
const styles = /* @__PURE__ */ new Set(["normal"]);
|
|
162
|
+
let isComplete = true;
|
|
163
|
+
if (!descriptor.template?.ast)
|
|
164
|
+
return { weights, styles, isComplete };
|
|
165
|
+
walkTemplateAst(descriptor.template.ast.children, (node) => {
|
|
166
|
+
if (node.type !== ELEMENT_NODE)
|
|
167
|
+
return;
|
|
168
|
+
const el = node;
|
|
169
|
+
for (const prop of el.props) {
|
|
170
|
+
if (prop.type === ATTRIBUTE_NODE && prop.name === "class" && prop.value) {
|
|
171
|
+
for (const cls of prop.value.content.split(/\s+/)) {
|
|
172
|
+
extractFontWeightFromClass(cls, weights, styles);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
if (prop.type === ATTRIBUTE_NODE && prop.name === "style" && prop.value) {
|
|
176
|
+
extractFontWeightFromStyle(prop.value.content, weights, styles);
|
|
177
|
+
}
|
|
178
|
+
if (prop.type === DIRECTIVE_NODE && prop.name === "bind" && prop.arg?.type === 4) {
|
|
179
|
+
const argContent = prop.arg.content;
|
|
180
|
+
const expr = prop.exp;
|
|
181
|
+
if (argContent === "class" && expr?.type === 4) {
|
|
182
|
+
const content = expr.content;
|
|
183
|
+
if (content.includes("props.") || content.includes("$props") || /\bfont(?:Weight|-weight)\b/i.test(content)) {
|
|
184
|
+
isComplete = false;
|
|
185
|
+
}
|
|
186
|
+
for (const match of content.matchAll(/['"`]([\w:.\-]+)['"`]/g)) {
|
|
187
|
+
extractFontWeightFromClass(match[1], weights, styles);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
if (argContent === "style" && expr?.type === 4) {
|
|
191
|
+
const content = expr.content;
|
|
192
|
+
if (/font-?weight/i.test(content) && (content.includes("props.") || content.includes("$props") || content.includes("?"))) {
|
|
193
|
+
isComplete = false;
|
|
194
|
+
}
|
|
195
|
+
extractFontWeightFromStyle(content, weights, styles);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
return { weights, styles, isComplete };
|
|
201
|
+
}
|
|
202
|
+
function extractFontWeightFromClass(cls, weights, styles) {
|
|
203
|
+
const baseClass = cls.replace(/^(?:sm:|md:|lg:|xl:|2xl:|dark:|hover:|focus:|active:)+/, "");
|
|
204
|
+
const weight = FONT_WEIGHT_CLASSES[baseClass];
|
|
205
|
+
if (weight !== void 0) {
|
|
206
|
+
weights.add(weight);
|
|
207
|
+
}
|
|
208
|
+
if (baseClass === "italic") {
|
|
209
|
+
styles.add("italic");
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
function extractFontWeightFromStyle(style, weights, styles) {
|
|
213
|
+
for (const match of style.matchAll(INLINE_FONT_WEIGHT_REGEX)) {
|
|
214
|
+
const weight = Number.parseInt(match[1], 10);
|
|
215
|
+
if (weight >= 100 && weight <= 900) {
|
|
216
|
+
weights.add(weight);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
if (/font-style:\s*italic/i.test(style)) {
|
|
220
|
+
styles.add("italic");
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
async function scanFontRequirements(components, logger, cacheDir) {
|
|
224
|
+
const allWeights = /* @__PURE__ */ new Set();
|
|
225
|
+
const allStyles = /* @__PURE__ */ new Set(["normal"]);
|
|
226
|
+
let isComplete = true;
|
|
227
|
+
const componentMap = {};
|
|
228
|
+
const cacheFile = cacheDir ? join(cacheDir, "cache", "og-image", "font-requirements.json") : null;
|
|
229
|
+
let cache = { files: {} };
|
|
230
|
+
if (cacheFile && existsSync(cacheFile)) {
|
|
231
|
+
cache = await readFile(cacheFile, "utf-8").then((c) => JSON.parse(c)).catch(() => ({ files: {} }));
|
|
232
|
+
}
|
|
233
|
+
const seenKeys = /* @__PURE__ */ new Set();
|
|
234
|
+
const seenPaths = /* @__PURE__ */ new Set();
|
|
235
|
+
for (const component of components) {
|
|
236
|
+
if (!component.path)
|
|
237
|
+
continue;
|
|
238
|
+
if (seenPaths.has(component.path))
|
|
239
|
+
continue;
|
|
240
|
+
seenPaths.add(component.path);
|
|
241
|
+
const cacheKey = component.hash || component.path;
|
|
242
|
+
seenKeys.add(cacheKey);
|
|
243
|
+
const cached = cache.files[cacheKey];
|
|
244
|
+
if (cached) {
|
|
245
|
+
for (const w of cached.weights) allWeights.add(w);
|
|
246
|
+
for (const s of cached.styles) allStyles.add(s);
|
|
247
|
+
if (!cached.isComplete)
|
|
248
|
+
isComplete = false;
|
|
249
|
+
const compWeights2 = cached.weights.length ? [...cached.weights] : [400];
|
|
250
|
+
if (!compWeights2.includes(400))
|
|
251
|
+
compWeights2.push(400);
|
|
252
|
+
componentMap[component.pascalName] = {
|
|
253
|
+
weights: compWeights2.sort((a, b) => a - b),
|
|
254
|
+
styles: [...cached.styles],
|
|
255
|
+
isComplete: cached.isComplete
|
|
256
|
+
};
|
|
257
|
+
continue;
|
|
258
|
+
}
|
|
259
|
+
const content = await readFile(component.path, "utf-8").catch(() => null);
|
|
260
|
+
if (!content) {
|
|
261
|
+
cache.files[cacheKey] = { weights: [], styles: ["normal"], isComplete: true };
|
|
262
|
+
componentMap[component.pascalName] = { weights: [400], styles: ["normal"], isComplete: true };
|
|
263
|
+
continue;
|
|
264
|
+
}
|
|
265
|
+
const result = await extractFontRequirementsFromVue(content);
|
|
266
|
+
cache.files[cacheKey] = {
|
|
267
|
+
weights: [...result.weights],
|
|
268
|
+
styles: [...result.styles],
|
|
269
|
+
isComplete: result.isComplete
|
|
270
|
+
};
|
|
271
|
+
for (const w of result.weights) allWeights.add(w);
|
|
272
|
+
for (const s of result.styles) allStyles.add(s);
|
|
273
|
+
if (!result.isComplete)
|
|
274
|
+
isComplete = false;
|
|
275
|
+
const compWeights = [...result.weights];
|
|
276
|
+
if (!compWeights.includes(400))
|
|
277
|
+
compWeights.push(400);
|
|
278
|
+
componentMap[component.pascalName] = {
|
|
279
|
+
weights: compWeights.sort((a, b) => a - b),
|
|
280
|
+
styles: [...result.styles],
|
|
281
|
+
isComplete: result.isComplete
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
for (const key of Object.keys(cache.files)) {
|
|
285
|
+
if (!seenKeys.has(key))
|
|
286
|
+
delete cache.files[key];
|
|
287
|
+
}
|
|
288
|
+
if (cacheFile) {
|
|
289
|
+
const cacheParent = join(cacheDir, "cache", "og-image");
|
|
290
|
+
mkdirSync(cacheParent, { recursive: true });
|
|
291
|
+
await writeFile(cacheFile, JSON.stringify(cache));
|
|
292
|
+
}
|
|
293
|
+
allWeights.add(400);
|
|
294
|
+
const weights = [...allWeights].sort((a, b) => a - b);
|
|
295
|
+
const styles = [...allStyles];
|
|
296
|
+
logger?.debug(`Fonts: Detected weights [${weights.join(", ")}], styles [${styles.join(", ")}]${isComplete ? "" : " (incomplete analysis)"}`);
|
|
297
|
+
return {
|
|
298
|
+
global: { weights, styles, isComplete },
|
|
299
|
+
components: componentMap
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
export { filterProcessableClasses, scanComponentClasses, scanFontRequirements };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const exsolve = require('exsolve');
|
|
4
|
+
|
|
5
|
+
function detectCssProvider(nuxt) {
|
|
6
|
+
const modules = nuxt.options.modules.flat();
|
|
7
|
+
if (modules.some((m) => typeof m === "string" && m.includes("@unocss/nuxt")))
|
|
8
|
+
return "unocss";
|
|
9
|
+
if (exsolve.resolveModulePath("tailwindcss", { from: nuxt.options.rootDir }))
|
|
10
|
+
return "tailwind";
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
exports.detectCssProvider = detectCssProvider;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { resolveModulePath } from 'exsolve';
|
|
2
|
+
|
|
3
|
+
function detectCssProvider(nuxt) {
|
|
4
|
+
const modules = nuxt.options.modules.flat();
|
|
5
|
+
if (modules.some((m) => typeof m === "string" && m.includes("@unocss/nuxt")))
|
|
6
|
+
return "unocss";
|
|
7
|
+
if (resolveModulePath("tailwindcss", { from: nuxt.options.rootDir }))
|
|
8
|
+
return "tailwind";
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export { detectCssProvider };
|