Vollstaendige Next.js/Prisma-E-Commerce-Anwendung fuer eine Imkerei: Shop, Warenkorb, Stripe-Checkout, Kundenkonto mit 2FA, Admin-Bereich (Produkte, Ernten, Chargen, Bestellungen, Gutscheine, admin-editierbare Website-Inhalte), i18n (DE/EN), Rate-Limiting/CSP/Audit-Log-Haertung, PostgreSQL- und MySQL-Unterstuetzung ueber austauschbare Prisma- Treiber-Adapter, Unit-/Komponenten-/E2E-Tests.
51 lines
1.8 KiB
TypeScript
51 lines
1.8 KiB
TypeScript
import type { TitledText, LegalSectionContent } from "@/i18n/dictionary-type";
|
|
|
|
/**
|
|
* Reine Parser-Funktionen fuer das Klartext-Format, in dem die
|
|
* Content-Registry-Felder (siehe content-registry.ts) gespeichert werden.
|
|
* Bewusst in einer eigenen Datei ohne DB-/Prisma-Import: content.ts zieht
|
|
* @/lib/prisma nach sich, dessen Modul-Ladezeit-Treiber-Adapter ohne gesetzte
|
|
* DATABASE_URL wirft — das wuerde jeden Test dieser reinen Funktionen
|
|
* zwingen, eine DB-Verbindung vorzutaeuschen, obwohl sie keine brauchen.
|
|
*/
|
|
|
|
export function parseListSimple(text: string): string[] {
|
|
return text.split("\n").map((line) => line.trim()).filter(Boolean);
|
|
}
|
|
|
|
export function parseListTitled(text: string): TitledText[] {
|
|
return text
|
|
.split("\n")
|
|
.map((line) => line.trim())
|
|
.filter(Boolean)
|
|
.map((line) => {
|
|
const [title, ...rest] = line.split("|");
|
|
return { title: (title ?? "").trim(), text: rest.join("|").trim() };
|
|
});
|
|
}
|
|
|
|
export function parseListNumbered(text: string): { number: string; title: string; text: string }[] {
|
|
return text
|
|
.split("\n")
|
|
.map((line) => line.trim())
|
|
.filter(Boolean)
|
|
.map((line) => {
|
|
const [number, title, ...rest] = line.split("|");
|
|
return { number: (number ?? "").trim(), title: (title ?? "").trim(), text: rest.join("|").trim() };
|
|
});
|
|
}
|
|
|
|
export function parseSections(text: string): LegalSectionContent[] {
|
|
const blocks = text.split(/\n(?=##\s)/).map((b) => b.trim()).filter(Boolean);
|
|
return blocks.map((block) => {
|
|
const headingMatch = block.match(/^##\s*(.*)$/m);
|
|
const heading = headingMatch ? headingMatch[1].trim() : "";
|
|
const body = block.replace(/^##\s*.*$/m, "").trim();
|
|
const paragraphs = body
|
|
.split(/\n\s*\n/)
|
|
.map((p) => p.trim())
|
|
.filter(Boolean);
|
|
return { heading, paragraphs };
|
|
});
|
|
}
|