nuxt-og-image 7.0.1 → 7.0.3

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.
@@ -2,7 +2,7 @@ import { readFile } from 'node:fs/promises';
2
2
  import { pathToFileURL } from 'node:url';
3
3
  import { resolveModulePath } from 'exsolve';
4
4
  import { dirname, join } from 'pathe';
5
- import { e as extractVariantBaseClasses, r as resolveVariantPrefixes, h as resolveExtractedVars, l as resolveVarsDeep, s as simplifyCss, p as postProcessStyles, m as loadLightningCss, a as extractCssVars, c as extractUniversalVars, d as extractPerClassVars, g as extractVarsFromCss, f as extractClassStyles } from '../shared/nuxt-og-image.DR_SxdDv.mjs';
5
+ import { e as extractVariantBaseClasses, r as resolveVariantPrefixes, h as resolveExtractedVars, l as resolveVarsDeep, s as simplifyCss, p as postProcessStyles, m as loadLightningCss, a as extractCssVars, c as extractUniversalVars, d as extractPerClassVars, g as extractVarsFromCss, f as extractClassStyles } from '../shared/nuxt-og-image.B5ZhjIiR.mjs';
6
6
  import 'node:fs';
7
7
  import 'node:module';
8
8
  import '@nuxt/kit';
@@ -225,7 +225,7 @@ async function parseCssOutput(rawCss, vars, extractedAccum) {
225
225
  if (!extractedAccum.rootVars.has(n))
226
226
  extractedAccum.rootVars.set(n, v);
227
227
  }
228
- extractedAccum.qualifiedRules.push(...fresh.qualifiedRules);
228
+ extractedAccum.qualifiedRules = fresh.qualifiedRules;
229
229
  for (const [n, v] of fresh.universalVars) {
230
230
  if (!extractedAccum.universalVars.has(n))
231
231
  extractedAccum.universalVars.set(n, v);
@@ -254,7 +254,16 @@ const LINEAR_GRADIENT_DIRECTIONS = {
254
254
  "bg-gradient-to-b": "to bottom",
255
255
  "bg-gradient-to-bl": "to bottom left",
256
256
  "bg-gradient-to-l": "to left",
257
- "bg-gradient-to-tl": "to top left"
257
+ "bg-gradient-to-tl": "to top left",
258
+ // Tailwind v4 names
259
+ "bg-linear-to-t": "to top",
260
+ "bg-linear-to-tr": "to top right",
261
+ "bg-linear-to-r": "to right",
262
+ "bg-linear-to-br": "to bottom right",
263
+ "bg-linear-to-b": "to bottom",
264
+ "bg-linear-to-bl": "to bottom left",
265
+ "bg-linear-to-l": "to left",
266
+ "bg-linear-to-tl": "to top left"
258
267
  };
259
268
  const RADIAL_GRADIENT_SHAPES = {
260
269
  "bg-radial": "circle at center",
@@ -268,32 +277,31 @@ const RADIAL_GRADIENT_SHAPES = {
268
277
  "bg-radial-at-tl": "circle at top left",
269
278
  "bg-radial-at-c": "circle at center"
270
279
  };
271
- async function resolveGradientColor(cls, vars) {
280
+ async function toGradientColor(value, vars) {
281
+ const resolved = await resolveVarsDeep(value, vars);
282
+ if (resolved.includes("var("))
283
+ return null;
284
+ const simplified = await simplifyCss(`.x{color:${resolved}}`);
285
+ return simplified.match(RE_CSS_COLOR_VALUE)?.[1]?.trim() ?? resolved;
286
+ }
287
+ async function resolveGradientColor(cls, vars, classVars) {
272
288
  const colorName = cls.replace(RE_GRADIENT_STOP_PREFIX, "");
273
289
  const shadeMatch = colorName.match(RE_COLOR_SHADE);
274
290
  if (shadeMatch?.[1] && shadeMatch?.[2]) {
275
- const varName2 = `--color-${shadeMatch[1]}-${shadeMatch[2]}`;
276
- const value2 = vars.get(varName2);
277
- if (value2) {
278
- const resolved = await resolveVarsDeep(value2, vars);
279
- if (!resolved.includes("var(")) {
280
- const simplified = await simplifyCss(`.x{color:${resolved}}`);
281
- return simplified.match(RE_CSS_COLOR_VALUE)?.[1]?.trim() ?? resolved;
282
- }
283
- }
291
+ const value2 = vars.get(`--color-${shadeMatch[1]}-${shadeMatch[2]}`);
292
+ const color2 = value2 ? await toGradientColor(value2, vars) : null;
293
+ if (color2)
294
+ return color2;
284
295
  }
285
- const varName = `--color-${colorName}`;
286
- const value = vars.get(varName);
287
- if (value) {
288
- const resolved = await resolveVarsDeep(value, vars);
289
- if (!resolved.includes("var(")) {
290
- const simplified = await simplifyCss(`.x{color:${resolved}}`);
291
- return simplified.match(RE_CSS_COLOR_VALUE)?.[1]?.trim() ?? resolved;
292
- }
293
- }
294
- return null;
296
+ const value = vars.get(`--color-${colorName}`);
297
+ const color = value ? await toGradientColor(value, vars) : null;
298
+ if (color)
299
+ return color;
300
+ const stop = cls.match(RE_GRADIENT_STOP_PREFIX)?.[1];
301
+ const own = stop ? classVars?.get(`--tw-gradient-${stop}`) : void 0;
302
+ return own ? toGradientColor(own, vars) : null;
295
303
  }
296
- async function buildGradient(classes, vars) {
304
+ async function buildGradient(classes, vars, perClassVars) {
297
305
  const linearDir = classes.find((c) => LINEAR_GRADIENT_DIRECTIONS[c]);
298
306
  const radialShape = classes.find((c) => RADIAL_GRADIENT_SHAPES[c]);
299
307
  const fromClass = classes.find((c) => c.startsWith("from-"));
@@ -303,9 +311,9 @@ async function buildGradient(classes, vars) {
303
311
  return null;
304
312
  if (!fromClass && !toClass)
305
313
  return null;
306
- const fromColor = fromClass ? await resolveGradientColor(fromClass, vars) : null;
307
- const viaColor = viaClass ? await resolveGradientColor(viaClass, vars) : null;
308
- const toColor = toClass ? await resolveGradientColor(toClass, vars) : null;
314
+ const fromColor = fromClass ? await resolveGradientColor(fromClass, vars, perClassVars?.get(fromClass)) : null;
315
+ const viaColor = viaClass ? await resolveGradientColor(viaClass, vars, perClassVars?.get(viaClass)) : null;
316
+ const toColor = toClass ? await resolveGradientColor(toClass, vars, perClassVars?.get(toClass)) : null;
309
317
  if (!fromColor && !toColor)
310
318
  return null;
311
319
  const stops = [fromColor, viaColor, toColor].filter(Boolean).join(", ");
@@ -348,21 +356,20 @@ async function resolveClassesToStyles(classes, options, context, theme) {
348
356
  const outputCss = compiler.build(uncached);
349
357
  const { classes: parsedClasses, perClassVars } = await parseCssOutput(outputCss, vars, cachedExtractedVars || void 0);
350
358
  const resolveVarsForClass = theme ? buildThemeVars(vars, cachedExtractedVars, theme, options.nuxtUiColors) : vars;
351
- for (const [className, rawStyles] of parsedClasses) {
352
- const classVars = perClassVars.get(className);
353
- const mergedVars = classVars ? new Map([...resolveVarsForClass, ...classVars]) : resolveVarsForClass;
354
- const styles = await postProcessStyles(rawStyles, mergedVars, void 0, context);
359
+ for (const className of uncached) {
355
360
  const cacheKey = cacheKeyFor(className);
356
- if (!styles && className.startsWith("bg-gradient-")) {
357
- resolvedStyleCache.set(cacheKey, rawStyles);
358
- } else {
359
- resolvedStyleCache.set(cacheKey, styles);
361
+ const rawStyles = parsedClasses.get(className);
362
+ if (!rawStyles) {
363
+ resolvedStyleCache.set(cacheKey, null);
364
+ continue;
360
365
  }
361
- }
362
- for (const c of uncached) {
363
- const key = cacheKeyFor(c);
364
- if (!resolvedStyleCache.has(key))
365
- resolvedStyleCache.set(key, null);
366
+ if (LINEAR_GRADIENT_DIRECTIONS[className] || RADIAL_GRADIENT_SHAPES[className]) {
367
+ resolvedStyleCache.set(cacheKey, {});
368
+ continue;
369
+ }
370
+ const classVars = perClassVars.get(className);
371
+ const mergedVars = classVars ? new Map([...resolveVarsForClass, ...classVars]) : resolveVarsForClass;
372
+ resolvedStyleCache.set(cacheKey, await postProcessStyles(rawStyles, mergedVars, void 0, context));
366
373
  }
367
374
  }
368
375
  const result = {};
@@ -372,7 +379,7 @@ async function resolveClassesToStyles(classes, options, context, theme) {
372
379
  result[cls] = resolved;
373
380
  }
374
381
  const gradientVars = theme ? buildThemeVars(vars, cachedExtractedVars, theme, options.nuxtUiColors) : vars;
375
- const gradient = await buildGradient(classes, gradientVars);
382
+ const gradient = await buildGradient(classes, gradientVars, cachedExtractedVars?.perClassVars);
376
383
  if (gradient) {
377
384
  result[gradient.gradientClass] = { "background-image": gradient.value };
378
385
  for (const colorClass of gradient.colorClasses) {
@@ -1,8 +1,8 @@
1
1
  import { readFile } from 'node:fs/promises';
2
2
  import { defu } from 'defu';
3
3
  import { logger } from '../../dist/runtime/logger.js';
4
- import { e as extractVariantBaseClasses, s as simplifyCss, a as extractCssVars, b as extractPropertyInitialValues, c as extractUniversalVars, d as extractPerClassVars, f as extractClassStyles, p as postProcessStyles, r as resolveVariantPrefixes, i as importOptionalPeer, g as extractVarsFromCss, h as resolveExtractedVars } from '../shared/nuxt-og-image.DR_SxdDv.mjs';
5
- export { j as importResolvedModule, k as resolveOptionalModulePath } from '../shared/nuxt-og-image.DR_SxdDv.mjs';
4
+ import { e as extractVariantBaseClasses, s as simplifyCss, a as extractCssVars, b as extractPropertyInitialValues, c as extractUniversalVars, d as extractPerClassVars, f as extractClassStyles, p as postProcessStyles, r as resolveVariantPrefixes, i as importOptionalPeer, g as extractVarsFromCss, h as resolveExtractedVars } from '../shared/nuxt-og-image.B5ZhjIiR.mjs';
5
+ export { j as importResolvedModule, k as resolveOptionalModulePath } from '../shared/nuxt-og-image.B5ZhjIiR.mjs';
6
6
  import 'node:fs';
7
7
  import 'node:module';
8
8
  import 'node:url';
package/dist/module.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "nuxt": "^4.6.1 || ^5.0.0-0"
5
5
  },
6
6
  "configKey": "ogImage",
7
- "version": "7.0.1",
7
+ "version": "7.0.3",
8
8
  "builder": {
9
9
  "@nuxt/module-builder": "1.0.3",
10
10
  "unbuild": "3.6.1"
package/dist/module.mjs CHANGED
@@ -7,7 +7,7 @@ import 'defu';
7
7
  import 'fnv1a-64';
8
8
  import 'nuxtseo-shared/kit';
9
9
  import 'pathe';
10
- export { n as default } from './shared/nuxt-og-image.DR_SxdDv.mjs';
10
+ export { n as default } from './shared/nuxt-og-image.B5ZhjIiR.mjs';
11
11
  import '../dist/runtime/logger.js';
12
12
  import '../dist/runtime/shared/publish.js';
13
13
  import 'node:crypto';
@@ -83,13 +83,13 @@ export function clientProcessOgImageOptions(input, route, basePath) {
83
83
  if (validOptions.url) {
84
84
  const url = validOptions.url;
85
85
  const absoluteUrl = /^https?:\/\//.test(url) ? url : toValue(resolveImageUrl(url));
86
- registerClientOgHead(ogKey, { meta: generateMeta(absoluteUrl, validOptions, metaOptions) }, { tagPriority: "high" });
86
+ registerClientOgHead(ogKey, { meta: generateMeta(absoluteUrl, validOptions, metaOptions) });
87
87
  paths.push(url);
88
88
  continue;
89
89
  }
90
90
  if (hasServerRuntime) {
91
91
  const finalUrl2 = buildResolverUrl(baseURL, basePath, ogKey, route.query);
92
- registerClientOgHead(ogKey, { meta: generateMeta(toValue(resolveImageUrl(finalUrl2)), validOptions, metaOptions) }, { tagPriority: "high" });
92
+ registerClientOgHead(ogKey, { meta: generateMeta(toValue(resolveImageUrl(finalUrl2)), validOptions, metaOptions) });
93
93
  paths.push(finalUrl2);
94
94
  continue;
95
95
  }
@@ -105,7 +105,7 @@ export function clientProcessOgImageOptions(input, route, basePath) {
105
105
  const query = opts._query && Object.keys(opts._query).length ? { _query: opts._query } : {};
106
106
  const finalUrl = withQuery(resolvedUrl, query);
107
107
  const imageUrl = rc.app.cdnURL ? withQuery(joinURL(rc.app.cdnURL, result.url), query) : toValue(resolveImageUrl(finalUrl));
108
- registerClientOgHead(ogKey, { meta: generateMeta(imageUrl, opts, metaOptions) }, { processTemplateParams: true, tagPriority: "high" });
108
+ registerClientOgHead(ogKey, { meta: generateMeta(imageUrl, opts, metaOptions) }, { processTemplateParams: true });
109
109
  paths.push(finalUrl);
110
110
  }
111
111
  return paths;
@@ -58,7 +58,7 @@ export function setHeadOgImagePrebuilt(input) {
58
58
  const urlValue = toValue(url);
59
59
  const absoluteUrl = /^https?:\/\//.test(urlValue) ? urlValue : toValue(withSiteUrl(urlValue, { withBase: true, canonical: !import.meta.dev }));
60
60
  const meta = generateMeta(absoluteUrl, input, { includeTwitter });
61
- useHead({ meta }, { tagPriority: "high" });
61
+ useHead({ meta });
62
62
  }
63
63
  export function createOgImageMeta(src, input, ssrContext, pagePath, head) {
64
64
  if (import.meta.client) {
@@ -126,8 +126,7 @@ export function createOgImageMeta(src, input, ssrContext, pagePath, head) {
126
126
  });
127
127
  }
128
128
  }, {
129
- processTemplateParams: true,
130
- tagPriority: "high"
129
+ processTemplateParams: true
131
130
  });
132
131
  if (import.meta.dev || import.meta.prerender) {
133
132
  ssrContext._ogImageDevtoolsInstance?.dispose();
@@ -9,7 +9,7 @@ export function generateMeta(url, resolvedOptions, metaOptions = {}) {
9
9
  const includeTwitter = (key === "og" || key === "twitter") && metaOptions.includeTwitter !== false;
10
10
  const meta = [];
11
11
  if (includeTwitter) {
12
- meta.push({ name: "twitter:card", content: "summary_large_image" });
12
+ meta.push({ name: "twitter:card", content: "summary_large_image", tagPriority: "low" });
13
13
  meta.push({ name: "twitter:image", content: url });
14
14
  }
15
15
  if (!isTwitterOnly) {
@@ -30,6 +30,8 @@ export function generateMeta(url, resolvedOptions, metaOptions = {}) {
30
30
  if (includeTwitter)
31
31
  meta.push({ name: "twitter:image:alt", content: resolvedOptions.alt });
32
32
  }
33
+ for (const tag of meta)
34
+ tag.tagPriority ??= "high";
33
35
  return meta;
34
36
  }
35
37
  export function isInternalRoute(path) {
@@ -671,7 +671,7 @@ const RE_CSS_DECL = /([\w-]+)\s*:\s*([^\s;][^;]*)(?:;|$)/g;
671
671
  const RE_CSS_TOGGLE = /(--[\w-]+)\s*:\s+;/g;
672
672
  const RE_CSS_CLASS_RULE = /\.((?:\\[0-9a-f]{1,6}\s?|\\[^0-9a-f]|[^\\\s{])+)\s*\{([^}]+)\}/gi;
673
673
  const RE_ROOT_HOST_BLOCK = /:(?:root|host)[^\s{]*\s*\{([^}]+)\}/g;
674
- const RE_UNIVERSAL_BLOCK = /\*[^{]*\{([^}]+)\}/g;
674
+ const RE_UNIVERSAL_BLOCK = /(?:^|[{};])\s*\*[^{};]*\{([^{}]+)\}/g;
675
675
  const RE_PROPERTY_AT_RULE = /@property\s+(--[\w-]+)\s*\{([^}]+)\}/g;
676
676
  const RE_INITIAL_VALUE = /initial-value\s*:\s*([^\s;][^;]*);?/;
677
677
  const RE_CSS_ESCAPE_HEX = /\\([0-9a-f]{1,6})\s?/gi;
@@ -1112,15 +1112,24 @@ async function extractVarsFromCss(css) {
1112
1112
  }
1113
1113
  return { rootVars, qualifiedRules, universalVars, propertyInitials, perClassVars };
1114
1114
  }
1115
+ const MAX_VAR_SUBSTITUTIONS = 100;
1115
1116
  function resolveCssVars(css, vars) {
1116
1117
  let result = css;
1117
- let iterations = 0;
1118
- while (result.includes("var(") && iterations < 20) {
1119
- const next = resolveInnermostVar(result, vars);
1120
- if (next === result)
1118
+ let cursor = result.length;
1119
+ for (let substitutions = 0; substitutions < MAX_VAR_SUBSTITUTIONS; ) {
1120
+ const idx = result.lastIndexOf("var(", cursor);
1121
+ if (idx === -1)
1121
1122
  break;
1122
- result = next;
1123
- iterations++;
1123
+ const resolved = substituteVar(result, idx, vars);
1124
+ if (resolved === void 0) {
1125
+ if (idx === 0)
1126
+ break;
1127
+ cursor = idx - 1;
1128
+ continue;
1129
+ }
1130
+ result = result.substring(0, idx) + resolved.value + result.substring(resolved.end);
1131
+ cursor = idx + resolved.value.length;
1132
+ substitutions++;
1124
1133
  }
1125
1134
  return result;
1126
1135
  }
@@ -1136,23 +1145,19 @@ function findClosingParen(str, startIdx) {
1136
1145
  }
1137
1146
  return -1;
1138
1147
  }
1139
- function resolveInnermostVar(css, vars) {
1140
- const idx = css.lastIndexOf("var(");
1141
- if (idx === -1)
1142
- return css;
1148
+ function substituteVar(css, idx, vars) {
1143
1149
  const closeIdx = findClosingParen(css, idx + 4);
1144
1150
  if (closeIdx === -1)
1145
- return css;
1151
+ return void 0;
1146
1152
  const content = css.substring(idx + 4, closeIdx);
1147
- if (content.includes("var("))
1148
- return css;
1149
1153
  const comma = content.indexOf(",");
1150
1154
  const name = (comma >= 0 ? content.substring(0, comma) : content).trim();
1151
1155
  const fallback = comma >= 0 ? content.substring(comma + 1).trim() : void 0;
1152
- const resolved = vars.get(name) ?? fallback;
1156
+ const value = vars.get(name);
1157
+ const resolved = value !== void 0 && value.trim() !== "initial" ? value : fallback;
1153
1158
  if (resolved === void 0)
1154
- return css;
1155
- return css.substring(0, idx) + resolved + css.substring(closeIdx + 1);
1159
+ return void 0;
1160
+ return { value: resolved, end: closeIdx + 1 };
1156
1161
  }
1157
1162
  function decodeCssClassName(selector) {
1158
1163
  let className = selector.startsWith(".") ? selector.slice(1) : selector;
@@ -2907,6 +2912,7 @@ function getMissingSiteUrlWarning(input) {
2907
2912
  function setupPrerenderHandler(options, resolve, getDetectedRenderers, nuxt = useNuxt()) {
2908
2913
  nuxt.hooks.hook("nitro:init", async (nitro) => {
2909
2914
  nitro.hooks.hook("prerender:config", async (nitroConfig) => {
2915
+ nitroConfig.plugins = [...nitroConfig.plugins || [], resolve.resolve("./runtime/server/plugins/prerender")];
2910
2916
  await applyNitroPresetCompatibility(nitroConfig, { compatibility: options.compatibility?.prerender, resolve, detectedRenderers: getDetectedRenderers() });
2911
2917
  nitroConfig.wasm = nitroConfig.wasm || {};
2912
2918
  nitroConfig.wasm.esmImport = false;
@@ -6399,8 +6405,6 @@ export const staticFontCacheDir = ${JSON.stringify(getStaticFontCacheDir(nuxt.op
6399
6405
  nuxt.options.nitro.virtual["#og-image-virtual/signing.mjs"] = () => `export const rendersImages = ${getDetectedRenderers().size > 0}`;
6400
6406
  addServerHandler({ middleware: true, handler: resolve("./runtime/server/middleware/signing") });
6401
6407
  }
6402
- if (nuxt.options.build)
6403
- addServerPlugin(resolve("./runtime/server/plugins/prerender"));
6404
6408
  if (nuxt.options.build && config.publish && !config.zeroRuntime)
6405
6409
  addServerPlugin(resolve("./runtime/server/plugins/publish"));
6406
6410
  if (nuxt.options.dev)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "nuxt-og-image",
3
3
  "type": "module",
4
- "version": "7.0.1",
4
+ "version": "7.0.3",
5
5
  "description": "Enlightened OG Image generation for Nuxt.",
6
6
  "author": {
7
7
  "website": "https://harlanzw.com",