nuxt-og-image 6.3.7 → 6.3.9
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/dist/chunks/tw4.cjs +1 -1
- package/dist/chunks/tw4.mjs +1 -1
- package/dist/chunks/uno.cjs +1 -1
- package/dist/chunks/uno.mjs +1 -1
- package/dist/cli.cjs +1 -0
- package/dist/cli.mjs +1 -0
- package/dist/devtools/200.html +1 -1
- package/dist/devtools/404.html +1 -1
- package/dist/devtools/_nuxt/{D6HqPJ2P.js → B1vWG-dr.js} +1 -1
- package/dist/devtools/_nuxt/{DO62csGn.js → B4O-Ri_H.js} +1 -1
- package/dist/devtools/_nuxt/{DJOUfd_s.js → B4pt0d5N.js} +1 -1
- package/dist/devtools/_nuxt/{C4ssBbxk.js → C-BKEkNl.js} +6 -6
- package/dist/devtools/_nuxt/{Dgwhb1xi.js → C-rB6lUS.js} +1 -1
- package/dist/devtools/_nuxt/{Dn8E1mDk.js → CFv1BN3Z.js} +1 -1
- package/dist/devtools/_nuxt/{DggwDRkJ.js → DOBkniDZ.js} +1 -1
- package/dist/devtools/_nuxt/DevtoolsSection.BkXKwKS6.css +1 -0
- package/dist/devtools/_nuxt/DevtoolsSnippet.CiX5uaV5.css +1 -0
- package/dist/devtools/_nuxt/builds/latest.json +1 -1
- package/dist/devtools/_nuxt/builds/meta/df0ad51c-c846-4813-9833-34c1d7a55599.json +1 -0
- package/dist/devtools/_nuxt/{entry.D0N1PjT9.css → entry.D7zgwaiY.css} +1 -1
- package/dist/devtools/_nuxt/{pages.DjPHX4aO.css → pages.Bkgf-fNs.css} +1 -1
- package/dist/devtools/_nuxt/renderer-select.Bvsk444V.css +1 -0
- package/dist/devtools/debug/index.html +1 -1
- package/dist/devtools/docs/index.html +1 -1
- package/dist/devtools/index.html +1 -1
- package/dist/devtools/templates/index.html +1 -1
- package/dist/module.cjs +1 -1
- package/dist/module.d.cts +6 -5
- package/dist/module.d.mts +6 -5
- package/dist/module.d.ts +6 -5
- package/dist/module.json +1 -1
- package/dist/module.mjs +1 -1
- package/dist/runtime/server/og-image/bindings/font-assets/node.js +6 -3
- package/dist/runtime/server/og-image/context.js +1 -1
- package/dist/runtime/server/util/cache.d.ts +1 -0
- package/dist/runtime/server/util/cache.js +23 -4
- package/dist/runtime/server/util/eventHandlers.js +4 -3
- package/dist/runtime/types.d.ts +0 -1
- package/dist/shared/{nuxt-og-image.Blp5UsK8.mjs → nuxt-og-image.caStlBVv.mjs} +134 -4
- package/dist/shared/{nuxt-og-image.BSlBlAci.cjs → nuxt-og-image.if6TuaSI.cjs} +135 -5
- package/package.json +5 -5
- package/dist/devtools/_nuxt/DevtoolsSection.BA22BKWd.css +0 -1
- package/dist/devtools/_nuxt/DevtoolsSnippet.5f9DiVqQ.css +0 -1
- package/dist/devtools/_nuxt/builds/meta/8d1f6507-8803-4bf0-b0a0-b07d9247f574.json +0 -1
- package/dist/devtools/_nuxt/renderer-select.Dd3SlzOB.css +0 -1
package/dist/module.d.ts
CHANGED
|
@@ -109,14 +109,15 @@ interface ModuleOptions {
|
|
|
109
109
|
*/
|
|
110
110
|
emojiStrategy?: 'auto' | 'local' | 'fetch';
|
|
111
111
|
/**
|
|
112
|
-
*
|
|
112
|
+
* Default cache duration in seconds for generated OG images.
|
|
113
113
|
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
114
|
+
* Controls the internal storage TTL, HTTP Cache-Control headers, and the
|
|
115
|
+
* auto-configured SWR route rule. Can be overridden per-image via
|
|
116
|
+
* `defineOgImage`'s `cacheMaxAgeSeconds` option.
|
|
116
117
|
*
|
|
117
|
-
* @default
|
|
118
|
+
* @default 60 * 60 * 24 * 3 (3 days)
|
|
118
119
|
*/
|
|
119
|
-
|
|
120
|
+
cacheMaxAgeSeconds?: number;
|
|
120
121
|
/**
|
|
121
122
|
* Font subsets to download when resolving missing font families via fontless.
|
|
122
123
|
*
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -7,7 +7,7 @@ import 'nuxt-site-config/kit';
|
|
|
7
7
|
import 'ohash';
|
|
8
8
|
import 'pathe';
|
|
9
9
|
import 'pkg-types';
|
|
10
|
-
export { m as default } from './shared/nuxt-og-image.
|
|
10
|
+
export { m as default } from './shared/nuxt-og-image.caStlBVv.mjs';
|
|
11
11
|
import 'nuxtseo-shared/kit';
|
|
12
12
|
import '../dist/runtime/logger.js';
|
|
13
13
|
import 'node:crypto';
|
|
@@ -6,9 +6,12 @@ export async function resolve(event, font) {
|
|
|
6
6
|
const { app } = useRuntimeConfig();
|
|
7
7
|
const fullPath = withBase(path, app.baseURL);
|
|
8
8
|
const origin = getNitroOrigin(event);
|
|
9
|
-
const res = await fetch(new URL(fullPath, origin).href);
|
|
10
|
-
if (res
|
|
9
|
+
const res = await fetch(new URL(fullPath, origin).href).catch(() => null);
|
|
10
|
+
if (res?.ok) {
|
|
11
11
|
return Buffer.from(await res.arrayBuffer());
|
|
12
12
|
}
|
|
13
|
-
|
|
13
|
+
const arrayBuffer = await event.$fetch(fullPath, {
|
|
14
|
+
responseType: "arrayBuffer"
|
|
15
|
+
});
|
|
16
|
+
return Buffer.from(arrayBuffer);
|
|
14
17
|
}
|
|
@@ -99,7 +99,7 @@ export async function resolveContext(e) {
|
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
101
|
let queryParams = {};
|
|
102
|
-
if (
|
|
102
|
+
if (import.meta.dev || import.meta.prerender) {
|
|
103
103
|
const query = getQuery(e);
|
|
104
104
|
for (const k in query) {
|
|
105
105
|
const v = String(query[k]);
|
|
@@ -3,6 +3,7 @@ import type { OgImageRenderEventContext } from '../../types.js';
|
|
|
3
3
|
export declare function useOgImageBufferCache(ctx: OgImageRenderEventContext, options: {
|
|
4
4
|
baseCacheKey: string | false;
|
|
5
5
|
cacheMaxAgeSeconds?: number;
|
|
6
|
+
secret?: string;
|
|
6
7
|
}): Promise<void | H3Error | {
|
|
7
8
|
cachedItem: false | BufferSource;
|
|
8
9
|
enabled: boolean;
|
|
@@ -3,9 +3,19 @@ import { useStorage } from "nitropack/runtime";
|
|
|
3
3
|
import { digest } from "ohash";
|
|
4
4
|
import { withTrailingSlash } from "ufo";
|
|
5
5
|
import { prefixStorage } from "unstorage";
|
|
6
|
+
import { logger } from "../../logger.js";
|
|
7
|
+
function safeCompare(a, b) {
|
|
8
|
+
if (a.length !== b.length)
|
|
9
|
+
return false;
|
|
10
|
+
let mismatch = 0;
|
|
11
|
+
for (let i = 0; i < a.length; i++)
|
|
12
|
+
mismatch |= a.charCodeAt(i) ^ b.charCodeAt(i);
|
|
13
|
+
return mismatch === 0;
|
|
14
|
+
}
|
|
6
15
|
export async function useOgImageBufferCache(ctx, options) {
|
|
7
16
|
const maxAge = Number(options.cacheMaxAgeSeconds);
|
|
8
|
-
|
|
17
|
+
const intentionallyEnabled = !import.meta.dev && maxAge > 0;
|
|
18
|
+
let enabled = intentionallyEnabled;
|
|
9
19
|
const cache = prefixStorage(useStorage(), withTrailingSlash(options.baseCacheKey || "/"));
|
|
10
20
|
const key = ctx.key;
|
|
11
21
|
let cachedItem = false;
|
|
@@ -25,7 +35,14 @@ export async function useOgImageBufferCache(ctx, options) {
|
|
|
25
35
|
value: null,
|
|
26
36
|
expiresAt: Date.now()
|
|
27
37
|
}));
|
|
28
|
-
|
|
38
|
+
const purgeValue = getQuery(ctx.e).purge;
|
|
39
|
+
if (typeof purgeValue !== "undefined") {
|
|
40
|
+
if (options.secret && !safeCompare(String(purgeValue), options.secret)) {
|
|
41
|
+
return createError({
|
|
42
|
+
statusCode: 403,
|
|
43
|
+
statusMessage: "[Nuxt OG Image] Invalid purge token. Provide the signing secret as ?purge=<secret>."
|
|
44
|
+
});
|
|
45
|
+
}
|
|
29
46
|
await cache.removeItem(key).catch(() => {
|
|
30
47
|
});
|
|
31
48
|
} else if (expiresAt > Date.now()) {
|
|
@@ -38,6 +55,7 @@ export async function useOgImageBufferCache(ctx, options) {
|
|
|
38
55
|
return;
|
|
39
56
|
}
|
|
40
57
|
setHeaders(ctx.e, headers);
|
|
58
|
+
setHeader(ctx.e, "X-OG-Cache", "HIT");
|
|
41
59
|
} else {
|
|
42
60
|
await cache.removeItem(key).catch(() => {
|
|
43
61
|
});
|
|
@@ -53,6 +71,7 @@ export async function useOgImageBufferCache(ctx, options) {
|
|
|
53
71
|
enabled,
|
|
54
72
|
cachedItem,
|
|
55
73
|
async update(item) {
|
|
74
|
+
setHeader(ctx.e, "X-OG-Cache", intentionallyEnabled ? "MISS" : "DISABLED");
|
|
56
75
|
if (!enabled)
|
|
57
76
|
return;
|
|
58
77
|
const value = Buffer.from(item).toString("base64");
|
|
@@ -61,14 +80,14 @@ export async function useOgImageBufferCache(ctx, options) {
|
|
|
61
80
|
"Vary": "accept-encoding, host",
|
|
62
81
|
"etag": `W/"${digest(value)}"`,
|
|
63
82
|
"last-modified": (/* @__PURE__ */ new Date()).toUTCString(),
|
|
64
|
-
"cache-control": `public, s-maxage=${maxAge}, stale-while-revalidate`
|
|
83
|
+
"cache-control": `public, max-age=${maxAge}, s-maxage=${maxAge}, stale-while-revalidate=${maxAge}, stale-if-error=${maxAge}`
|
|
65
84
|
};
|
|
66
85
|
setHeaders(ctx.e, headers);
|
|
67
86
|
await cache.setItem(key, {
|
|
68
87
|
value,
|
|
69
88
|
headers,
|
|
70
89
|
expiresAt: Date.now() + maxAge * 1e3
|
|
71
|
-
});
|
|
90
|
+
}).catch((err) => logger.warn(`[Nuxt OG Image] Failed to write cache for key "${key}": ${err?.message || err}`));
|
|
72
91
|
}
|
|
73
92
|
};
|
|
74
93
|
}
|
|
@@ -82,6 +82,7 @@ export async function imageEventHandler(e) {
|
|
|
82
82
|
case "png":
|
|
83
83
|
case "jpeg":
|
|
84
84
|
case "jpg":
|
|
85
|
+
case "webp":
|
|
85
86
|
if (!renderer.supportedFormats.includes(extension)) {
|
|
86
87
|
return createError({
|
|
87
88
|
statusCode: 400,
|
|
@@ -102,7 +103,8 @@ export async function imageEventHandler(e) {
|
|
|
102
103
|
}
|
|
103
104
|
const cacheApi = await useOgImageBufferCache(ctx, {
|
|
104
105
|
cacheMaxAgeSeconds: ctx.options.cacheMaxAgeSeconds,
|
|
105
|
-
baseCacheKey
|
|
106
|
+
baseCacheKey,
|
|
107
|
+
secret: security?.secret
|
|
106
108
|
});
|
|
107
109
|
if (typeof cacheApi === "undefined")
|
|
108
110
|
return;
|
|
@@ -110,8 +112,7 @@ export async function imageEventHandler(e) {
|
|
|
110
112
|
return cacheApi;
|
|
111
113
|
let image = cacheApi.cachedItem;
|
|
112
114
|
if (!image) {
|
|
113
|
-
const
|
|
114
|
-
const timeout = security2?.renderTimeout || 15e3;
|
|
115
|
+
const timeout = security?.renderTimeout || 15e3;
|
|
115
116
|
let timer;
|
|
116
117
|
image = await Promise.race([
|
|
117
118
|
renderer.createImage(ctx),
|
package/dist/runtime/types.d.ts
CHANGED
|
@@ -38,7 +38,6 @@ export interface OgImageRuntimeConfig {
|
|
|
38
38
|
colorPreference: 'light' | 'dark';
|
|
39
39
|
isNuxtContentDocumentDriven: boolean;
|
|
40
40
|
zeroRuntime: boolean;
|
|
41
|
-
cacheQueryParams: boolean;
|
|
42
41
|
cssFramework: 'tailwind' | 'unocss' | 'none';
|
|
43
42
|
componentDirs?: string[];
|
|
44
43
|
/** Directory for persistent build cache (CI caching) */
|
|
@@ -2535,6 +2535,94 @@ const ATTRIBUTE_NODE = 6;
|
|
|
2535
2535
|
const DIRECTIVE_NODE = 7;
|
|
2536
2536
|
const RE_PURE_NUMBER = /^\d+(?:\.\d+)?$/;
|
|
2537
2537
|
const RE_DOUBLE_QUOTE = /"/g;
|
|
2538
|
+
const RE_CAMEL_TO_KEBAB = /[A-Z]/g;
|
|
2539
|
+
const RE_STRIP_QUOTES = /^['"]|['"]$/g;
|
|
2540
|
+
const RE_SINGLE_QUOTED = /^'([^']*)'$/;
|
|
2541
|
+
const RE_DOUBLE_QUOTED = /^"([^"]*)"$/;
|
|
2542
|
+
const RE_BACKTICK_QUOTED = /^`([^`]*)`$/;
|
|
2543
|
+
const RE_CSS_NUMBER = /^[\d.]+(?:px|em|rem|%|vh|vw|ch|ex|vmin|vmax|pt|pc|in|cm|mm)?$/;
|
|
2544
|
+
function camelToKebab(str) {
|
|
2545
|
+
return str.replace(RE_CAMEL_TO_KEBAB, (m) => `-${m.toLowerCase()}`);
|
|
2546
|
+
}
|
|
2547
|
+
function parseStaticStyleObject(expr) {
|
|
2548
|
+
const trimmed = expr.trim();
|
|
2549
|
+
if (!trimmed.startsWith("{") || !trimmed.endsWith("}"))
|
|
2550
|
+
return void 0;
|
|
2551
|
+
const inner = trimmed.slice(1, -1).trim();
|
|
2552
|
+
if (!inner)
|
|
2553
|
+
return {};
|
|
2554
|
+
const result = {};
|
|
2555
|
+
let depth = 0;
|
|
2556
|
+
let inQuote = null;
|
|
2557
|
+
let current = "";
|
|
2558
|
+
for (let i = 0; i < inner.length; i++) {
|
|
2559
|
+
const ch = inner[i];
|
|
2560
|
+
if (inQuote) {
|
|
2561
|
+
current += ch;
|
|
2562
|
+
if (ch === inQuote && inner[i - 1] !== "\\")
|
|
2563
|
+
inQuote = null;
|
|
2564
|
+
continue;
|
|
2565
|
+
}
|
|
2566
|
+
if (ch === "'" || ch === '"' || ch === "`") {
|
|
2567
|
+
inQuote = ch;
|
|
2568
|
+
current += ch;
|
|
2569
|
+
continue;
|
|
2570
|
+
}
|
|
2571
|
+
if (ch === "(" || ch === "[" || ch === "{") {
|
|
2572
|
+
depth++;
|
|
2573
|
+
current += ch;
|
|
2574
|
+
continue;
|
|
2575
|
+
}
|
|
2576
|
+
if (ch === ")" || ch === "]" || ch === "}") {
|
|
2577
|
+
depth--;
|
|
2578
|
+
current += ch;
|
|
2579
|
+
continue;
|
|
2580
|
+
}
|
|
2581
|
+
if (ch === "," && depth === 0) {
|
|
2582
|
+
const parsed = parseStyleEntry(current);
|
|
2583
|
+
if (!parsed)
|
|
2584
|
+
return void 0;
|
|
2585
|
+
result[parsed[0]] = parsed[1];
|
|
2586
|
+
current = "";
|
|
2587
|
+
continue;
|
|
2588
|
+
}
|
|
2589
|
+
current += ch;
|
|
2590
|
+
}
|
|
2591
|
+
if (current.trim()) {
|
|
2592
|
+
const parsed = parseStyleEntry(current);
|
|
2593
|
+
if (!parsed)
|
|
2594
|
+
return void 0;
|
|
2595
|
+
result[parsed[0]] = parsed[1];
|
|
2596
|
+
}
|
|
2597
|
+
return result;
|
|
2598
|
+
}
|
|
2599
|
+
function parseStyleEntry(entry) {
|
|
2600
|
+
const colonIdx = entry.indexOf(":");
|
|
2601
|
+
if (colonIdx === -1)
|
|
2602
|
+
return void 0;
|
|
2603
|
+
const rawKey = entry.slice(0, colonIdx).trim();
|
|
2604
|
+
const rawValue = entry.slice(colonIdx + 1).trim();
|
|
2605
|
+
const key = rawKey.replace(RE_STRIP_QUOTES, "");
|
|
2606
|
+
if (!key)
|
|
2607
|
+
return void 0;
|
|
2608
|
+
let value;
|
|
2609
|
+
const singleQuoteMatch = rawValue.match(RE_SINGLE_QUOTED);
|
|
2610
|
+
const doubleQuoteMatch = rawValue.match(RE_DOUBLE_QUOTED);
|
|
2611
|
+
const backtickMatch = rawValue.match(RE_BACKTICK_QUOTED);
|
|
2612
|
+
const numberMatch = rawValue.match(RE_CSS_NUMBER);
|
|
2613
|
+
if (singleQuoteMatch) {
|
|
2614
|
+
value = singleQuoteMatch[1];
|
|
2615
|
+
} else if (doubleQuoteMatch) {
|
|
2616
|
+
value = doubleQuoteMatch[1];
|
|
2617
|
+
} else if (backtickMatch && !backtickMatch[1].includes("${")) {
|
|
2618
|
+
value = backtickMatch[1];
|
|
2619
|
+
} else if (numberMatch) {
|
|
2620
|
+
value = rawValue;
|
|
2621
|
+
} else {
|
|
2622
|
+
return void 0;
|
|
2623
|
+
}
|
|
2624
|
+
return [camelToKebab(key), value];
|
|
2625
|
+
}
|
|
2538
2626
|
function escapeAttrValue(value) {
|
|
2539
2627
|
return value.replace(RE_DOUBLE_QUOTE, """);
|
|
2540
2628
|
}
|
|
@@ -2572,7 +2660,17 @@ async function transformVueTemplate(code, options) {
|
|
|
2572
2660
|
}
|
|
2573
2661
|
}
|
|
2574
2662
|
if (prop.type === DIRECTIVE_NODE && prop.name === "bind" && prop.arg?.content === "style") {
|
|
2575
|
-
|
|
2663
|
+
const exp = prop.exp?.content;
|
|
2664
|
+
if (exp) {
|
|
2665
|
+
const parsed = parseStaticStyleObject(exp);
|
|
2666
|
+
if (parsed) {
|
|
2667
|
+
collector.dynamicStyleProps = parsed;
|
|
2668
|
+
collector.dynamicStyleLoc = {
|
|
2669
|
+
start: prop.loc.start.offset,
|
|
2670
|
+
end: prop.loc.end.offset
|
|
2671
|
+
};
|
|
2672
|
+
}
|
|
2673
|
+
}
|
|
2576
2674
|
}
|
|
2577
2675
|
if (prop.type === ATTRIBUTE_NODE && (prop.name === "width" || prop.name === "height") && prop.value && el.tag === "img") {
|
|
2578
2676
|
if (!collector.dimensionAttrs)
|
|
@@ -2580,7 +2678,7 @@ async function transformVueTemplate(code, options) {
|
|
|
2580
2678
|
collector.dimensionAttrs.push({ name: prop.name, value: prop.value.content });
|
|
2581
2679
|
}
|
|
2582
2680
|
}
|
|
2583
|
-
if (collector.classes.length > 0 || collector.existingStyle || collector.dimensionAttrs?.length) {
|
|
2681
|
+
if (collector.classes.length > 0 || collector.existingStyle || collector.dimensionAttrs?.length || collector.dynamicStyleProps) {
|
|
2584
2682
|
if (collector.existingStyle && !collector.styleLoc) {
|
|
2585
2683
|
logger.warn(`[vue-template-transform] BUG: existingStyle found but styleLoc is undefined!`);
|
|
2586
2684
|
}
|
|
@@ -2621,6 +2719,9 @@ async function transformVueTemplate(code, options) {
|
|
|
2621
2719
|
}
|
|
2622
2720
|
}
|
|
2623
2721
|
}
|
|
2722
|
+
if (collector.dynamicStyleProps) {
|
|
2723
|
+
Object.assign(styleProps, collector.dynamicStyleProps);
|
|
2724
|
+
}
|
|
2624
2725
|
if (styleProps.display === "flex" && !styleProps["flex-direction"]) {
|
|
2625
2726
|
styleProps["flex-direction"] = "row";
|
|
2626
2727
|
}
|
|
@@ -2629,7 +2730,8 @@ async function transformVueTemplate(code, options) {
|
|
|
2629
2730
|
const hasUnresolved = unresolvedClasses.length > 0;
|
|
2630
2731
|
const resolvedSome = collector.classes.length > 0 && (unresolvedClasses.length < collector.classes.length || hasClassRewrites);
|
|
2631
2732
|
const styleChanged = collector.existingStyle && styleStr !== collector.existingStyle;
|
|
2632
|
-
|
|
2733
|
+
const hasDynamicStyleResolved = collector.dynamicStyleProps && Object.keys(collector.dynamicStyleProps).length > 0;
|
|
2734
|
+
if (!resolvedSome && !styleChanged && !collector.dimensionAttrs?.length && !hasDynamicStyleResolved)
|
|
2633
2735
|
continue;
|
|
2634
2736
|
hasChanges = true;
|
|
2635
2737
|
if (collector.classLoc) {
|
|
@@ -2639,6 +2741,9 @@ async function transformVueTemplate(code, options) {
|
|
|
2639
2741
|
s.remove(collector.classLoc.start, collector.classLoc.end);
|
|
2640
2742
|
}
|
|
2641
2743
|
}
|
|
2744
|
+
if (collector.dynamicStyleLoc) {
|
|
2745
|
+
s.remove(collector.dynamicStyleLoc.start, collector.dynamicStyleLoc.end);
|
|
2746
|
+
}
|
|
2642
2747
|
if (hasResolvedStyles) {
|
|
2643
2748
|
if (collector.styleLoc) {
|
|
2644
2749
|
s.overwrite(collector.styleLoc.start, collector.styleLoc.end, `style="${styleStr}"`);
|
|
@@ -3550,6 +3655,7 @@ const REMOVED_CONFIG = {
|
|
|
3550
3655
|
"runtimeSatori": "compatibility.runtime.satori",
|
|
3551
3656
|
"cacheTtl": "cacheMaxAgeSeconds",
|
|
3552
3657
|
"cache": "cacheMaxAgeSeconds",
|
|
3658
|
+
"cacheQueryParams": "Removed (all options are encoded in the URL path)",
|
|
3553
3659
|
"cacheKey": "Removed",
|
|
3554
3660
|
"static": "zeroRuntime",
|
|
3555
3661
|
"chromium-node": "compatibility.runtime.browser: 'playwright'",
|
|
@@ -3671,6 +3777,7 @@ const DEPRECATED_CONFIG = {
|
|
|
3671
3777
|
runtimeSatori: "Use compatibility.runtime.satori",
|
|
3672
3778
|
cacheTtl: "Use cacheMaxAgeSeconds",
|
|
3673
3779
|
cache: "Use cacheMaxAgeSeconds",
|
|
3780
|
+
cacheQueryParams: "Removed (all options are encoded in the URL path)",
|
|
3674
3781
|
cacheKey: "Removed",
|
|
3675
3782
|
static: "Removed - use zeroRuntime",
|
|
3676
3783
|
fonts: "Use @nuxt/fonts module instead"
|
|
@@ -4217,6 +4324,10 @@ const module$1 = defineNuxtModule({
|
|
|
4217
4324
|
logger.warn("Nuxt OG Image is enabled but SSR is disabled.\n\nYou should enable SSR (`ssr: true`) or disable the module (`ogImage: { enabled: false }`).");
|
|
4218
4325
|
return;
|
|
4219
4326
|
}
|
|
4327
|
+
if (config.cacheMaxAgeSeconds != null) {
|
|
4328
|
+
config.defaults = config.defaults || {};
|
|
4329
|
+
config.defaults.cacheMaxAgeSeconds = config.cacheMaxAgeSeconds;
|
|
4330
|
+
}
|
|
4220
4331
|
if (config.debug && !nuxt.options.dev) {
|
|
4221
4332
|
logger.warn("`ogImage.debug` is enabled in production. This exposes the `/_og/debug.json` endpoint and should not be enabled in production. Disable it before deploying.");
|
|
4222
4333
|
}
|
|
@@ -4622,6 +4733,26 @@ ${familyInfo}`);
|
|
|
4622
4733
|
route: "/_og/s/**",
|
|
4623
4734
|
handler: resolve(`${basePath}/image`)
|
|
4624
4735
|
});
|
|
4736
|
+
if (!nuxt.options.dev) {
|
|
4737
|
+
nuxt.options.routeRules = nuxt.options.routeRules || {};
|
|
4738
|
+
if (config.runtimeCacheStorage !== false && !nuxt.options.test) {
|
|
4739
|
+
const ogDynamicRule = nuxt.options.routeRules["/_og/d/**"];
|
|
4740
|
+
if (!ogDynamicRule?.swr && !ogDynamicRule?.isr && !ogDynamicRule?.cache && !ogDynamicRule?.headers) {
|
|
4741
|
+
const ttl = config.cacheMaxAgeSeconds ?? config.defaults?.cacheMaxAgeSeconds ?? 60 * 60 * 24 * 3;
|
|
4742
|
+
nuxt.options.routeRules["/_og/d/**"] = defu(
|
|
4743
|
+
nuxt.options.routeRules["/_og/d/**"] || {},
|
|
4744
|
+
{ swr: ttl }
|
|
4745
|
+
);
|
|
4746
|
+
}
|
|
4747
|
+
}
|
|
4748
|
+
const ogStaticRule = nuxt.options.routeRules["/_og/s/**"];
|
|
4749
|
+
if (!ogStaticRule?.swr && !ogStaticRule?.isr && !ogStaticRule?.cache && !ogStaticRule?.headers) {
|
|
4750
|
+
nuxt.options.routeRules["/_og/s/**"] = defu(
|
|
4751
|
+
nuxt.options.routeRules["/_og/s/**"] || {},
|
|
4752
|
+
{ headers: { "cache-control": "public, max-age=31536000, immutable" } }
|
|
4753
|
+
);
|
|
4754
|
+
}
|
|
4755
|
+
}
|
|
4625
4756
|
if (!nuxt.options.dev) {
|
|
4626
4757
|
nuxt.options.optimization.treeShake.composables.client["nuxt-og-image"] = [];
|
|
4627
4758
|
}
|
|
@@ -5072,7 +5203,6 @@ export const rootDir = ${JSON.stringify(nuxt.options.rootDir)}`;
|
|
|
5072
5203
|
colorPreference,
|
|
5073
5204
|
// @ts-expect-error runtime type
|
|
5074
5205
|
isNuxtContentDocumentDriven: !!nuxt.options.content?.documentDriven,
|
|
5075
|
-
cacheQueryParams: config.cacheQueryParams ?? false,
|
|
5076
5206
|
cssFramework: cssFramework || "none",
|
|
5077
5207
|
// Browser renderer config for cloudflare binding access
|
|
5078
5208
|
browser: typeof config.browser === "object" ? {
|
|
@@ -2555,6 +2555,94 @@ const ATTRIBUTE_NODE = 6;
|
|
|
2555
2555
|
const DIRECTIVE_NODE = 7;
|
|
2556
2556
|
const RE_PURE_NUMBER = /^\d+(?:\.\d+)?$/;
|
|
2557
2557
|
const RE_DOUBLE_QUOTE = /"/g;
|
|
2558
|
+
const RE_CAMEL_TO_KEBAB = /[A-Z]/g;
|
|
2559
|
+
const RE_STRIP_QUOTES = /^['"]|['"]$/g;
|
|
2560
|
+
const RE_SINGLE_QUOTED = /^'([^']*)'$/;
|
|
2561
|
+
const RE_DOUBLE_QUOTED = /^"([^"]*)"$/;
|
|
2562
|
+
const RE_BACKTICK_QUOTED = /^`([^`]*)`$/;
|
|
2563
|
+
const RE_CSS_NUMBER = /^[\d.]+(?:px|em|rem|%|vh|vw|ch|ex|vmin|vmax|pt|pc|in|cm|mm)?$/;
|
|
2564
|
+
function camelToKebab(str) {
|
|
2565
|
+
return str.replace(RE_CAMEL_TO_KEBAB, (m) => `-${m.toLowerCase()}`);
|
|
2566
|
+
}
|
|
2567
|
+
function parseStaticStyleObject(expr) {
|
|
2568
|
+
const trimmed = expr.trim();
|
|
2569
|
+
if (!trimmed.startsWith("{") || !trimmed.endsWith("}"))
|
|
2570
|
+
return void 0;
|
|
2571
|
+
const inner = trimmed.slice(1, -1).trim();
|
|
2572
|
+
if (!inner)
|
|
2573
|
+
return {};
|
|
2574
|
+
const result = {};
|
|
2575
|
+
let depth = 0;
|
|
2576
|
+
let inQuote = null;
|
|
2577
|
+
let current = "";
|
|
2578
|
+
for (let i = 0; i < inner.length; i++) {
|
|
2579
|
+
const ch = inner[i];
|
|
2580
|
+
if (inQuote) {
|
|
2581
|
+
current += ch;
|
|
2582
|
+
if (ch === inQuote && inner[i - 1] !== "\\")
|
|
2583
|
+
inQuote = null;
|
|
2584
|
+
continue;
|
|
2585
|
+
}
|
|
2586
|
+
if (ch === "'" || ch === '"' || ch === "`") {
|
|
2587
|
+
inQuote = ch;
|
|
2588
|
+
current += ch;
|
|
2589
|
+
continue;
|
|
2590
|
+
}
|
|
2591
|
+
if (ch === "(" || ch === "[" || ch === "{") {
|
|
2592
|
+
depth++;
|
|
2593
|
+
current += ch;
|
|
2594
|
+
continue;
|
|
2595
|
+
}
|
|
2596
|
+
if (ch === ")" || ch === "]" || ch === "}") {
|
|
2597
|
+
depth--;
|
|
2598
|
+
current += ch;
|
|
2599
|
+
continue;
|
|
2600
|
+
}
|
|
2601
|
+
if (ch === "," && depth === 0) {
|
|
2602
|
+
const parsed = parseStyleEntry(current);
|
|
2603
|
+
if (!parsed)
|
|
2604
|
+
return void 0;
|
|
2605
|
+
result[parsed[0]] = parsed[1];
|
|
2606
|
+
current = "";
|
|
2607
|
+
continue;
|
|
2608
|
+
}
|
|
2609
|
+
current += ch;
|
|
2610
|
+
}
|
|
2611
|
+
if (current.trim()) {
|
|
2612
|
+
const parsed = parseStyleEntry(current);
|
|
2613
|
+
if (!parsed)
|
|
2614
|
+
return void 0;
|
|
2615
|
+
result[parsed[0]] = parsed[1];
|
|
2616
|
+
}
|
|
2617
|
+
return result;
|
|
2618
|
+
}
|
|
2619
|
+
function parseStyleEntry(entry) {
|
|
2620
|
+
const colonIdx = entry.indexOf(":");
|
|
2621
|
+
if (colonIdx === -1)
|
|
2622
|
+
return void 0;
|
|
2623
|
+
const rawKey = entry.slice(0, colonIdx).trim();
|
|
2624
|
+
const rawValue = entry.slice(colonIdx + 1).trim();
|
|
2625
|
+
const key = rawKey.replace(RE_STRIP_QUOTES, "");
|
|
2626
|
+
if (!key)
|
|
2627
|
+
return void 0;
|
|
2628
|
+
let value;
|
|
2629
|
+
const singleQuoteMatch = rawValue.match(RE_SINGLE_QUOTED);
|
|
2630
|
+
const doubleQuoteMatch = rawValue.match(RE_DOUBLE_QUOTED);
|
|
2631
|
+
const backtickMatch = rawValue.match(RE_BACKTICK_QUOTED);
|
|
2632
|
+
const numberMatch = rawValue.match(RE_CSS_NUMBER);
|
|
2633
|
+
if (singleQuoteMatch) {
|
|
2634
|
+
value = singleQuoteMatch[1];
|
|
2635
|
+
} else if (doubleQuoteMatch) {
|
|
2636
|
+
value = doubleQuoteMatch[1];
|
|
2637
|
+
} else if (backtickMatch && !backtickMatch[1].includes("${")) {
|
|
2638
|
+
value = backtickMatch[1];
|
|
2639
|
+
} else if (numberMatch) {
|
|
2640
|
+
value = rawValue;
|
|
2641
|
+
} else {
|
|
2642
|
+
return void 0;
|
|
2643
|
+
}
|
|
2644
|
+
return [camelToKebab(key), value];
|
|
2645
|
+
}
|
|
2558
2646
|
function escapeAttrValue(value) {
|
|
2559
2647
|
return value.replace(RE_DOUBLE_QUOTE, """);
|
|
2560
2648
|
}
|
|
@@ -2592,7 +2680,17 @@ async function transformVueTemplate(code, options) {
|
|
|
2592
2680
|
}
|
|
2593
2681
|
}
|
|
2594
2682
|
if (prop.type === DIRECTIVE_NODE && prop.name === "bind" && prop.arg?.content === "style") {
|
|
2595
|
-
|
|
2683
|
+
const exp = prop.exp?.content;
|
|
2684
|
+
if (exp) {
|
|
2685
|
+
const parsed = parseStaticStyleObject(exp);
|
|
2686
|
+
if (parsed) {
|
|
2687
|
+
collector.dynamicStyleProps = parsed;
|
|
2688
|
+
collector.dynamicStyleLoc = {
|
|
2689
|
+
start: prop.loc.start.offset,
|
|
2690
|
+
end: prop.loc.end.offset
|
|
2691
|
+
};
|
|
2692
|
+
}
|
|
2693
|
+
}
|
|
2596
2694
|
}
|
|
2597
2695
|
if (prop.type === ATTRIBUTE_NODE && (prop.name === "width" || prop.name === "height") && prop.value && el.tag === "img") {
|
|
2598
2696
|
if (!collector.dimensionAttrs)
|
|
@@ -2600,7 +2698,7 @@ async function transformVueTemplate(code, options) {
|
|
|
2600
2698
|
collector.dimensionAttrs.push({ name: prop.name, value: prop.value.content });
|
|
2601
2699
|
}
|
|
2602
2700
|
}
|
|
2603
|
-
if (collector.classes.length > 0 || collector.existingStyle || collector.dimensionAttrs?.length) {
|
|
2701
|
+
if (collector.classes.length > 0 || collector.existingStyle || collector.dimensionAttrs?.length || collector.dynamicStyleProps) {
|
|
2604
2702
|
if (collector.existingStyle && !collector.styleLoc) {
|
|
2605
2703
|
logger_js.logger.warn(`[vue-template-transform] BUG: existingStyle found but styleLoc is undefined!`);
|
|
2606
2704
|
}
|
|
@@ -2641,6 +2739,9 @@ async function transformVueTemplate(code, options) {
|
|
|
2641
2739
|
}
|
|
2642
2740
|
}
|
|
2643
2741
|
}
|
|
2742
|
+
if (collector.dynamicStyleProps) {
|
|
2743
|
+
Object.assign(styleProps, collector.dynamicStyleProps);
|
|
2744
|
+
}
|
|
2644
2745
|
if (styleProps.display === "flex" && !styleProps["flex-direction"]) {
|
|
2645
2746
|
styleProps["flex-direction"] = "row";
|
|
2646
2747
|
}
|
|
@@ -2649,7 +2750,8 @@ async function transformVueTemplate(code, options) {
|
|
|
2649
2750
|
const hasUnresolved = unresolvedClasses.length > 0;
|
|
2650
2751
|
const resolvedSome = collector.classes.length > 0 && (unresolvedClasses.length < collector.classes.length || hasClassRewrites);
|
|
2651
2752
|
const styleChanged = collector.existingStyle && styleStr !== collector.existingStyle;
|
|
2652
|
-
|
|
2753
|
+
const hasDynamicStyleResolved = collector.dynamicStyleProps && Object.keys(collector.dynamicStyleProps).length > 0;
|
|
2754
|
+
if (!resolvedSome && !styleChanged && !collector.dimensionAttrs?.length && !hasDynamicStyleResolved)
|
|
2653
2755
|
continue;
|
|
2654
2756
|
hasChanges = true;
|
|
2655
2757
|
if (collector.classLoc) {
|
|
@@ -2659,6 +2761,9 @@ async function transformVueTemplate(code, options) {
|
|
|
2659
2761
|
s.remove(collector.classLoc.start, collector.classLoc.end);
|
|
2660
2762
|
}
|
|
2661
2763
|
}
|
|
2764
|
+
if (collector.dynamicStyleLoc) {
|
|
2765
|
+
s.remove(collector.dynamicStyleLoc.start, collector.dynamicStyleLoc.end);
|
|
2766
|
+
}
|
|
2662
2767
|
if (hasResolvedStyles) {
|
|
2663
2768
|
if (collector.styleLoc) {
|
|
2664
2769
|
s.overwrite(collector.styleLoc.start, collector.styleLoc.end, `style="${styleStr}"`);
|
|
@@ -3570,6 +3675,7 @@ const REMOVED_CONFIG = {
|
|
|
3570
3675
|
"runtimeSatori": "compatibility.runtime.satori",
|
|
3571
3676
|
"cacheTtl": "cacheMaxAgeSeconds",
|
|
3572
3677
|
"cache": "cacheMaxAgeSeconds",
|
|
3678
|
+
"cacheQueryParams": "Removed (all options are encoded in the URL path)",
|
|
3573
3679
|
"cacheKey": "Removed",
|
|
3574
3680
|
"static": "zeroRuntime",
|
|
3575
3681
|
"chromium-node": "compatibility.runtime.browser: 'playwright'",
|
|
@@ -3691,6 +3797,7 @@ const DEPRECATED_CONFIG = {
|
|
|
3691
3797
|
runtimeSatori: "Use compatibility.runtime.satori",
|
|
3692
3798
|
cacheTtl: "Use cacheMaxAgeSeconds",
|
|
3693
3799
|
cache: "Use cacheMaxAgeSeconds",
|
|
3800
|
+
cacheQueryParams: "Removed (all options are encoded in the URL path)",
|
|
3694
3801
|
cacheKey: "Removed",
|
|
3695
3802
|
static: "Removed - use zeroRuntime",
|
|
3696
3803
|
fonts: "Use @nuxt/fonts module instead"
|
|
@@ -4207,7 +4314,7 @@ const module$1 = kit.defineNuxtModule({
|
|
|
4207
4314
|
await onUpgrade(nuxt, options, previousVersion);
|
|
4208
4315
|
},
|
|
4209
4316
|
async setup(config, nuxt) {
|
|
4210
|
-
const _resolver = kit.createResolver((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('shared/nuxt-og-image.
|
|
4317
|
+
const _resolver = kit.createResolver((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('shared/nuxt-og-image.if6TuaSI.cjs', document.baseURI).href)));
|
|
4211
4318
|
const fixSharedPath = (p) => {
|
|
4212
4319
|
if (p.includes("/shared/runtime/"))
|
|
4213
4320
|
return p.replace("/shared/runtime/", "/runtime/");
|
|
@@ -4237,6 +4344,10 @@ const module$1 = kit.defineNuxtModule({
|
|
|
4237
4344
|
logger_js.logger.warn("Nuxt OG Image is enabled but SSR is disabled.\n\nYou should enable SSR (`ssr: true`) or disable the module (`ogImage: { enabled: false }`).");
|
|
4238
4345
|
return;
|
|
4239
4346
|
}
|
|
4347
|
+
if (config.cacheMaxAgeSeconds != null) {
|
|
4348
|
+
config.defaults = config.defaults || {};
|
|
4349
|
+
config.defaults.cacheMaxAgeSeconds = config.cacheMaxAgeSeconds;
|
|
4350
|
+
}
|
|
4240
4351
|
if (config.debug && !nuxt.options.dev) {
|
|
4241
4352
|
logger_js.logger.warn("`ogImage.debug` is enabled in production. This exposes the `/_og/debug.json` endpoint and should not be enabled in production. Disable it before deploying.");
|
|
4242
4353
|
}
|
|
@@ -4642,6 +4753,26 @@ ${familyInfo}`);
|
|
|
4642
4753
|
route: "/_og/s/**",
|
|
4643
4754
|
handler: resolve(`${basePath}/image`)
|
|
4644
4755
|
});
|
|
4756
|
+
if (!nuxt.options.dev) {
|
|
4757
|
+
nuxt.options.routeRules = nuxt.options.routeRules || {};
|
|
4758
|
+
if (config.runtimeCacheStorage !== false && !nuxt.options.test) {
|
|
4759
|
+
const ogDynamicRule = nuxt.options.routeRules["/_og/d/**"];
|
|
4760
|
+
if (!ogDynamicRule?.swr && !ogDynamicRule?.isr && !ogDynamicRule?.cache && !ogDynamicRule?.headers) {
|
|
4761
|
+
const ttl = config.cacheMaxAgeSeconds ?? config.defaults?.cacheMaxAgeSeconds ?? 60 * 60 * 24 * 3;
|
|
4762
|
+
nuxt.options.routeRules["/_og/d/**"] = defu.defu(
|
|
4763
|
+
nuxt.options.routeRules["/_og/d/**"] || {},
|
|
4764
|
+
{ swr: ttl }
|
|
4765
|
+
);
|
|
4766
|
+
}
|
|
4767
|
+
}
|
|
4768
|
+
const ogStaticRule = nuxt.options.routeRules["/_og/s/**"];
|
|
4769
|
+
if (!ogStaticRule?.swr && !ogStaticRule?.isr && !ogStaticRule?.cache && !ogStaticRule?.headers) {
|
|
4770
|
+
nuxt.options.routeRules["/_og/s/**"] = defu.defu(
|
|
4771
|
+
nuxt.options.routeRules["/_og/s/**"] || {},
|
|
4772
|
+
{ headers: { "cache-control": "public, max-age=31536000, immutable" } }
|
|
4773
|
+
);
|
|
4774
|
+
}
|
|
4775
|
+
}
|
|
4645
4776
|
if (!nuxt.options.dev) {
|
|
4646
4777
|
nuxt.options.optimization.treeShake.composables.client["nuxt-og-image"] = [];
|
|
4647
4778
|
}
|
|
@@ -5092,7 +5223,6 @@ export const rootDir = ${JSON.stringify(nuxt.options.rootDir)}`;
|
|
|
5092
5223
|
colorPreference,
|
|
5093
5224
|
// @ts-expect-error runtime type
|
|
5094
5225
|
isNuxtContentDocumentDriven: !!nuxt.options.content?.documentDriven,
|
|
5095
|
-
cacheQueryParams: config.cacheQueryParams ?? false,
|
|
5096
5226
|
cssFramework: cssFramework || "none",
|
|
5097
5227
|
// Browser renderer config for cloudflare binding access
|
|
5098
5228
|
browser: typeof config.browser === "object" ? {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nuxt-og-image",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "6.3.
|
|
4
|
+
"version": "6.3.9",
|
|
5
5
|
"description": "Enlightened OG Image generation for Nuxt.",
|
|
6
6
|
"author": {
|
|
7
7
|
"website": "https://harlanzw.com",
|
|
@@ -135,8 +135,8 @@
|
|
|
135
135
|
"@iconify-json/tabler": "^1.2.33",
|
|
136
136
|
"@img/sharp-linux-x64": "^0.34.5",
|
|
137
137
|
"@nuxt/content": "^3.12.0",
|
|
138
|
-
"@nuxt/devtools": "
|
|
139
|
-
"@nuxt/devtools-kit": "
|
|
138
|
+
"@nuxt/devtools": "4.0.0-alpha.4",
|
|
139
|
+
"@nuxt/devtools-kit": "4.0.0-alpha.4",
|
|
140
140
|
"@nuxt/fonts": "^0.14.0",
|
|
141
141
|
"@nuxt/icon": "^2.2.1",
|
|
142
142
|
"@nuxt/image": "^2.0.0",
|
|
@@ -152,8 +152,8 @@
|
|
|
152
152
|
"@shikijs/langs": "^4.0.2",
|
|
153
153
|
"@shikijs/themes": "^4.0.2",
|
|
154
154
|
"@tailwindcss/vite": "^4.2.2",
|
|
155
|
-
"@takumi-rs/core": "1.0.
|
|
156
|
-
"@takumi-rs/wasm": "1.0.
|
|
155
|
+
"@takumi-rs/core": "1.0.1",
|
|
156
|
+
"@takumi-rs/wasm": "1.0.1",
|
|
157
157
|
"@unocss/nuxt": "^66.6.8",
|
|
158
158
|
"@vitejs/plugin-vue": "^6.0.5",
|
|
159
159
|
"@vueuse/nuxt": "^14.2.1",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
.section-block[data-v-959e3b7d]{background:var(--color-surface-elevated);border:1px solid var(--color-border);border-radius:var(--radius-lg);transition:border-color .2s;overflow:hidden}.section-block[data-v-959e3b7d]:hover{border-color:var(--color-neutral-300)}.dark .section-block[data-v-959e3b7d]:hover{border-color:var(--color-neutral-700)}.section-header[data-v-959e3b7d]{cursor:pointer;-webkit-user-select:none;user-select:none;padding:.875rem 1rem;list-style:none;transition:background .15s}.section-header[data-v-959e3b7d]::-webkit-details-marker{display:none}.section-header[data-v-959e3b7d]:hover{background:var(--color-surface-sunken)}details[open] .section-header[data-v-959e3b7d]{border-bottom:1px solid var(--color-border)}.section-title[data-v-959e3b7d]{align-items:center;gap:.625rem;transition:opacity .15s;display:flex}.section-icon[data-v-959e3b7d]{color:var(--color-text-muted);flex-shrink:0;font-size:1.125rem}.section-label[data-v-959e3b7d]{color:var(--color-text);font-size:.875rem;font-weight:600}.section-description[data-v-959e3b7d]{color:var(--color-text-muted);margin-top:.125rem;font-size:.75rem}.chevron[data-v-959e3b7d]{color:var(--color-text-subtle);flex-shrink:0;font-size:.875rem;transition:transform .2s cubic-bezier(.22,1,.36,1)}details[open] .chevron[data-v-959e3b7d]{color:var(--color-text-muted);transform:rotate(180deg)}.section-content[data-v-959e3b7d]{background:var(--color-surface-sunken);flex-direction:column;gap:.75rem;padding:1rem;display:flex}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
.devtools-snippet[data-v-97299906]{margin:.5rem .75rem}.devtools-snippet-header[data-v-97299906]{justify-content:space-between;align-items:center;margin-bottom:.375rem;display:flex}.devtools-snippet-label[data-v-97299906]{color:var(--color-text-muted);font-family:var(--font-mono);letter-spacing:-.01em;font-size:.6875rem;font-weight:500}.devtools-snippet-block[data-v-97299906]{border-radius:var(--radius-sm);max-height:300px;font-size:.6875rem;line-height:1.6;overflow-y:auto;padding:.5rem .625rem!important}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"id":"8d1f6507-8803-4bf0-b0a0-b07d9247f574","timestamp":1775803048648,"prerendered":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
.devtools-alert[data-v-9b9ce76b]{border-bottom:1px solid var(--color-border);align-items:center;gap:.5rem;padding:.5rem 1rem;font-size:.8125rem;display:flex}.devtools-alert-icon[data-v-9b9ce76b]{flex-shrink:0}.devtools-alert-content[data-v-9b9ce76b]{flex:1;min-width:0}.devtools-alert-action[data-v-9b9ce76b]{flex-shrink:0;margin-left:auto}.devtools-alert-info[data-v-9b9ce76b]{color:oklch(55% .12 230);background:oklch(85% .1 230/.1);border-bottom-color:oklch(75% .1 230/.2)}.dark .devtools-alert-info[data-v-9b9ce76b]{color:oklch(80% .1 230);background:oklch(45% .1 230/.15)}.devtools-alert-error[data-v-9b9ce76b]{color:oklch(52% .18 25);background:oklch(65% .18 25/.1);border-bottom-color:oklch(55% .15 25/.25)}.dark .devtools-alert-error[data-v-9b9ce76b]{color:oklch(75% .14 25);background:oklch(40% .14 25/.18)}.devtools-alert-warning[data-v-9b9ce76b]{color:oklch(55% .15 85);background:oklch(85% .12 85/.1);border-bottom-color:oklch(75% .12 85/.2)}.dark .devtools-alert-warning[data-v-9b9ce76b]{color:oklch(80% .12 85);background:oklch(45% .12 85/.15)}.devtools-alert-success[data-v-9b9ce76b]{color:oklch(50% .15 145);background:oklch(75% .15 145/.12);border-bottom-color:oklch(65% .12 145/.2)}.dark .devtools-alert-success[data-v-9b9ce76b]{color:oklch(75% .18 145);background:oklch(50% .15 145/.15)}.devtools-alert-production[data-v-9b9ce76b]{color:oklch(45% .15 145);background:oklch(85% .12 145/.1);border-bottom-color:oklch(75% .12 145/.2)}.dark .devtools-alert-production[data-v-9b9ce76b]{color:oklch(75% .12 145);background:oklch(35% .08 145/.15)}
|