nuxt-og-image 6.3.6 → 6.3.8
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/d4af52db-d87a-45fc-9901-69797a3ca24f.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/app/utils.js +3 -1
- 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.BWSGGMOE.mjs → nuxt-og-image.caStlBVv.mjs} +135 -4
- package/dist/shared/{nuxt-og-image.DD0uPnWP.cjs → nuxt-og-image.if6TuaSI.cjs} +136 -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/4bfaee23-0bae-4d94-b1da-6726b2c174f9.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';
|
|
@@ -98,8 +98,10 @@ export function createOgImageMeta(src, input, ssrContext, pagePath, head) {
|
|
|
98
98
|
if (component?.hash)
|
|
99
99
|
urlOpts._componentHash = component.hash;
|
|
100
100
|
const result = buildOgImageUrl(urlOpts, extension, isStatic, defaults, ogImageConfig.security?.secret || void 0);
|
|
101
|
-
if (result.hash)
|
|
101
|
+
if (result.hash) {
|
|
102
102
|
opts._hash = result.hash;
|
|
103
|
+
options._hash = result.hash;
|
|
104
|
+
}
|
|
103
105
|
const resolvedUrl = joinURL("/", baseURL, result.url);
|
|
104
106
|
const finalUrl = opts._query && Object.keys(opts._query).length ? withQuery(resolvedUrl, { _query: opts._query }) : resolvedUrl;
|
|
105
107
|
if (isStatic && import.meta.prerender && ssrContext.event) {
|
|
@@ -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) */
|
|
@@ -2240,6 +2240,7 @@ function setupPrerenderHandler(options, resolve, getDetectedRenderers, nuxt = us
|
|
|
2240
2240
|
orphanedOgHashes.push(route.route);
|
|
2241
2241
|
route.skip = true;
|
|
2242
2242
|
delete route.error;
|
|
2243
|
+
route.contents = "";
|
|
2243
2244
|
});
|
|
2244
2245
|
nitro.hooks.hook("prerender:done", async () => {
|
|
2245
2246
|
if (orphanedOgHashes.length > 0) {
|
|
@@ -2534,6 +2535,94 @@ const ATTRIBUTE_NODE = 6;
|
|
|
2534
2535
|
const DIRECTIVE_NODE = 7;
|
|
2535
2536
|
const RE_PURE_NUMBER = /^\d+(?:\.\d+)?$/;
|
|
2536
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
|
+
}
|
|
2537
2626
|
function escapeAttrValue(value) {
|
|
2538
2627
|
return value.replace(RE_DOUBLE_QUOTE, """);
|
|
2539
2628
|
}
|
|
@@ -2571,7 +2660,17 @@ async function transformVueTemplate(code, options) {
|
|
|
2571
2660
|
}
|
|
2572
2661
|
}
|
|
2573
2662
|
if (prop.type === DIRECTIVE_NODE && prop.name === "bind" && prop.arg?.content === "style") {
|
|
2574
|
-
|
|
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
|
+
}
|
|
2575
2674
|
}
|
|
2576
2675
|
if (prop.type === ATTRIBUTE_NODE && (prop.name === "width" || prop.name === "height") && prop.value && el.tag === "img") {
|
|
2577
2676
|
if (!collector.dimensionAttrs)
|
|
@@ -2579,7 +2678,7 @@ async function transformVueTemplate(code, options) {
|
|
|
2579
2678
|
collector.dimensionAttrs.push({ name: prop.name, value: prop.value.content });
|
|
2580
2679
|
}
|
|
2581
2680
|
}
|
|
2582
|
-
if (collector.classes.length > 0 || collector.existingStyle || collector.dimensionAttrs?.length) {
|
|
2681
|
+
if (collector.classes.length > 0 || collector.existingStyle || collector.dimensionAttrs?.length || collector.dynamicStyleProps) {
|
|
2583
2682
|
if (collector.existingStyle && !collector.styleLoc) {
|
|
2584
2683
|
logger.warn(`[vue-template-transform] BUG: existingStyle found but styleLoc is undefined!`);
|
|
2585
2684
|
}
|
|
@@ -2620,6 +2719,9 @@ async function transformVueTemplate(code, options) {
|
|
|
2620
2719
|
}
|
|
2621
2720
|
}
|
|
2622
2721
|
}
|
|
2722
|
+
if (collector.dynamicStyleProps) {
|
|
2723
|
+
Object.assign(styleProps, collector.dynamicStyleProps);
|
|
2724
|
+
}
|
|
2623
2725
|
if (styleProps.display === "flex" && !styleProps["flex-direction"]) {
|
|
2624
2726
|
styleProps["flex-direction"] = "row";
|
|
2625
2727
|
}
|
|
@@ -2628,7 +2730,8 @@ async function transformVueTemplate(code, options) {
|
|
|
2628
2730
|
const hasUnresolved = unresolvedClasses.length > 0;
|
|
2629
2731
|
const resolvedSome = collector.classes.length > 0 && (unresolvedClasses.length < collector.classes.length || hasClassRewrites);
|
|
2630
2732
|
const styleChanged = collector.existingStyle && styleStr !== collector.existingStyle;
|
|
2631
|
-
|
|
2733
|
+
const hasDynamicStyleResolved = collector.dynamicStyleProps && Object.keys(collector.dynamicStyleProps).length > 0;
|
|
2734
|
+
if (!resolvedSome && !styleChanged && !collector.dimensionAttrs?.length && !hasDynamicStyleResolved)
|
|
2632
2735
|
continue;
|
|
2633
2736
|
hasChanges = true;
|
|
2634
2737
|
if (collector.classLoc) {
|
|
@@ -2638,6 +2741,9 @@ async function transformVueTemplate(code, options) {
|
|
|
2638
2741
|
s.remove(collector.classLoc.start, collector.classLoc.end);
|
|
2639
2742
|
}
|
|
2640
2743
|
}
|
|
2744
|
+
if (collector.dynamicStyleLoc) {
|
|
2745
|
+
s.remove(collector.dynamicStyleLoc.start, collector.dynamicStyleLoc.end);
|
|
2746
|
+
}
|
|
2641
2747
|
if (hasResolvedStyles) {
|
|
2642
2748
|
if (collector.styleLoc) {
|
|
2643
2749
|
s.overwrite(collector.styleLoc.start, collector.styleLoc.end, `style="${styleStr}"`);
|
|
@@ -3549,6 +3655,7 @@ const REMOVED_CONFIG = {
|
|
|
3549
3655
|
"runtimeSatori": "compatibility.runtime.satori",
|
|
3550
3656
|
"cacheTtl": "cacheMaxAgeSeconds",
|
|
3551
3657
|
"cache": "cacheMaxAgeSeconds",
|
|
3658
|
+
"cacheQueryParams": "Removed (all options are encoded in the URL path)",
|
|
3552
3659
|
"cacheKey": "Removed",
|
|
3553
3660
|
"static": "zeroRuntime",
|
|
3554
3661
|
"chromium-node": "compatibility.runtime.browser: 'playwright'",
|
|
@@ -3670,6 +3777,7 @@ const DEPRECATED_CONFIG = {
|
|
|
3670
3777
|
runtimeSatori: "Use compatibility.runtime.satori",
|
|
3671
3778
|
cacheTtl: "Use cacheMaxAgeSeconds",
|
|
3672
3779
|
cache: "Use cacheMaxAgeSeconds",
|
|
3780
|
+
cacheQueryParams: "Removed (all options are encoded in the URL path)",
|
|
3673
3781
|
cacheKey: "Removed",
|
|
3674
3782
|
static: "Removed - use zeroRuntime",
|
|
3675
3783
|
fonts: "Use @nuxt/fonts module instead"
|
|
@@ -4216,6 +4324,10 @@ const module$1 = defineNuxtModule({
|
|
|
4216
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 }`).");
|
|
4217
4325
|
return;
|
|
4218
4326
|
}
|
|
4327
|
+
if (config.cacheMaxAgeSeconds != null) {
|
|
4328
|
+
config.defaults = config.defaults || {};
|
|
4329
|
+
config.defaults.cacheMaxAgeSeconds = config.cacheMaxAgeSeconds;
|
|
4330
|
+
}
|
|
4219
4331
|
if (config.debug && !nuxt.options.dev) {
|
|
4220
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.");
|
|
4221
4333
|
}
|
|
@@ -4621,6 +4733,26 @@ ${familyInfo}`);
|
|
|
4621
4733
|
route: "/_og/s/**",
|
|
4622
4734
|
handler: resolve(`${basePath}/image`)
|
|
4623
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
|
+
}
|
|
4624
4756
|
if (!nuxt.options.dev) {
|
|
4625
4757
|
nuxt.options.optimization.treeShake.composables.client["nuxt-og-image"] = [];
|
|
4626
4758
|
}
|
|
@@ -5071,7 +5203,6 @@ export const rootDir = ${JSON.stringify(nuxt.options.rootDir)}`;
|
|
|
5071
5203
|
colorPreference,
|
|
5072
5204
|
// @ts-expect-error runtime type
|
|
5073
5205
|
isNuxtContentDocumentDriven: !!nuxt.options.content?.documentDriven,
|
|
5074
|
-
cacheQueryParams: config.cacheQueryParams ?? false,
|
|
5075
5206
|
cssFramework: cssFramework || "none",
|
|
5076
5207
|
// Browser renderer config for cloudflare binding access
|
|
5077
5208
|
browser: typeof config.browser === "object" ? {
|
|
@@ -2260,6 +2260,7 @@ function setupPrerenderHandler(options, resolve, getDetectedRenderers, nuxt = ki
|
|
|
2260
2260
|
orphanedOgHashes.push(route.route);
|
|
2261
2261
|
route.skip = true;
|
|
2262
2262
|
delete route.error;
|
|
2263
|
+
route.contents = "";
|
|
2263
2264
|
});
|
|
2264
2265
|
nitro.hooks.hook("prerender:done", async () => {
|
|
2265
2266
|
if (orphanedOgHashes.length > 0) {
|
|
@@ -2554,6 +2555,94 @@ const ATTRIBUTE_NODE = 6;
|
|
|
2554
2555
|
const DIRECTIVE_NODE = 7;
|
|
2555
2556
|
const RE_PURE_NUMBER = /^\d+(?:\.\d+)?$/;
|
|
2556
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
|
+
}
|
|
2557
2646
|
function escapeAttrValue(value) {
|
|
2558
2647
|
return value.replace(RE_DOUBLE_QUOTE, """);
|
|
2559
2648
|
}
|
|
@@ -2591,7 +2680,17 @@ async function transformVueTemplate(code, options) {
|
|
|
2591
2680
|
}
|
|
2592
2681
|
}
|
|
2593
2682
|
if (prop.type === DIRECTIVE_NODE && prop.name === "bind" && prop.arg?.content === "style") {
|
|
2594
|
-
|
|
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
|
+
}
|
|
2595
2694
|
}
|
|
2596
2695
|
if (prop.type === ATTRIBUTE_NODE && (prop.name === "width" || prop.name === "height") && prop.value && el.tag === "img") {
|
|
2597
2696
|
if (!collector.dimensionAttrs)
|
|
@@ -2599,7 +2698,7 @@ async function transformVueTemplate(code, options) {
|
|
|
2599
2698
|
collector.dimensionAttrs.push({ name: prop.name, value: prop.value.content });
|
|
2600
2699
|
}
|
|
2601
2700
|
}
|
|
2602
|
-
if (collector.classes.length > 0 || collector.existingStyle || collector.dimensionAttrs?.length) {
|
|
2701
|
+
if (collector.classes.length > 0 || collector.existingStyle || collector.dimensionAttrs?.length || collector.dynamicStyleProps) {
|
|
2603
2702
|
if (collector.existingStyle && !collector.styleLoc) {
|
|
2604
2703
|
logger_js.logger.warn(`[vue-template-transform] BUG: existingStyle found but styleLoc is undefined!`);
|
|
2605
2704
|
}
|
|
@@ -2640,6 +2739,9 @@ async function transformVueTemplate(code, options) {
|
|
|
2640
2739
|
}
|
|
2641
2740
|
}
|
|
2642
2741
|
}
|
|
2742
|
+
if (collector.dynamicStyleProps) {
|
|
2743
|
+
Object.assign(styleProps, collector.dynamicStyleProps);
|
|
2744
|
+
}
|
|
2643
2745
|
if (styleProps.display === "flex" && !styleProps["flex-direction"]) {
|
|
2644
2746
|
styleProps["flex-direction"] = "row";
|
|
2645
2747
|
}
|
|
@@ -2648,7 +2750,8 @@ async function transformVueTemplate(code, options) {
|
|
|
2648
2750
|
const hasUnresolved = unresolvedClasses.length > 0;
|
|
2649
2751
|
const resolvedSome = collector.classes.length > 0 && (unresolvedClasses.length < collector.classes.length || hasClassRewrites);
|
|
2650
2752
|
const styleChanged = collector.existingStyle && styleStr !== collector.existingStyle;
|
|
2651
|
-
|
|
2753
|
+
const hasDynamicStyleResolved = collector.dynamicStyleProps && Object.keys(collector.dynamicStyleProps).length > 0;
|
|
2754
|
+
if (!resolvedSome && !styleChanged && !collector.dimensionAttrs?.length && !hasDynamicStyleResolved)
|
|
2652
2755
|
continue;
|
|
2653
2756
|
hasChanges = true;
|
|
2654
2757
|
if (collector.classLoc) {
|
|
@@ -2658,6 +2761,9 @@ async function transformVueTemplate(code, options) {
|
|
|
2658
2761
|
s.remove(collector.classLoc.start, collector.classLoc.end);
|
|
2659
2762
|
}
|
|
2660
2763
|
}
|
|
2764
|
+
if (collector.dynamicStyleLoc) {
|
|
2765
|
+
s.remove(collector.dynamicStyleLoc.start, collector.dynamicStyleLoc.end);
|
|
2766
|
+
}
|
|
2661
2767
|
if (hasResolvedStyles) {
|
|
2662
2768
|
if (collector.styleLoc) {
|
|
2663
2769
|
s.overwrite(collector.styleLoc.start, collector.styleLoc.end, `style="${styleStr}"`);
|
|
@@ -3569,6 +3675,7 @@ const REMOVED_CONFIG = {
|
|
|
3569
3675
|
"runtimeSatori": "compatibility.runtime.satori",
|
|
3570
3676
|
"cacheTtl": "cacheMaxAgeSeconds",
|
|
3571
3677
|
"cache": "cacheMaxAgeSeconds",
|
|
3678
|
+
"cacheQueryParams": "Removed (all options are encoded in the URL path)",
|
|
3572
3679
|
"cacheKey": "Removed",
|
|
3573
3680
|
"static": "zeroRuntime",
|
|
3574
3681
|
"chromium-node": "compatibility.runtime.browser: 'playwright'",
|
|
@@ -3690,6 +3797,7 @@ const DEPRECATED_CONFIG = {
|
|
|
3690
3797
|
runtimeSatori: "Use compatibility.runtime.satori",
|
|
3691
3798
|
cacheTtl: "Use cacheMaxAgeSeconds",
|
|
3692
3799
|
cache: "Use cacheMaxAgeSeconds",
|
|
3800
|
+
cacheQueryParams: "Removed (all options are encoded in the URL path)",
|
|
3693
3801
|
cacheKey: "Removed",
|
|
3694
3802
|
static: "Removed - use zeroRuntime",
|
|
3695
3803
|
fonts: "Use @nuxt/fonts module instead"
|
|
@@ -4206,7 +4314,7 @@ const module$1 = kit.defineNuxtModule({
|
|
|
4206
4314
|
await onUpgrade(nuxt, options, previousVersion);
|
|
4207
4315
|
},
|
|
4208
4316
|
async setup(config, nuxt) {
|
|
4209
|
-
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)));
|
|
4210
4318
|
const fixSharedPath = (p) => {
|
|
4211
4319
|
if (p.includes("/shared/runtime/"))
|
|
4212
4320
|
return p.replace("/shared/runtime/", "/runtime/");
|
|
@@ -4236,6 +4344,10 @@ const module$1 = kit.defineNuxtModule({
|
|
|
4236
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 }`).");
|
|
4237
4345
|
return;
|
|
4238
4346
|
}
|
|
4347
|
+
if (config.cacheMaxAgeSeconds != null) {
|
|
4348
|
+
config.defaults = config.defaults || {};
|
|
4349
|
+
config.defaults.cacheMaxAgeSeconds = config.cacheMaxAgeSeconds;
|
|
4350
|
+
}
|
|
4239
4351
|
if (config.debug && !nuxt.options.dev) {
|
|
4240
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.");
|
|
4241
4353
|
}
|
|
@@ -4641,6 +4753,26 @@ ${familyInfo}`);
|
|
|
4641
4753
|
route: "/_og/s/**",
|
|
4642
4754
|
handler: resolve(`${basePath}/image`)
|
|
4643
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
|
+
}
|
|
4644
4776
|
if (!nuxt.options.dev) {
|
|
4645
4777
|
nuxt.options.optimization.treeShake.composables.client["nuxt-og-image"] = [];
|
|
4646
4778
|
}
|
|
@@ -5091,7 +5223,6 @@ export const rootDir = ${JSON.stringify(nuxt.options.rootDir)}`;
|
|
|
5091
5223
|
colorPreference,
|
|
5092
5224
|
// @ts-expect-error runtime type
|
|
5093
5225
|
isNuxtContentDocumentDriven: !!nuxt.options.content?.documentDriven,
|
|
5094
|
-
cacheQueryParams: config.cacheQueryParams ?? false,
|
|
5095
5226
|
cssFramework: cssFramework || "none",
|
|
5096
5227
|
// Browser renderer config for cloudflare binding access
|
|
5097
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.8",
|
|
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}
|