mirror of
https://github.com/Techtonic-Fault/homepage.git
synced 2026-01-23 05:26:30 +00:00
90 lines
3.1 KiB
TypeScript
90 lines
3.1 KiB
TypeScript
import { defineCollection, defineConfig } from "@content-collections/core";
|
|
import { parsePostDate } from "@/lib/blog";
|
|
|
|
const italianDateRegex = /^\d{1,2} (gennaio|febbraio|marzo|aprile|maggio|giugno|luglio|agosto|settembre|ottobre|novembre|dicembre) \d{4}$/i;
|
|
|
|
// Regex per "8 min", "12 min", ecc.
|
|
const readTimeRegex = /^\d{1,3} min$/;
|
|
|
|
const authors = defineCollection({
|
|
name: "authors",
|
|
directory: "src/authors",
|
|
include: "*.yml",
|
|
parser: "yaml",
|
|
schema: (z) => ({
|
|
name: z.string().min(1, "Nome obbligatorio"),
|
|
ref: z.string().min(1, "Riferimento obbligatorio"),
|
|
avatar: z.string(),
|
|
title: z.string().min(1, "Titolo obbligatorio"),
|
|
description: z.string().min(1, "Descrizione obbligatoria"),
|
|
socialLinks: z.object({
|
|
twitter: z.string().url("URL non valido").optional(),
|
|
github: z.string().url("URL non valido").optional(),
|
|
linkedin: z.string().url("URL non valido").optional(),
|
|
}).optional(),
|
|
}),
|
|
transform(data, context) {
|
|
return {
|
|
...data,
|
|
avatar: `${data.avatar}?height=80&width=80`,
|
|
}
|
|
},
|
|
});
|
|
|
|
const posts = defineCollection({
|
|
name: "posts",
|
|
directory: "src/posts",
|
|
include: "**/*.md",
|
|
schema: (z) => ({
|
|
title: z.string().min(1, "Titolo obbligatorio"),
|
|
excerpt: z.string().min(1, "Excerpt obbligatorio"),
|
|
content: z.string().min(1),
|
|
author: z.string().min(1, "Autore obbligatorio"),
|
|
date: z.string().regex(italianDateRegex, "La data deve essere nel formato 'dd mmm yyyy'"),
|
|
readTime: z.string().regex(readTimeRegex, "readTime deve essere nel formato 'X min'").optional(),
|
|
category: z.string().min(1, "Categoria obbligatoria"),
|
|
tags: z.array(z.string().min(1)).min(1, "Almeno un tag è richiesto"),
|
|
coverImage: z.string(),
|
|
hidden: z.null().optional(),
|
|
}),
|
|
transform(data, context) {
|
|
const date = parsePostDate(data.date);
|
|
const prefix = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}-${String(date.getDate()).padStart(2, "0")}`;
|
|
const authorObj = context.documents(authors).find((author) => author.ref === data.author);
|
|
if (authorObj == null) throw new Error(`Autore non trovato: ${data.author}`);
|
|
if (data.readTime == null) {
|
|
const words = data.content.trim().split(/\s+/).length;
|
|
const wpm = 180;
|
|
const minutes = Math.ceil(words / wpm);
|
|
data.readTime = `${minutes} min`;
|
|
}
|
|
return {
|
|
...data,
|
|
slug: `${prefix}-${data._meta.path}`,
|
|
dateObject: date,
|
|
author: authorObj,
|
|
}
|
|
}
|
|
});
|
|
|
|
const portfolio = defineCollection({
|
|
name: "portfolio",
|
|
directory: "src/portfolio",
|
|
include: "**/*.md",
|
|
schema: (z) => ({
|
|
title: z.string().min(1, "Nome obbligatorio"),
|
|
description: z.string().min(1, "Descrizione obbligatoria"),
|
|
content: z.string().min(1),
|
|
image: z.string(),
|
|
tags: z.array(z.string().min(1)).min(1, "Almeno un tag è richiesto"),
|
|
year: z.number().min(2000, "L'anno deve essere maggiore di 2000"),
|
|
links: z.object({
|
|
apple: z.string().url().or(z.null()),
|
|
play: z.string().url().or(z.null()),
|
|
}).or(z.null()),
|
|
}),
|
|
});
|
|
|
|
export default defineConfig({
|
|
collections: [authors, posts, portfolio],
|
|
}); |