chore: move the image metadata generation to schema.ts

This commit is contained in:
Yufan Sheng 2024-09-26 12:27:03 +08:00
parent 87d7bf10b3
commit 96b4d913ed
Signed by: syhily
GPG Key ID: 9D18A22A7DCD5A9B
4 changed files with 103 additions and 92 deletions

90
package-lock.json generated
View File

@ -28,7 +28,7 @@
"@napi-rs/canvas": "^0.1.56", "@napi-rs/canvas": "^0.1.56",
"@types/lodash": "^4.17.9", "@types/lodash": "^4.17.9",
"@types/luxon": "^3.4.2", "@types/luxon": "^3.4.2",
"@types/node": "^22.6.1", "@types/node": "^22.7.2",
"@types/pg": "^8.11.10", "@types/pg": "^8.11.10",
"@types/qrcode-svg": "^1.1.5", "@types/qrcode-svg": "^1.1.5",
"@types/unist": "^3.0.3", "@types/unist": "^3.0.3",
@ -2290,44 +2290,44 @@
] ]
}, },
"node_modules/@shikijs/core": { "node_modules/@shikijs/core": {
"version": "1.18.0", "version": "1.19.0",
"resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.18.0.tgz", "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.19.0.tgz",
"integrity": "sha512-VK4BNVCd2leY62Nm2JjyxtRLkyrZT/tv104O81eyaCjHq4Adceq2uJVFJJAIof6lT1mBwZrEo2qT/T+grv3MQQ==", "integrity": "sha512-314J5MPdS1wzfjuD856MXvbAI2wN03ofMnUGkZ5ZDBOza/d38paLwd+YVyuKrrjxJ4hfPMjc4tRmPkXd6UDMPQ==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@shikijs/engine-javascript": "1.18.0", "@shikijs/engine-javascript": "1.19.0",
"@shikijs/engine-oniguruma": "1.18.0", "@shikijs/engine-oniguruma": "1.19.0",
"@shikijs/types": "1.18.0", "@shikijs/types": "1.19.0",
"@shikijs/vscode-textmate": "^9.2.2", "@shikijs/vscode-textmate": "^9.2.2",
"@types/hast": "^3.0.4", "@types/hast": "^3.0.4",
"hast-util-to-html": "^9.0.3" "hast-util-to-html": "^9.0.3"
} }
}, },
"node_modules/@shikijs/engine-javascript": { "node_modules/@shikijs/engine-javascript": {
"version": "1.18.0", "version": "1.19.0",
"resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-1.18.0.tgz", "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-1.19.0.tgz",
"integrity": "sha512-qoP/aO/ATNwYAUw1YMdaip/YVEstMZEgrwhePm83Ll9OeQPuxDZd48szZR8oSQNQBT8m8UlWxZv8EA3lFuyI5A==", "integrity": "sha512-D1sioU61n7fLWfDzTC9JNS19zEYZMr7qxkSVzv6ziEWDxnwzy2PvYoKPedJV4qUf+2VnrYPSaArDz2W0XgGB7A==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@shikijs/types": "1.18.0", "@shikijs/types": "1.19.0",
"@shikijs/vscode-textmate": "^9.2.2", "@shikijs/vscode-textmate": "^9.2.2",
"oniguruma-to-js": "0.4.3" "oniguruma-to-js": "0.4.3"
} }
}, },
"node_modules/@shikijs/engine-oniguruma": { "node_modules/@shikijs/engine-oniguruma": {
"version": "1.18.0", "version": "1.19.0",
"resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-1.18.0.tgz", "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-1.19.0.tgz",
"integrity": "sha512-B9u0ZKI/cud+TcmF8Chyh+R4V5qQVvyDOqXC2l2a4x73PBSBc6sZ0JRAX3eqyJswqir6ktwApUUGBYePdKnMJg==", "integrity": "sha512-/JxwIefNVLGB4EmpB8i6P4JB/oVYRuzSixbqvx7m6iPW0lQ1T97c/0wmA+JlKbngEiExckSuPwa48fajlShB7A==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@shikijs/types": "1.18.0", "@shikijs/types": "1.19.0",
"@shikijs/vscode-textmate": "^9.2.2" "@shikijs/vscode-textmate": "^9.2.2"
} }
}, },
"node_modules/@shikijs/types": { "node_modules/@shikijs/types": {
"version": "1.18.0", "version": "1.19.0",
"resolved": "https://registry.npmjs.org/@shikijs/types/-/types-1.18.0.tgz", "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-1.19.0.tgz",
"integrity": "sha512-O9N36UEaGGrxv1yUrN2nye7gDLG5Uq0/c1LyfmxsvzNPqlHzWo9DI0A4+fhW2y3bGKuQu/fwS7EPdKJJCowcVA==", "integrity": "sha512-NZvVp3k1bP4MTRUbmnkGhYzPdoNMjNLSAwczMRUbtUl4oj2LlNRNbwERyeIyJt56Ac9fvPVZ2nn13OXk86E5UQ==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@shikijs/vscode-textmate": "^9.2.2", "@shikijs/vscode-textmate": "^9.2.2",
@ -2474,9 +2474,9 @@
} }
}, },
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "22.6.1", "version": "22.7.2",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.6.1.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.2.tgz",
"integrity": "sha512-V48tCfcKb/e6cVUigLAaJDAILdMP0fUW6BidkPK4GpGjXcfbnoHasCZDwz3N3yVt5we2RHm4XTQCpv0KJz9zqw==", "integrity": "sha512-866lXSrpGpgyHBZUa2m9YNWqHDjjM0aBTJlNtYaGEw4rqY/dcD7deRVTbBBAJelfA7oaGDbNftXF/TL/A6RgoA==",
"devOptional": true, "devOptional": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -3257,9 +3257,9 @@
} }
}, },
"node_modules/browserslist": { "node_modules/browserslist": {
"version": "4.23.3", "version": "4.24.0",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.0.tgz",
"integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==", "integrity": "sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==",
"funding": [ "funding": [
{ {
"type": "opencollective", "type": "opencollective",
@ -3276,8 +3276,8 @@
], ],
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"caniuse-lite": "^1.0.30001646", "caniuse-lite": "^1.0.30001663",
"electron-to-chromium": "^1.5.4", "electron-to-chromium": "^1.5.28",
"node-releases": "^2.0.18", "node-releases": "^2.0.18",
"update-browserslist-db": "^1.1.0" "update-browserslist-db": "^1.1.0"
}, },
@ -3301,9 +3301,9 @@
} }
}, },
"node_modules/caniuse-lite": { "node_modules/caniuse-lite": {
"version": "1.0.30001663", "version": "1.0.30001664",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001663.tgz", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001664.tgz",
"integrity": "sha512-o9C3X27GLKbLeTYZ6HBOLU1tsAcBZsLis28wrVzddShCS16RujjHp9GDHKZqrB3meE0YjhawvMFsGb/igqiPzA==", "integrity": "sha512-AmE7k4dXiNKQipgn7a2xg558IRqPN3jMQY/rOsbxDhrd0tyChwbITBfiwtnqz8bi2M5mIWbxAYBvk7W7QBUS2g==",
"funding": [ "funding": [
{ {
"type": "opencollective", "type": "opencollective",
@ -3828,9 +3828,9 @@
} }
}, },
"node_modules/devalue": { "node_modules/devalue": {
"version": "5.0.0", "version": "5.1.1",
"resolved": "https://registry.npmjs.org/devalue/-/devalue-5.0.0.tgz", "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.1.1.tgz",
"integrity": "sha512-gO+/OMXF7488D+u3ue+G7Y4AA3ZmUnB3eHJXmBTgNHvr4ZNzl36A0ZtG+XCRNYCkYx/bFmw4qtkoFLa+wSrwAA==", "integrity": "sha512-maua5KUiapvEwiEAe+XnlZ3Rh0GD+qI1J/nb9vrJc3muPXvcF/8gXYTWF76+5DAqHyDUtOIImEuo0YKE9mshVw==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/devlop": { "node_modules/devlop": {
@ -3998,9 +3998,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/electron-to-chromium": { "node_modules/electron-to-chromium": {
"version": "1.5.28", "version": "1.5.29",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.28.tgz", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.29.tgz",
"integrity": "sha512-VufdJl+rzaKZoYVUijN13QcXVF5dWPZANeFTLNy+OSpHdDL5ynXTF35+60RSBbaQYB1ae723lQXHCrf4pyLsMw==", "integrity": "sha512-PF8n2AlIhCKXQ+gTpiJi0VhcHDb69kYX4MtCiivctc2QD3XuNZ/XIOlbGzt7WAjjEev0TtaH6Cu3arZExm5DOw==",
"license": "ISC" "license": "ISC"
}, },
"node_modules/emmet": { "node_modules/emmet": {
@ -8181,15 +8181,15 @@
} }
}, },
"node_modules/shiki": { "node_modules/shiki": {
"version": "1.18.0", "version": "1.19.0",
"resolved": "https://registry.npmjs.org/shiki/-/shiki-1.18.0.tgz", "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.19.0.tgz",
"integrity": "sha512-8jo7tOXr96h9PBQmOHVrltnETn1honZZY76YA79MHheGQg55jBvbm9dtU+MI5pjC5NJCFuA6rvVTLVeSW5cE4A==", "integrity": "sha512-Ng7Gd6XgWFLsv4Z3so65hOyXjV78qz1M117MuZHwdPQD6fgb5wR2IoLMvSlM/Ml14EXH7n+/YxIpTD74i7kDdw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@shikijs/core": "1.18.0", "@shikijs/core": "1.19.0",
"@shikijs/engine-javascript": "1.18.0", "@shikijs/engine-javascript": "1.19.0",
"@shikijs/engine-oniguruma": "1.18.0", "@shikijs/engine-oniguruma": "1.19.0",
"@shikijs/types": "1.18.0", "@shikijs/types": "1.19.0",
"@shikijs/vscode-textmate": "^9.2.2", "@shikijs/vscode-textmate": "^9.2.2",
"@types/hast": "^3.0.4" "@types/hast": "^3.0.4"
} }
@ -8869,9 +8869,9 @@
} }
}, },
"node_modules/vite": { "node_modules/vite": {
"version": "5.4.7", "version": "5.4.8",
"resolved": "https://registry.npmjs.org/vite/-/vite-5.4.7.tgz", "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.8.tgz",
"integrity": "sha512-5l2zxqMEPVENgvzTuBpHer2awaetimj2BGkhBPdnwKbPNOlHsODU+oiazEZzLK7KhAnOrO+XGYJYn4ZlUhDtDQ==", "integrity": "sha512-FqrItQ4DT1NC4zCUqMB4c4AZORMKIa0m8/URVCZ77OZ/QSNeJ54bU1vrFADbDsuwfIPcgknRkmqakQcgnL4GiQ==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"esbuild": "^0.21.3", "esbuild": "^0.21.3",

View File

@ -61,7 +61,7 @@
"@napi-rs/canvas": "^0.1.56", "@napi-rs/canvas": "^0.1.56",
"@types/lodash": "^4.17.9", "@types/lodash": "^4.17.9",
"@types/luxon": "^3.4.2", "@types/luxon": "^3.4.2",
"@types/node": "^22.6.1", "@types/node": "^22.7.2",
"@types/pg": "^8.11.10", "@types/pg": "^8.11.10",
"@types/qrcode-svg": "^1.1.5", "@types/qrcode-svg": "^1.1.5",
"@types/unist": "^3.0.3", "@types/unist": "^3.0.3",

View File

@ -1,4 +1,3 @@
import { imageMetadata } from '@/helpers/images';
import { urlJoin } from '@/helpers/tools'; import { urlJoin } from '@/helpers/tools';
import options from '@/options'; import options from '@/options';
import { defineCollection, z } from 'astro:content'; import { defineCollection, z } from 'astro:content';
@ -15,12 +14,7 @@ const slug = () =>
.max(200) .max(200)
.regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/i, 'Invalid slug'); .regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/i, 'Invalid slug');
const image = (fallbackImage: string) => const image = (fallbackImage: string) => z.string().optional().default(fallbackImage);
z
.string()
.optional()
.default(fallbackImage)
.transform(async (arg) => await imageMetadata(arg));
// Categories Collection // Categories Collection
const categoriesCollection = defineCollection({ const categoriesCollection = defineCollection({

View File

@ -1,4 +1,5 @@
import { defaultCover } from '@/content/config.ts'; import { defaultCover } from '@/content/config.ts';
import { imageMetadata, type Image } from '@/helpers/images';
import options from '@/options'; import options from '@/options';
import { getCollection, getEntry, type Render } from 'astro:content'; import { getCollection, getEntry, type Render } from 'astro:content';
@ -10,16 +11,22 @@ const postsCollection = await getCollection('posts');
const tagsCollection = await getCollection('tags'); const tagsCollection = await getCollection('tags');
// Redefine the types from the astro content. // Redefine the types from the astro content.
export type Category = (typeof categoriesCollection)[number]['data'] & { counts: number; permalink: string }; export type Category = Omit<(typeof categoriesCollection)[number]['data'], 'cover'> & {
counts: number;
permalink: string;
cover: Image;
};
export type Friend = (typeof friendsCollection)[number]['data'][number]; export type Friend = (typeof friendsCollection)[number]['data'][number];
export type Page = (typeof pagesCollection)[number]['data'] & { export type Page = Omit<(typeof pagesCollection)[number]['data'], 'cover'> & {
slug: string; slug: string;
permalink: string; permalink: string;
cover: Image;
render: () => Render['.mdx']; render: () => Render['.mdx'];
}; };
export type Post = (typeof postsCollection)[number]['data'] & { export type Post = Omit<(typeof postsCollection)[number]['data'], 'cover'> & {
slug: string; slug: string;
permalink: string; permalink: string;
cover: Image;
render: () => Render['.mdx']; render: () => Render['.mdx'];
raw: () => Promise<string>; raw: () => Promise<string>;
}; };
@ -28,9 +35,10 @@ export type Tag = (typeof tagsCollection)[number]['data'][number] & { counts: nu
// Translate the Astro content into the original content for dealing with different configuration types. // Translate the Astro content into the original content for dealing with different configuration types.
export const friends: Friend[] = friendsCollection[0].data; export const friends: Friend[] = friendsCollection[0].data;
// Override the website for local debugging // Override the website for local debugging
export const pages: Page[] = pagesCollection export const pages: Page[] = await Promise.all(
pagesCollection
.filter((page) => page.data.published || !options.isProd()) .filter((page) => page.data.published || !options.isProd())
.map((page) => ({ .map(async (page) => ({
slug: page.slug, slug: page.slug,
permalink: `/${page.slug}`, permalink: `/${page.slug}`,
render: async () => { render: async () => {
@ -38,10 +46,14 @@ export const pages: Page[] = pagesCollection
return entry.render(); return entry.render();
}, },
...page.data, ...page.data,
})); cover: await imageMetadata(page.data.cover),
export const posts: Post[] = postsCollection })),
);
export const posts: Post[] = (
await Promise.all(
postsCollection
.filter((post) => post.data.published || !options.isProd()) .filter((post) => post.data.published || !options.isProd())
.map((post) => ({ .map(async (post) => ({
slug: post.slug, slug: post.slug,
permalink: `/posts/${post.slug}`, permalink: `/posts/${post.slug}`,
render: async () => { render: async () => {
@ -53,17 +65,22 @@ export const posts: Post[] = postsCollection
return entry.body; return entry.body;
}, },
...post.data, ...post.data,
})) cover: await imageMetadata(post.data.cover),
.sort((left: Post, right: Post) => { })),
)
).sort((left: Post, right: Post) => {
const a = left.date.getTime(); const a = left.date.getTime();
const b = right.date.getTime(); const b = right.date.getTime();
return options.settings.post.sort === 'asc' ? a - b : b - a; return options.settings.post.sort === 'asc' ? a - b : b - a;
}); });
export const categories: Category[] = categoriesCollection.map((cat) => ({ export const categories: Category[] = await Promise.all(
categoriesCollection.map(async (cat) => ({
counts: posts.filter((post) => post.category === cat.data.name).length, counts: posts.filter((post) => post.category === cat.data.name).length,
permalink: `/cats/${cat.data.slug}`, permalink: `/cats/${cat.data.slug}`,
...cat.data, ...cat.data,
})); cover: await imageMetadata(cat.data.cover),
})),
);
export const tags: Tag[] = tagsCollection[0].data.map((tag) => ({ export const tags: Tag[] = tagsCollection[0].data.map((tag) => ({
counts: posts.filter((post) => post.tags.includes(tag.name)).length, counts: posts.filter((post) => post.tags.includes(tag.name)).length,
permalink: `/tags/${tag.slug}`, permalink: `/tags/${tag.slug}`,