New auto opengraph
This commit is contained in:
parent
6c43b4f81d
commit
a176f11e55
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "@matthiesenxyz/astro-ghostcms-theme-default",
|
||||
"description": "Default Theme for astro-ghostcms",
|
||||
"version": "0.1.6",
|
||||
"version": "0.1.7",
|
||||
"homepage": "https://astro-ghostcms.xyz/",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
|
@ -50,7 +50,7 @@
|
|||
"astro": "^4.2.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@matthiesenxyz/astro-ghostcms": "^3.1.5",
|
||||
"@matthiesenxyz/astro-ghostcms": "^3.1.6",
|
||||
"astro-font": "^0.0.77",
|
||||
"sass": "^1.70.0"
|
||||
}
|
||||
|
|
|
@ -15,6 +15,17 @@ export type Props = {
|
|||
permalink?: string;
|
||||
};
|
||||
|
||||
export const getOgImagePath = (filename: string = "index") => {
|
||||
if (filename.startsWith("/")) filename = filename.substring(1);
|
||||
if (filename.endsWith("/"))
|
||||
filename = filename.substring(0, filename.length - 1);
|
||||
if (filename === "") filename = "index";
|
||||
return `./open-graph/${filename}.png`;
|
||||
};
|
||||
|
||||
const ogImage = new URL(getOgImagePath(Astro.url.pathname), Astro.url.origin)
|
||||
.href;
|
||||
|
||||
const { content, permalink, image, settings, bodyClass = "" } = Astro.props as Props;
|
||||
const ghostAccentColor = settings.accent_color;
|
||||
---
|
||||
|
@ -58,14 +69,14 @@ const ghostAccentColor = settings.accent_color;
|
|||
<meta property="og:title" content={content?.title} />
|
||||
{permalink && <meta property="og:url" content={permalink} />}
|
||||
{content?.description && <meta property="og:description" content={content.description} />}
|
||||
{image && <meta property="og:image" content={image} />}
|
||||
<meta property="og:image" content={ogImage} />
|
||||
|
||||
<!-- Twitter -->
|
||||
<meta property="twitter:card" content="summary_large_image" />
|
||||
<meta property="twitter:title" content={content?.title} />
|
||||
{permalink && <meta property="twitter:url" content={permalink} />}
|
||||
{content?.description && <meta property="twitter:description" content={content.description} />}
|
||||
{image && <meta property="twitter:image" content={image} />}
|
||||
<meta property="twitter:image" content={ogImage} />
|
||||
|
||||
<!-- Link to the global style, or the file that imports constructs -->
|
||||
<link
|
||||
|
|
|
@ -26,6 +26,7 @@ const bodyClass = `post-template ${postClass}`;
|
|||
content={{ title: post.title, description: post.excerpt }}
|
||||
settings={settings}
|
||||
bodyClass={bodyClass}
|
||||
image={post.feature_image?post.feature_image:undefined}
|
||||
>
|
||||
{
|
||||
post.primary_author ? (
|
||||
|
|
|
@ -8,6 +8,8 @@ import { loadEnv } from 'vite';
|
|||
import { fromZodError } from "zod-validation-error";
|
||||
import { addVirtualImport } from "./src/utils/add-virtual-import";
|
||||
|
||||
export * from "./types.js"
|
||||
|
||||
/** INTERNAL CONSTANTS */
|
||||
const IC = {
|
||||
/** INTERNAL PACKAGE NAME */
|
||||
|
@ -139,6 +141,31 @@ export default function GhostCMS(options: UserConfig): AstroIntegration {
|
|||
});
|
||||
} else { if( !GCD.dCO ) { logger.info(IC.idRSS)}}
|
||||
|
||||
injectRoute({
|
||||
pattern: '/open-graph/[slug].png',
|
||||
entrypoint: `${IC.PKG}/open-graph/[slug].png.ts`
|
||||
});
|
||||
injectRoute({
|
||||
pattern: '/open-graph/index.png',
|
||||
entrypoint: `${IC.PKG}/open-graph/index.png.ts`
|
||||
});
|
||||
injectRoute({
|
||||
pattern: '/open-graph/authors.png',
|
||||
entrypoint: `${IC.PKG}/open-graph/authors.png.ts`
|
||||
});
|
||||
injectRoute({
|
||||
pattern: '/open-graph/author/[slug].png',
|
||||
entrypoint: `${IC.PKG}/open-graph/author/[slug].png.ts`
|
||||
});
|
||||
injectRoute({
|
||||
pattern: '/open-graph/tags.png',
|
||||
entrypoint: `${IC.PKG}/open-graph/tags.png.ts`
|
||||
});
|
||||
injectRoute({
|
||||
pattern: '/open-graph/tag/[slug].png',
|
||||
entrypoint: `${IC.PKG}/open-graph/tag/[slug].png.ts`
|
||||
});
|
||||
|
||||
// THEME ROUTES
|
||||
if( !GCD.dCO ) { logger.info( IC.ITR )}
|
||||
|
||||
|
@ -203,7 +230,15 @@ export default function GhostCMS(options: UserConfig): AstroIntegration {
|
|||
// FINAL STEP TO KEEP INTEGRATION LIVE
|
||||
try { updateConfig( {
|
||||
// UPDATE ASTRO CONFIG WITH INTEGRATED INTEGRATIONS
|
||||
integrations: [ ghostSitemap( GCD.SM ), ghostRobots( GCD.RTXT ) ],
|
||||
integrations: [
|
||||
ghostSitemap(GCD.SM),
|
||||
ghostRobots(GCD.RTXT)
|
||||
],
|
||||
vite: {
|
||||
optimizeDeps: {
|
||||
exclude: ["@resvg/resvg-js"],
|
||||
}
|
||||
}
|
||||
// LOAD VITE AND SETUP viteGhostCMS Configs
|
||||
}) } catch ( e ) {
|
||||
logger.error( e as string );
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "@matthiesenxyz/astro-ghostcms",
|
||||
"description": "Astro GhostCMS integration to allow easier importing of GhostCMS Content",
|
||||
"version": "3.1.5",
|
||||
"version": "3.1.6",
|
||||
"homepage": "https://astro-ghostcms.xyz/",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
|
@ -53,7 +53,13 @@
|
|||
"./404.astro": "./src/default-routes/404/404.astro",
|
||||
"./rss.xml.ts": "./src/default-routes/rss.xml.ts",
|
||||
"./config": "./src/integrations/virtual-config.ts",
|
||||
"./types": "./types.ts"
|
||||
"./types": "./types.ts",
|
||||
"./open-graph/[slug].png.ts": "./src/default-routes/open-graph/[slug].png.ts",
|
||||
"./open-graph/index.png.ts": "./src/default-routes/open-graph/index.png.ts",
|
||||
"./open-graph/authors.png.ts": "./src/default-routes/open-graph/authors.png.ts",
|
||||
"./open-graph/author/[slug].png.ts": "./src/default-routes/open-graph/author/[slug].png.ts",
|
||||
"./open-graph/tags.png.ts": "./src/default-routes/open-graph/tags.png.ts",
|
||||
"./open-graph/tag/[slug].png.ts": "./src/default-routes/open-graph/tag/[slug].png.ts"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "vitest run",
|
||||
|
@ -62,7 +68,7 @@
|
|||
"test:ci": "vitest run --coverage.enabled --coverage.reporter='text-summary'"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"astro": "^4.2.3"
|
||||
"astro": "^4.2.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@astrojs/check": "^0.4.1",
|
||||
|
@ -82,11 +88,14 @@
|
|||
"vitest-fetch-mock": "^0.2.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@matthiesenxyz/astro-ghostcms-theme-default": "^0.1.3",
|
||||
"@matthiesenxyz/astro-ghostcms-theme-default": "^0.1.7",
|
||||
"@astrojs/rss": "^4.0.4",
|
||||
"@astrojs/sitemap": "^3.0.5",
|
||||
"@resvg/resvg-js": "^2.6.0",
|
||||
"@ts-ghost/core-api": "^5.1.2",
|
||||
"astro-robots-txt": "^1.0.0",
|
||||
"satori": "^0.10.11",
|
||||
"satori-html": "^0.3.2",
|
||||
"vite": "^5.0.12",
|
||||
"vite-tsconfig-paths": "^4.2.2",
|
||||
"zod": "^3.22.4",
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
import type { APIRoute, GetStaticPaths, GetStaticPathsItem, InferGetStaticPropsType } from "astro";
|
||||
import { satoriOG } from "../../integrations/satori.js";
|
||||
import { html } from "satori-html";
|
||||
import { invariant, getAllPosts, getAllPages, getSettings } from "../../api/index.js";
|
||||
|
||||
export const getStaticPaths: GetStaticPaths = async () => {
|
||||
const result: GetStaticPathsItem[] = [];
|
||||
const [posts, pages, settings] = await Promise.all([getAllPosts(), await getAllPages(), await getSettings()]);
|
||||
const allPosts = [...posts, ...pages];
|
||||
invariant(settings, "Settings are required");
|
||||
|
||||
allPosts.map(allPosts => {
|
||||
result.push({
|
||||
params: {slug: allPosts.slug},
|
||||
props: {
|
||||
title: allPosts.title,
|
||||
image: allPosts.feature_image
|
||||
}
|
||||
})
|
||||
})
|
||||
return result
|
||||
}
|
||||
export type Props = InferGetStaticPropsType<typeof getStaticPaths>;
|
||||
|
||||
|
||||
export const GET: APIRoute = async ({ props, site}) => {
|
||||
const settings = await getSettings();
|
||||
invariant(settings, "Settings are required");
|
||||
const fontFile = await fetch(
|
||||
"https://og-playground.vercel.app/inter-latin-ext-700-normal.woff",
|
||||
);
|
||||
const fontData: ArrayBuffer = await fontFile.arrayBuffer();
|
||||
|
||||
return await satoriOG({
|
||||
template: html`<div style="display: flex; height: 100%; width: 100%; alignItems: center; justifyContent: center; letterSpacing: -.02em; fontWeight: 700; background: white;"> <div style="left: 24; top: 24; position: absolute; display: flex; alignItems: center;"> <img src=${settings.icon} width="82"/> <span style="marginLeft: 8; fontSize: 48;">${settings.title} - ${props.title}</span> </div> <div style=" display: flex; flexWrap: wrap; justifyContent: center; padding: 20px 50px; margin: 0 42px; fontSize: 40; width: 1700; height: 850; textAlign: center; backgroundColor: black; color: white; lineHeight: 1.4;"> <img src=${props.image?props.image:settings.twitter_image} width="100%" height="100%"/> </div> <div style="left: 24; bottom: 24; position: absolute; display: flex; alignItems: center;"> <span style="marginLeft: 8; fontSize: 48;">${site}</span> </div> </div>`,
|
||||
width: 1920,
|
||||
height: 1080,
|
||||
}).toResponse({
|
||||
satori: {
|
||||
fonts: [
|
||||
{
|
||||
name: "Inter Latin",
|
||||
data: fontData,
|
||||
style: "normal",
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
};
|
|
@ -0,0 +1,55 @@
|
|||
import type { APIRoute, GetStaticPaths, GetStaticPathsItem, InferGetStaticParamsType, InferGetStaticPropsType } from "astro";
|
||||
import { satoriOG } from "../../../integrations/satori.js";
|
||||
import { html } from "satori-html";
|
||||
import { invariant, getAllPosts, getSettings, getAllAuthors } from "../../../api/index.js";
|
||||
|
||||
export const getStaticPaths: GetStaticPaths = async () => {
|
||||
const result: GetStaticPathsItem[] = [];
|
||||
const posts = await getAllPosts();
|
||||
const { authors } = await getAllAuthors();
|
||||
invariant(authors, "Settings are required");
|
||||
const settings = await getSettings();
|
||||
invariant(settings, "Settings are required");
|
||||
|
||||
authors.map((author) => {
|
||||
const filteredPosts = posts.filter((post) =>
|
||||
post.authors?.map((author) => author.slug).includes(author.slug)
|
||||
);
|
||||
result.push( {
|
||||
params: { slug: author.slug },
|
||||
props: {
|
||||
posts: filteredPosts,
|
||||
settings,
|
||||
author,
|
||||
},
|
||||
});
|
||||
});
|
||||
return result;
|
||||
}
|
||||
export type Props = InferGetStaticPropsType<typeof getStaticPaths>;
|
||||
|
||||
|
||||
export const GET: APIRoute = async ({ props, site }) => {
|
||||
const settings = await getSettings();
|
||||
invariant(settings, "Settings are required");
|
||||
const fontFile = await fetch(
|
||||
"https://og-playground.vercel.app/inter-latin-ext-700-normal.woff",
|
||||
);
|
||||
const fontData: ArrayBuffer = await fontFile.arrayBuffer();
|
||||
|
||||
return await satoriOG({
|
||||
template: html`<div style="display: flex; height: 100%; width: 100%; alignItems: center; justifyContent: center; letterSpacing: -.02em; fontWeight: 700; background: white;"> <div style="left: 24; top: 24; position: absolute; display: flex; alignItems: center;"> <img src=${settings.icon} width="82"/> <span style="marginLeft: 8; fontSize: 48;">${settings.title} - ${props.author.name}</span> </div> <div style=" display: flex; flexWrap: wrap; justifyContent: center; padding: 20px 50px; margin: 0 42px; fontSize: 40; width: 1700; height: 850; textAlign: center; backgroundColor: black; color: white; lineHeight: 1.4;"> <img src=${props.author.profile_image} width="800" height="800"/> </div> <div style="left: 24; bottom: 24; position: absolute; display: flex; alignItems: center;"> <span style="marginLeft: 8; fontSize: 48;">${site}</span> </div> </div>`,
|
||||
width: 1920,
|
||||
height: 1080,
|
||||
}).toResponse({
|
||||
satori: {
|
||||
fonts: [
|
||||
{
|
||||
name: "Inter Latin",
|
||||
data: fontData,
|
||||
style: "normal",
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
};
|
|
@ -0,0 +1,49 @@
|
|||
import type { APIRoute, GetStaticPaths, GetStaticPathsItem, InferGetStaticPropsType } from "astro";
|
||||
import { satoriOG } from "../../integrations/satori.js";
|
||||
import { html } from "satori-html";
|
||||
import { invariant, getAllPosts, getAllPages, getSettings } from "../../api/index.js";
|
||||
|
||||
export const getStaticPaths: GetStaticPaths = async () => {
|
||||
const result: GetStaticPathsItem[] = [];
|
||||
const [posts, pages, settings] = await Promise.all([getAllPosts(), await getAllPages(), await getSettings()]);
|
||||
const allPosts = [...posts, ...pages];
|
||||
invariant(settings, "Settings are required");
|
||||
|
||||
allPosts.map(allPosts => {
|
||||
result.push({
|
||||
params: {slug: allPosts.slug},
|
||||
props: {
|
||||
title: allPosts.title,
|
||||
image: allPosts.feature_image
|
||||
}
|
||||
})
|
||||
})
|
||||
return result
|
||||
}
|
||||
export type Props = InferGetStaticPropsType<typeof getStaticPaths>;
|
||||
|
||||
|
||||
export const GET: APIRoute = async ({ props, site}) => {
|
||||
const settings = await getSettings();
|
||||
invariant(settings, "Settings are required");
|
||||
const fontFile = await fetch(
|
||||
"https://og-playground.vercel.app/inter-latin-ext-700-normal.woff",
|
||||
);
|
||||
const fontData: ArrayBuffer = await fontFile.arrayBuffer();
|
||||
|
||||
return await satoriOG({
|
||||
template: html`<div style="display: flex; height: 100%; width: 100%; alignItems: center; justifyContent: center; letterSpacing: -.02em; fontWeight: 700; background: white;"> <div style="left: 24; top: 24; position: absolute; display: flex; alignItems: center;"> <img src=${settings.icon} width="82"/> <span style="marginLeft: 8; fontSize: 48;">${settings.title} - Authors</span> </div> <div style=" display: flex; flexWrap: wrap; justifyContent: center; padding: 20px 50px; margin: 0 42px; fontSize: 40; width: 1700; height: 850; textAlign: center; backgroundColor: black; color: white; lineHeight: 1.4;"> <img src=${settings.cover_image?settings.cover_image:settings.twitter_image} width="100%" height="100%"/> </div> <div style="left: 24; bottom: 24; position: absolute; display: flex; alignItems: center;"> <span style="marginLeft: 8; fontSize: 48;">${site}</span> </div> </div>`,
|
||||
width: 1920,
|
||||
height: 1080,
|
||||
}).toResponse({
|
||||
satori: {
|
||||
fonts: [
|
||||
{
|
||||
name: "Inter Latin",
|
||||
data: fontData,
|
||||
style: "normal",
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
};
|
|
@ -0,0 +1,49 @@
|
|||
import type { APIRoute, GetStaticPaths, GetStaticPathsItem, InferGetStaticPropsType } from "astro";
|
||||
import { satoriOG } from "../../integrations/satori.js";
|
||||
import { html } from "satori-html";
|
||||
import { invariant, getAllPosts, getAllPages, getSettings } from "../../api/index.js";
|
||||
|
||||
export const getStaticPaths: GetStaticPaths = async () => {
|
||||
const result: GetStaticPathsItem[] = [];
|
||||
const [posts, pages, settings] = await Promise.all([getAllPosts(), await getAllPages(), await getSettings()]);
|
||||
const allPosts = [...posts, ...pages];
|
||||
invariant(settings, "Settings are required");
|
||||
|
||||
allPosts.map(allPosts => {
|
||||
result.push({
|
||||
params: {slug: allPosts.slug},
|
||||
props: {
|
||||
title: allPosts.title,
|
||||
image: allPosts.feature_image
|
||||
}
|
||||
})
|
||||
})
|
||||
return result
|
||||
}
|
||||
export type Props = InferGetStaticPropsType<typeof getStaticPaths>;
|
||||
|
||||
|
||||
export const GET: APIRoute = async ({ props, site}) => {
|
||||
const settings = await getSettings();
|
||||
invariant(settings, "Settings are required");
|
||||
const fontFile = await fetch(
|
||||
"https://og-playground.vercel.app/inter-latin-ext-700-normal.woff",
|
||||
);
|
||||
const fontData: ArrayBuffer = await fontFile.arrayBuffer();
|
||||
|
||||
return await satoriOG({
|
||||
template: html`<div style="display: flex; height: 100%; width: 100%; alignItems: center; justifyContent: center; letterSpacing: -.02em; fontWeight: 700; background: white;"> <div style="left: 24; top: 24; position: absolute; display: flex; alignItems: center;"> <img src=${settings.icon} width="82"/> <span style="marginLeft: 8; fontSize: 48;">${settings.title} - Index</span> </div> <div style=" display: flex; flexWrap: wrap; justifyContent: center; padding: 20px 50px; margin: 0 42px; fontSize: 40; width: 1700; height: 850; textAlign: center; backgroundColor: black; color: white; lineHeight: 1.4;"> <img src=${settings.cover_image?settings.cover_image:settings.twitter_image} width="100%" height="100%"/> </div> <div style="left: 24; bottom: 24; position: absolute; display: flex; alignItems: center;"> <span style="marginLeft: 8; fontSize: 48;">${site}</span> </div> </div>`,
|
||||
width: 1920,
|
||||
height: 1080,
|
||||
}).toResponse({
|
||||
satori: {
|
||||
fonts: [
|
||||
{
|
||||
name: "Inter Latin",
|
||||
data: fontData,
|
||||
style: "normal",
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
};
|
|
@ -0,0 +1,54 @@
|
|||
import type { APIRoute, GetStaticPaths, GetStaticPathsItem, InferGetStaticPropsType } from "astro";
|
||||
import { satoriOG } from "../../../integrations/satori.js";
|
||||
import { html } from "satori-html";
|
||||
import { invariant, getAllPosts, getSettings, getAllTags } from "../../../api/index.js";
|
||||
|
||||
export const getStaticPaths: GetStaticPaths = async () => {
|
||||
const result: GetStaticPathsItem[] = [];
|
||||
const posts = await getAllPosts();
|
||||
const { tags } = await getAllTags();
|
||||
const settings = await getSettings();
|
||||
invariant(settings, "Settings are required");
|
||||
|
||||
tags.map((tag) => {
|
||||
const filteredPosts = posts.filter((post) =>
|
||||
post.tags?.map((tag) => tag.slug).includes(tag.slug)
|
||||
);
|
||||
result.push( {
|
||||
params: { slug: tag.slug },
|
||||
props: {
|
||||
posts: filteredPosts,
|
||||
settings,
|
||||
tag,
|
||||
},
|
||||
});
|
||||
});
|
||||
return result;
|
||||
}
|
||||
export type Props = InferGetStaticPropsType<typeof getStaticPaths>;
|
||||
|
||||
|
||||
export const GET: APIRoute = async ({ props, site}) => {
|
||||
const settings = await getSettings();
|
||||
invariant(settings, "Settings are required");
|
||||
const fontFile = await fetch(
|
||||
"https://og-playground.vercel.app/inter-latin-ext-700-normal.woff",
|
||||
);
|
||||
const fontData: ArrayBuffer = await fontFile.arrayBuffer();
|
||||
|
||||
return await satoriOG({
|
||||
template: html`<div style="display: flex; height: 100%; width: 100%; alignItems: center; justifyContent: center; letterSpacing: -.02em; fontWeight: 700; background: white;"> <div style="left: 24; top: 24; position: absolute; display: flex; alignItems: center;"> <img src=${settings.icon} width="82"/> <span style="marginLeft: 8; fontSize: 48;">${settings.title} - Tag: ${props.tag.name}</span> </div> <div style=" display: flex; flexWrap: wrap; justifyContent: center; padding: 20px 50px; margin: 0 42px; fontSize: 40; width: 1700; height: 850; textAlign: center; backgroundColor: black; color: white; lineHeight: 1.4;"> <img src=${settings.cover_image?settings.cover_image:settings.twitter_image} width="100%" height="100%"/> </div> <div style="left: 24; bottom: 24; position: absolute; display: flex; alignItems: center;"> <span style="marginLeft: 8; fontSize: 48;">${site}</span> </div> </div>`,
|
||||
width: 1920,
|
||||
height: 1080,
|
||||
}).toResponse({
|
||||
satori: {
|
||||
fonts: [
|
||||
{
|
||||
name: "Inter Latin",
|
||||
data: fontData,
|
||||
style: "normal",
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
};
|
|
@ -0,0 +1,49 @@
|
|||
import type { APIRoute, GetStaticPaths, GetStaticPathsItem, InferGetStaticPropsType } from "astro";
|
||||
import { satoriOG } from "../../integrations/satori.js";
|
||||
import { html } from "satori-html";
|
||||
import { invariant, getAllPosts, getAllPages, getSettings } from "../../api/index.js";
|
||||
|
||||
export const getStaticPaths: GetStaticPaths = async () => {
|
||||
const result: GetStaticPathsItem[] = [];
|
||||
const [posts, pages, settings] = await Promise.all([getAllPosts(), await getAllPages(), await getSettings()]);
|
||||
const allPosts = [...posts, ...pages];
|
||||
invariant(settings, "Settings are required");
|
||||
|
||||
allPosts.map(allPosts => {
|
||||
result.push({
|
||||
params: {slug: allPosts.slug},
|
||||
props: {
|
||||
title: allPosts.title,
|
||||
image: allPosts.feature_image
|
||||
}
|
||||
})
|
||||
})
|
||||
return result
|
||||
}
|
||||
export type Props = InferGetStaticPropsType<typeof getStaticPaths>;
|
||||
|
||||
|
||||
export const GET: APIRoute = async ({ props, site}) => {
|
||||
const settings = await getSettings();
|
||||
invariant(settings, "Settings are required");
|
||||
const fontFile = await fetch(
|
||||
"https://og-playground.vercel.app/inter-latin-ext-700-normal.woff",
|
||||
);
|
||||
const fontData: ArrayBuffer = await fontFile.arrayBuffer();
|
||||
|
||||
return await satoriOG({
|
||||
template: html`<div style="display: flex; height: 100%; width: 100%; alignItems: center; justifyContent: center; letterSpacing: -.02em; fontWeight: 700; background: white;"> <div style="left: 24; top: 24; position: absolute; display: flex; alignItems: center;"> <img src=${settings.icon} width="82"/> <span style="marginLeft: 8; fontSize: 48;">${settings.title} - Tags</span> </div> <div style=" display: flex; flexWrap: wrap; justifyContent: center; padding: 20px 50px; margin: 0 42px; fontSize: 40; width: 1700; height: 850; textAlign: center; backgroundColor: black; color: white; lineHeight: 1.4;"> <img src=${settings.cover_image?settings.cover_image:settings.twitter_image} width="100%" height="100%"/> </div> <div style="left: 24; bottom: 24; position: absolute; display: flex; alignItems: center;"> <span style="marginLeft: 8; fontSize: 48;">${site}</span> </div> </div>`,
|
||||
width: 1920,
|
||||
height: 1080,
|
||||
}).toResponse({
|
||||
satori: {
|
||||
fonts: [
|
||||
{
|
||||
name: "Inter Latin",
|
||||
data: fontData,
|
||||
style: "normal",
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
};
|
|
@ -0,0 +1,49 @@
|
|||
import { Resvg } from "@resvg/resvg-js";
|
||||
import satori from "satori";
|
||||
import type {
|
||||
SatoriAstroOGOptions,
|
||||
ToSvgOptions,
|
||||
ToImageOptions,
|
||||
ToResponseOptions,
|
||||
} from "../../types.js";
|
||||
|
||||
export const satoriOG = ({
|
||||
width,
|
||||
height,
|
||||
template,
|
||||
}: SatoriAstroOGOptions) => {
|
||||
return {
|
||||
async toSvg(options: ToSvgOptions) {
|
||||
return await satori(template, { width, height, ...options });
|
||||
},
|
||||
async toImage({
|
||||
satori: satoriOptions,
|
||||
resvg: _resvgOptions,
|
||||
}: ToImageOptions) {
|
||||
const resvgOptions =
|
||||
typeof _resvgOptions === "function"
|
||||
? _resvgOptions({ width, height })
|
||||
: _resvgOptions;
|
||||
|
||||
return new Resvg(await this.toSvg(satoriOptions), {
|
||||
fitTo: { mode: "width", value: width },
|
||||
...resvgOptions,
|
||||
})
|
||||
.render()
|
||||
.asPng();
|
||||
},
|
||||
async toResponse({ response: init, ...rest }: ToResponseOptions) {
|
||||
const image = await this.toImage(rest);
|
||||
|
||||
return new Response(image, {
|
||||
...init,
|
||||
headers: {
|
||||
"Content-Type": "image/png",
|
||||
"Content-Length": image.length.toString(),
|
||||
"Cache-Control": "public, max-age=31536000, immutable",
|
||||
...init?.headers,
|
||||
},
|
||||
});
|
||||
},
|
||||
};
|
||||
};
|
|
@ -1,3 +1,6 @@
|
|||
import type { Resvg } from "@resvg/resvg-js";
|
||||
import type satori from "satori";
|
||||
|
||||
export type { UserConfig } from './src/schemas';
|
||||
|
||||
export type {
|
||||
|
@ -8,3 +11,22 @@ export type {
|
|||
|
||||
|
||||
export type { ContentAPICredentials, APIVersions } from "@ts-ghost/core-api";
|
||||
|
||||
type SatoriParameters = Parameters<typeof satori>;
|
||||
type SatoriOptions = SatoriParameters[1];
|
||||
type ResvgOptions = NonNullable<ConstructorParameters<typeof Resvg>[1]>;
|
||||
|
||||
export type SatoriAstroOGOptions = {
|
||||
template: SatoriParameters[0];
|
||||
width: number;
|
||||
height: number;
|
||||
};
|
||||
|
||||
export type ToSvgOptions = Omit<SatoriOptions, "width" | "height">;
|
||||
export type ToImageOptions = {
|
||||
satori: ToSvgOptions;
|
||||
resvg?:
|
||||
| ResvgOptions
|
||||
| ((params: { width: number; height: number }) => ResvgOptions);
|
||||
};
|
||||
export type ToResponseOptions = ToImageOptions & { response?: ResponseInit };
|
267
pnpm-lock.yaml
267
pnpm-lock.yaml
|
@ -27,7 +27,7 @@ importers:
|
|||
specifier: 3.1.5
|
||||
version: link:../packages/astro-ghostcms
|
||||
'@matthiesenxyz/astro-ghostcms-theme-default':
|
||||
specifier: 0.1.5
|
||||
specifier: 0.1.6
|
||||
version: link:../packages/astro-ghostcms-theme-default
|
||||
astro:
|
||||
specifier: ^4.2.6
|
||||
|
@ -51,15 +51,24 @@ importers:
|
|||
'@matthiesenxyz/astro-ghostcms-theme-default':
|
||||
specifier: ^0.1.3
|
||||
version: link:../astro-ghostcms-theme-default
|
||||
'@resvg/resvg-js':
|
||||
specifier: ^2.6.0
|
||||
version: 2.6.0
|
||||
'@ts-ghost/core-api':
|
||||
specifier: ^5.1.2
|
||||
version: 5.1.2
|
||||
astro:
|
||||
specifier: ^4.2.3
|
||||
version: 4.2.4(@types/node@20.11.10)(typescript@5.3.3)
|
||||
specifier: ^4.2.6
|
||||
version: 4.2.6(@types/node@20.11.10)(typescript@5.3.3)
|
||||
astro-robots-txt:
|
||||
specifier: ^1.0.0
|
||||
version: 1.0.0
|
||||
satori:
|
||||
specifier: ^0.10.11
|
||||
version: 0.10.13
|
||||
satori-html:
|
||||
specifier: ^0.3.2
|
||||
version: 0.3.2
|
||||
vite:
|
||||
specifier: ^5.0.12
|
||||
version: 5.0.12(@types/node@20.11.10)
|
||||
|
@ -1592,6 +1601,132 @@ packages:
|
|||
engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
|
||||
dev: true
|
||||
|
||||
/@resvg/resvg-js-android-arm-eabi@2.6.0:
|
||||
resolution: {integrity: sha512-lJnZ/2P5aMocrFMW7HWhVne5gH82I8xH6zsfH75MYr4+/JOaVcGCTEQ06XFohGMdYRP3v05SSPLPvTM/RHjxfA==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm]
|
||||
os: [android]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@resvg/resvg-js-android-arm64@2.6.0:
|
||||
resolution: {integrity: sha512-N527f529bjMwYWShZYfBD60dXA4Fux+D695QsHQ93BDYZSHUoOh1CUGUyICevnTxs7VgEl98XpArmUWBZQVMfQ==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [android]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@resvg/resvg-js-darwin-arm64@2.6.0:
|
||||
resolution: {integrity: sha512-MabUKLVayEwlPo0mIqAmMt+qESN8LltCvv5+GLgVga1avpUrkxj/fkU1TKm8kQegutUjbP/B0QuMuUr0uhF8ew==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@resvg/resvg-js-darwin-x64@2.6.0:
|
||||
resolution: {integrity: sha512-zrFetdnSw/suXjmyxSjfDV7i61hahv6DDG6kM7BYN2yJ3Es5+BZtqYZTcIWogPJedYKmzN1YTMWGd/3f0ubFiA==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@resvg/resvg-js-linux-arm-gnueabihf@2.6.0:
|
||||
resolution: {integrity: sha512-sH4gxXt7v7dGwjGyzLwn7SFGvwZG6DQqLaZ11MmzbCwd9Zosy1TnmrMJfn6TJ7RHezmQMgBPi18bl55FZ1AT4A==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@resvg/resvg-js-linux-arm64-gnu@2.6.0:
|
||||
resolution: {integrity: sha512-fCyMncqCJtrlANADIduYF4IfnWQ295UKib7DAxFXQhBsM9PLDTpizr0qemZcCNadcwSVHnAIzL4tliZhCM8P6A==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@resvg/resvg-js-linux-arm64-musl@2.6.0:
|
||||
resolution: {integrity: sha512-ouLjTgBQHQyxLht4FdMPTvuY8xzJigM9EM2Tlu0llWkN1mKyTQrvYWi6TA6XnKdzDJHy7ZLpWpjZi7F5+Pg+Vg==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@resvg/resvg-js-linux-x64-gnu@2.6.0:
|
||||
resolution: {integrity: sha512-n3zC8DWsvxC1AwxpKFclIPapDFibs5XdIRoV/mcIlxlh0vseW1F49b97F33BtJQRmlntsqqN6GMMqx8byB7B+Q==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@resvg/resvg-js-linux-x64-musl@2.6.0:
|
||||
resolution: {integrity: sha512-n4tasK1HOlAxdTEROgYA1aCfsEKk0UOFDNd/AQTTZlTmCbHKXPq+O8npaaKlwXquxlVK8vrkcWbksbiGqbCAcw==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@resvg/resvg-js-win32-arm64-msvc@2.6.0:
|
||||
resolution: {integrity: sha512-X2+EoBJFwDI5LDVb51Sk7ldnVLitMGr9WwU/i21i3fAeAXZb3hM16k67DeTy16OYkT2dk/RfU1tP1wG+rWbz2Q==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@resvg/resvg-js-win32-ia32-msvc@2.6.0:
|
||||
resolution: {integrity: sha512-L7oevWjQoUgK5W1fCKn0euSVemhDXVhrjtwqpc7MwBKKimYeiOshO1Li1pa8bBt5PESahenhWgdB6lav9O0fEg==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [ia32]
|
||||
os: [win32]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@resvg/resvg-js-win32-x64-msvc@2.6.0:
|
||||
resolution: {integrity: sha512-8lJlghb+Unki5AyKgsnFbRJwkEj9r1NpwyuBG8yEJiG1W9eEGl03R3I7bsVa3haof/3J1NlWf0rzSa1G++A2iw==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@resvg/resvg-js@2.6.0:
|
||||
resolution: {integrity: sha512-Tf3YpbBKcQn991KKcw/vg7vZf98v01seSv6CVxZBbRkL/xyjnoYB6KgrFL6zskT1A4dWC/vg77KyNOW+ePaNlA==}
|
||||
engines: {node: '>= 10'}
|
||||
optionalDependencies:
|
||||
'@resvg/resvg-js-android-arm-eabi': 2.6.0
|
||||
'@resvg/resvg-js-android-arm64': 2.6.0
|
||||
'@resvg/resvg-js-darwin-arm64': 2.6.0
|
||||
'@resvg/resvg-js-darwin-x64': 2.6.0
|
||||
'@resvg/resvg-js-linux-arm-gnueabihf': 2.6.0
|
||||
'@resvg/resvg-js-linux-arm64-gnu': 2.6.0
|
||||
'@resvg/resvg-js-linux-arm64-musl': 2.6.0
|
||||
'@resvg/resvg-js-linux-x64-gnu': 2.6.0
|
||||
'@resvg/resvg-js-linux-x64-musl': 2.6.0
|
||||
'@resvg/resvg-js-win32-arm64-msvc': 2.6.0
|
||||
'@resvg/resvg-js-win32-ia32-msvc': 2.6.0
|
||||
'@resvg/resvg-js-win32-x64-msvc': 2.6.0
|
||||
dev: false
|
||||
|
||||
/@rollup/rollup-android-arm-eabi@4.9.6:
|
||||
resolution: {integrity: sha512-MVNXSSYN6QXOulbHpLMKYi60ppyO13W9my1qogeiAqtjb2yR4LSmfU2+POvDkLzhjYLXz9Rf9+9a3zFHW1Lecg==}
|
||||
cpu: [arm]
|
||||
|
@ -1683,6 +1818,15 @@ packages:
|
|||
requiresBuild: true
|
||||
optional: true
|
||||
|
||||
/@shuding/opentype.js@1.4.0-beta.0:
|
||||
resolution: {integrity: sha512-3NgmNyH3l/Hv6EvsWJbsvpcpUba6R8IREQ83nH83cyakCw7uM1arZKNfHwv1Wz6jgqrF/j4x5ELvR6PnK9nTcA==}
|
||||
engines: {node: '>= 8.0.0'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
fflate: 0.7.4
|
||||
string.prototype.codepointat: 0.2.1
|
||||
dev: false
|
||||
|
||||
/@sinclair/typebox@0.27.8:
|
||||
resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==}
|
||||
dev: true
|
||||
|
@ -2416,8 +2560,8 @@ packages:
|
|||
- typescript
|
||||
dev: false
|
||||
|
||||
/astro@4.2.4(@types/node@20.11.10)(typescript@5.3.3):
|
||||
resolution: {integrity: sha512-z1f52lXkHf71M5HSLKrd5G1PH5/Zfq4kMp0iUT7Na5VHcPDma/NYFPFPewDxqV6UPmyxupj3xuooFaN3j8zaow==}
|
||||
/astro@4.2.6(@types/node@20.11.10)(typescript@5.3.3):
|
||||
resolution: {integrity: sha512-k5i8pEI2r45JTkoE0I4JyhOH/dZFpjUA4AONbRd9Gr1LtnGOhKHDftiYOrRLUGx91q7BzoW3DOk+h4yZM4yC3g==}
|
||||
engines: {node: '>=18.14.1', npm: '>=6.14.0'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
|
@ -2441,6 +2585,7 @@ packages:
|
|||
clsx: 2.1.0
|
||||
common-ancestor-path: 1.0.1
|
||||
cookie: 0.6.0
|
||||
cssesc: 3.0.0
|
||||
debug: 4.3.4
|
||||
deterministic-object-hash: 2.0.2
|
||||
devalue: 4.3.2
|
||||
|
@ -2620,6 +2765,11 @@ packages:
|
|||
resolution: {integrity: sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==}
|
||||
dev: false
|
||||
|
||||
/base64-js@0.0.8:
|
||||
resolution: {integrity: sha512-3XSA2cR/h/73EzlXXdU6YNycmYI7+kicTxks4eJg2g39biHR84slg2+des+p7iHYhbRg/udIS4TD53WabcOUkw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
dev: false
|
||||
|
||||
/base64-js@1.5.1:
|
||||
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
|
||||
dev: false
|
||||
|
@ -2772,6 +2922,10 @@ packages:
|
|||
engines: {node: '>=14.16'}
|
||||
dev: false
|
||||
|
||||
/camelize@1.0.1:
|
||||
resolution: {integrity: sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==}
|
||||
dev: false
|
||||
|
||||
/caniuse-lite@1.0.30001579:
|
||||
resolution: {integrity: sha512-u5AUVkixruKHJjw/pj9wISlcMpgFWzSrczLZbrqBSxukQixmg0SJ5sZTpvaFvxU0HoQKd4yoyAogyrAz9pzJnA==}
|
||||
dev: false
|
||||
|
@ -2996,10 +3150,31 @@ packages:
|
|||
shebang-command: 2.0.0
|
||||
which: 2.0.2
|
||||
|
||||
/css-background-parser@0.1.0:
|
||||
resolution: {integrity: sha512-2EZLisiZQ+7m4wwur/qiYJRniHX4K5Tc9w93MT3AS0WS1u5kaZ4FKXlOTBhOjc+CgEgPiGY+fX1yWD8UwpEqUA==}
|
||||
dev: false
|
||||
|
||||
/css-box-shadow@1.0.0-3:
|
||||
resolution: {integrity: sha512-9jaqR6e7Ohds+aWwmhe6wILJ99xYQbfmK9QQB9CcMjDbTxPZjwEmUQpU91OG05Xgm8BahT5fW+svbsQGjS/zPg==}
|
||||
dev: false
|
||||
|
||||
/css-color-keywords@1.0.0:
|
||||
resolution: {integrity: sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==}
|
||||
engines: {node: '>=4'}
|
||||
dev: false
|
||||
|
||||
/css-selector-parser@3.0.4:
|
||||
resolution: {integrity: sha512-pnmS1dbKsz6KA4EW4BznyPL2xxkNDRg62hcD0v8g6DEw2W7hxOln5M953jsp9hmw5Dg57S6o/A8GOn37mbAgcQ==}
|
||||
dev: false
|
||||
|
||||
/css-to-react-native@3.2.0:
|
||||
resolution: {integrity: sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==}
|
||||
dependencies:
|
||||
camelize: 1.0.1
|
||||
css-color-keywords: 1.0.0
|
||||
postcss-value-parser: 4.2.0
|
||||
dev: false
|
||||
|
||||
/cssesc@3.0.0:
|
||||
resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
|
||||
engines: {node: '>=4'}
|
||||
|
@ -3372,6 +3547,10 @@ packages:
|
|||
resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
/escape-html@1.0.3:
|
||||
resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==}
|
||||
dev: false
|
||||
|
||||
/escape-string-regexp@1.0.5:
|
||||
resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==}
|
||||
engines: {node: '>=0.8.0'}
|
||||
|
@ -3756,6 +3935,10 @@ packages:
|
|||
dependencies:
|
||||
reusify: 1.0.4
|
||||
|
||||
/fflate@0.7.4:
|
||||
resolution: {integrity: sha512-5u2V/CDW15QM1XbbgS+0DfPxVB+jUKhWEKuuFuHncbk3tEEqzmoXL+2KyOFuKGqOnmdIy0/davWF1CkuwtibCw==}
|
||||
dev: false
|
||||
|
||||
/file-entry-cache@6.0.1:
|
||||
resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==}
|
||||
engines: {node: ^10.12.0 || >=12.0.0}
|
||||
|
@ -4312,6 +4495,11 @@ packages:
|
|||
space-separated-tokens: 2.0.2
|
||||
dev: false
|
||||
|
||||
/hex-rgb@4.3.0:
|
||||
resolution: {integrity: sha512-Ox1pJVrDCyGHMG9CFg1tmrRUMRPRsAWYc/PinY0XzJU4K7y7vjNoLKIQ7BR5UJMCxNN8EM1MNDmHWA/B3aZUuw==}
|
||||
engines: {node: '>=6'}
|
||||
dev: false
|
||||
|
||||
/hosted-git-info@2.8.9:
|
||||
resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==}
|
||||
|
||||
|
@ -4742,6 +4930,13 @@ packages:
|
|||
type-check: 0.4.0
|
||||
dev: true
|
||||
|
||||
/linebreak@1.1.0:
|
||||
resolution: {integrity: sha512-MHp03UImeVhB7XZtjd0E4n6+3xr5Dq/9xI/5FptGk5FrbDR3zagPa2DS6U8ks/3HjbKWG9Q1M2ufOzxV2qLYSQ==}
|
||||
dependencies:
|
||||
base64-js: 0.0.8
|
||||
unicode-trie: 2.0.0
|
||||
dev: false
|
||||
|
||||
/lines-and-columns@1.2.4:
|
||||
resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
|
||||
|
||||
|
@ -5785,6 +5980,10 @@ packages:
|
|||
'@pagefind/windows-x64': 1.0.4
|
||||
dev: false
|
||||
|
||||
/pako@0.2.9:
|
||||
resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==}
|
||||
dev: false
|
||||
|
||||
/parent-module@1.0.1:
|
||||
resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
|
||||
engines: {node: '>=6'}
|
||||
|
@ -5792,6 +5991,13 @@ packages:
|
|||
callsites: 3.1.0
|
||||
dev: true
|
||||
|
||||
/parse-css-color@0.2.1:
|
||||
resolution: {integrity: sha512-bwS/GGIFV3b6KS4uwpzCFj4w297Yl3uqnSgIPsoQkx7GMLROXfMnWvxfNkL0oh8HVhZA4hvJoEoEIqonfJ3BWg==}
|
||||
dependencies:
|
||||
color-name: 1.1.4
|
||||
hex-rgb: 4.3.0
|
||||
dev: false
|
||||
|
||||
/parse-entities@4.0.1:
|
||||
resolution: {integrity: sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==}
|
||||
dependencies:
|
||||
|
@ -5922,6 +6128,10 @@ packages:
|
|||
cssesc: 3.0.0
|
||||
util-deprecate: 1.0.2
|
||||
|
||||
/postcss-value-parser@4.2.0:
|
||||
resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
|
||||
dev: false
|
||||
|
||||
/postcss@8.4.33:
|
||||
resolution: {integrity: sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg==}
|
||||
engines: {node: ^10 || ^12 || >=14}
|
||||
|
@ -6401,6 +6611,28 @@ packages:
|
|||
immutable: 4.3.4
|
||||
source-map-js: 1.0.2
|
||||
|
||||
/satori-html@0.3.2:
|
||||
resolution: {integrity: sha512-wjTh14iqADFKDK80e51/98MplTGfxz2RmIzh0GqShlf4a67+BooLywF17TvJPD6phO0Hxm7Mf1N5LtRYvdkYRA==}
|
||||
dependencies:
|
||||
ultrahtml: 1.5.2
|
||||
dev: false
|
||||
|
||||
/satori@0.10.13:
|
||||
resolution: {integrity: sha512-klCwkVYMQ/ZN5inJLHzrUmGwoRfsdP7idB5hfpJ1jfiJk1ErDitK8Hkc6Kll1+Ox2WtqEuGecSZLnmup3CGzvQ==}
|
||||
engines: {node: '>=16'}
|
||||
dependencies:
|
||||
'@shuding/opentype.js': 1.4.0-beta.0
|
||||
css-background-parser: 0.1.0
|
||||
css-box-shadow: 1.0.0-3
|
||||
css-to-react-native: 3.2.0
|
||||
emoji-regex: 10.3.0
|
||||
escape-html: 1.0.3
|
||||
linebreak: 1.1.0
|
||||
parse-css-color: 0.2.1
|
||||
postcss-value-parser: 4.2.0
|
||||
yoga-wasm-web: 0.3.3
|
||||
dev: false
|
||||
|
||||
/sax@1.3.0:
|
||||
resolution: {integrity: sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==}
|
||||
dev: false
|
||||
|
@ -6729,6 +6961,10 @@ packages:
|
|||
strip-ansi: 7.1.0
|
||||
dev: false
|
||||
|
||||
/string.prototype.codepointat@0.2.1:
|
||||
resolution: {integrity: sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg==}
|
||||
dev: false
|
||||
|
||||
/string.prototype.trim@1.2.8:
|
||||
resolution: {integrity: sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
@ -6922,6 +7158,10 @@ packages:
|
|||
resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
|
||||
dev: true
|
||||
|
||||
/tiny-inflate@1.0.3:
|
||||
resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==}
|
||||
dev: false
|
||||
|
||||
/tinybench@2.6.0:
|
||||
resolution: {integrity: sha512-N8hW3PG/3aOoZAN5V/NSAEDz0ZixDSSt5b/a05iqtpgfLWMSVuCo7w0k2vVvEjdrIoeGqZzweX2WlyioNIHchA==}
|
||||
dev: true
|
||||
|
@ -7117,6 +7357,10 @@ packages:
|
|||
resolution: {integrity: sha512-o+ORpgGwaYQXgqGDwd+hkS4PuZ3QnmqMMxRuajK/a38L6fTpcE5GPIfrf+L/KemFzfUpeUQc1rRS1iDBozvnFA==}
|
||||
dev: true
|
||||
|
||||
/ultrahtml@1.5.2:
|
||||
resolution: {integrity: sha512-qh4mBffhlkiXwDAOxvSGxhL0QEQsTbnP9BozOK3OYPEGvPvdWzvAUaXNtUSMdNsKDtuyjEbyVUPFZ52SSLhLqw==}
|
||||
dev: false
|
||||
|
||||
/unbox-primitive@1.0.2:
|
||||
resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==}
|
||||
dependencies:
|
||||
|
@ -7133,6 +7377,13 @@ packages:
|
|||
resolution: {integrity: sha512-akOOQ/Yln8a2sgcLj4U0Jmx0R5jpIg2IUyRrWOzmEbjBtGzBdHtSeFKgoEcoH4KYIG/Pb8GQ/BwtYm0GCq1Sqg==}
|
||||
dev: false
|
||||
|
||||
/unicode-trie@2.0.0:
|
||||
resolution: {integrity: sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ==}
|
||||
dependencies:
|
||||
pako: 0.2.9
|
||||
tiny-inflate: 1.0.3
|
||||
dev: false
|
||||
|
||||
/unified@10.1.2:
|
||||
resolution: {integrity: sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==}
|
||||
dependencies:
|
||||
|
@ -7491,7 +7742,7 @@ packages:
|
|||
vitest: '>=0.16.0'
|
||||
dependencies:
|
||||
cross-fetch: 3.1.8
|
||||
vitest: 1.2.1(@types/node@20.11.10)
|
||||
vitest: 1.2.1
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
dev: true
|
||||
|
@ -7927,6 +8178,10 @@ packages:
|
|||
resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==}
|
||||
engines: {node: '>=12.20'}
|
||||
|
||||
/yoga-wasm-web@0.3.3:
|
||||
resolution: {integrity: sha512-N+d4UJSJbt/R3wqY7Coqs5pcV0aUj2j9IaQ3rNj9bVCLld8tTGKRa2USARjnvZJWVx1NDmQev8EknoczaOQDOA==}
|
||||
dev: false
|
||||
|
||||
/zod-validation-error@3.0.0(zod@3.22.4):
|
||||
resolution: {integrity: sha512-x+agsJJG9rvC7axF0xqTEdZhJkLHyIZkdOAWDJSmwGPzxNHMHwtU6w2yDOAAP6yuSfTAUhAMJRBfhVGY64ySEQ==}
|
||||
engines: {node: '>=18.0.0'}
|
||||
|
|
Loading…
Reference in New Issue