```js // article.mjs import { z } from "zod"; // Slug rule, matched to the behaviour the toolchain reported for this project's // zod build: "Héllo Wörld" -> "hllo-wrld". Characters outside [a-z0-9] are // DROPPED, not transliterated (no NFKD folding: "é" disappears, it does not // become "e"), separators and punctuation collapse to a single "-", and leading // and trailing "-" are trimmed. // // "Hello, World!" -> "hello-world" // "Héllo Wörld" -> "hllo-wrld" // "Café ☕ au lait!" -> "caf-au-lait" // // Both the API and the web client must import THIS module, so the two sides // cannot drift character for character. const slugify = (input) => input .toLowerCase() .replace(/[^a-z0-9\s-]+/g, "") // drop punctuation, emoji, accented letters .replace(/[\s-]+/g, "-") // any run of separators -> a single "-" .replace(/^-+|-+$/g, ""); // trim leading/trailing separators export const Slug = z.string().transform(slugify); export const Article = z.object({ title: z.string().min(3), slug: Slug, }); ``` TOOLS_USED: none