{"id":37201,"date":"2025-05-28T17:11:11","date_gmt":"2025-05-28T15:11:11","guid":{"rendered":"https:\/\/nearshore-it.eu\/?p=37201"},"modified":"2025-06-18T12:27:14","modified_gmt":"2025-06-18T10:27:14","slug":"zod-ai-schema-validation","status":"publish","type":"post","link":"https:\/\/nearshore-it.eu\/pl\/artykuly\/zod-ai-schema-validation\/","title":{"rendered":"Zod &#038; AI \u2013 schema validation w projektach AI \u2013 przewodnik TypeScript\u00a0"},"content":{"rendered":"\n<div class=\"table-of-contents\">\n    <p class=\"title\">Przejd\u017a do:<\/p>\n    <ol>\n                    <li><a href=\"#Biblioteka-Zod\">1.  Biblioteka Zod<\/a><\/li>\n                    <li><a href=\"#Czym-jest-walidacja-danych-Zod\">2.  Czym jest walidacja danych Zod i dlaczego jest tak wa\u017cna?\u00a0\u00a0<\/a><\/li>\n                    <li><a href=\"#Jak-u\u017cywa\u0107-Zod-w-aplikacjach-opartych-na-AI?\">3.  Jak u\u017cywa\u0107 Zod w aplikacjach opartych na AI? <\/a><\/li>\n                    <li><a href=\"#Zastosowanie-Zod-w-preprocessingu-danych\">4.  Zastosowanie Zod w preprocessingu danych\u00a0\u00a0<\/a><\/li>\n                    <li><a href=\"#Jak-Zod-usprawnia-deployment-modeli-AI?\">5.  Jak Zod usprawnia deployment modeli AI?\u00a0\u00a0<\/a><\/li>\n                    <li><a href=\"#Kluczowe-cechy-Zod-w-JavaScript\">6.  Kluczowe cechy Zod w JavaScript\u00a0\u00a0<\/a><\/li>\n                    <li><a href=\"#Jak-zaimplementowa\u0107-walidacj\u0119-formularza-z-u\u017cyciem-Zod?\">7.  Jak zaimplementowa\u0107 walidacj\u0119 formularza z u\u017cyciem Zod?\u00a0\u00a0<\/a><\/li>\n            <\/ol>\n<\/div>\n\n\n<h2 class=\"wp-block-heading\" id=\"Biblioteka-Zod\"><strong>Biblioteka Zod<\/strong>&nbsp;<\/h2>\n\n\n\n<p>I w\u0142a\u015bnie tutaj dobrym rozwi\u0105zaniem jest Zod: lekka, szybka biblioteka do walidacji danych dla TypeScript, kt\u00f3ra pozwala jasno okre\u015bli\u0107, jakich struktur oczekujemy od inputu. Zamiast zgadywa\u0107, czy odpowied\u017a b\u0119dzie zgodna z oczekiwaniami, po prostu j\u0105 walidujemy. Je\u015bli co\u015b si\u0119 nie zgadza \u2013 dostajemy informacj\u0119 o b\u0142\u0119dzie i jasny komunikat. Je\u015bli wszystko gra \u2013 mo\u017cemy bezpiecznie przetwarza\u0107 dane dalej. Mamy nad wszystkim kontrol\u0119, jeszcze zanim przeka\u017cemy dalej dane do naszej logiki biznesowej.&nbsp;&nbsp;<\/p>\n\n\n\n<p>Zod dzia\u0142a jak filtr bezpiecze\u0144stwa \u2013 pozwala odrzuci\u0107 b\u0142\u0119dne odpowiedzi, zanim trafi\u0105 do logiki aplikacji. Dzi\u0119ki temu zyskujemy nie tylko wi\u0119ksz\u0105 kontrol\u0119, ale te\u017c spok\u00f3j ducha: <strong>nawet je\u015bli AI troch\u0119 \u201ezb\u0142\u0105dzi\u201d, warstwa frontend to odpowiednio obs\u0142u\u017cy i tego nie odczuje.&nbsp;&nbsp;<\/strong><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"Czym-jest-walidacja-danych-Zod\"><strong>Czym jest walidacja danych Zod i dlaczego jest tak wa\u017cna?&nbsp;<\/strong>&nbsp;<\/h2>\n\n\n\n<p>Zod to biblioteka TypeScript \/ JavaScript, kt\u00f3ra umo\u017cliwia tworzenie schemat\u00f3w danych (schemas), wykorzystywanych zar\u00f3wno do walidacji danych w czasie rzeczywistym, jak i do generowania typ\u00f3w w czasie kompilacji. Dzi\u0119ki niej mo\u017cemy opisa\u0107 struktur\u0119 danych, kt\u00f3rej aplikacja oczekuje, i automatycznie sprawdzi\u0107, czy rzeczywiste dane, kt\u00f3re przekazali\u015bmy do inputu spe\u0142niaj\u0105 wszystkie nasze za\u0142o\u017cenia.&nbsp;&nbsp;<\/p>\n\n\n\n<p>W kontek\u015bcie AI \u2013 gdzie dane zwracane przez modele bywaj\u0105 nieprzewidywalne i cz\u0119sto nie trzymaj\u0105 si\u0119 jednej struktury, <strong>walidacja staje si\u0119 wr\u0119cz obowi\u0105zkowa. <\/strong>Nawet drobna zmiana w odpowiedzi modelu mo\u017ce wywo\u0142a\u0107 b\u0142\u0105d w aplikacji, je\u015bli nasz kod zak\u0142ada konkretn\u0105 struktur\u0119 danych. Zod pozwala temu zapobiec, sprawdzaj\u0105c zgodno\u015b\u0107 danych, zanim trafi\u0105 dalej do logiki biznesowej.&nbsp;&nbsp;<\/p>\n\n\n\n<p><strong>Przeczytaj tak\u017ce:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/nearshore-it.eu\/pl\/artykuly\/najlepsze-ai-for-coding-w-2025-roku-czego-uzywac-do-generowania-kodu\/\" data-type=\"post\" data-id=\"34778\">Najlepsze AI for coding<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/nearshore-it.eu\/pl\/artykuly\/github-copilot-asystent-ai\/\" data-type=\"post\" data-id=\"34871\">AI w programowaniu: Github Copilot <\/a><\/li>\n<\/ul>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"Jak-u\u017cywa\u0107-Zod-w-aplikacjach-opartych-na-AI?-\"><strong>Jak u\u017cywa\u0107 Zod w aplikacjach opartych na AI? <\/strong><strong>(validation in AI with Zod)<\/strong>&nbsp;<\/h2>\n\n\n\n<p>Zod mo\u017cna zintegrowa\u0107 z dowoln\u0105 aplikacj\u0105 JavaScript, zar\u00f3wno po stronie frontendu, jak i backendu. W kontek\u015bcie AI najcz\u0119\u015bciej wykorzystywany jest do:&nbsp;&nbsp;<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>walidacji odpowiedzi z API (np. OpenAI),&nbsp;&nbsp;<\/li>\n\n\n\n<li>generowania interfejs\u00f3w dynamicznych,&nbsp;&nbsp;<\/li>\n\n\n\n<li>utrzymywania sp\u00f3jnych kontrakt\u00f3w danych mi\u0119dzy frontendem a modelem.&nbsp;&nbsp;<\/li>\n<\/ul>\n\n\n\n<p>Dzi\u0119ki helperowi zodResponseFormat w SDK OpenAI mo\u017cemy \u0142atwo powi\u0105za\u0107 schemat Zod z odpowiedzi\u0105 modelu:&nbsp;&nbsp;<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">const MathResponse = z.object({\n  steps: z.array(z.object({\n    explanation: z.string(),\n    output: z.string(),\n  })),\n  final_answer: z.string(),\n});\n\nconst completion = await client.beta.chat.completions.parse({\n  model: 'gpt-4o',\n  messages: [...],\n  response_format: zodResponseFormat(MathResponse, 'math_response'),\n});\n<\/pre>\n\n\n\n<p>Taka integracja sprawia, \u017ce odpowied\u017a modelu jest walidowana automatycznie i mo\u017cemy bezpiecznie korzysta\u0107 z jej zawarto\u015bci w aplikacji.&nbsp;&nbsp;<\/p>\n\n\n\n<p>Je\u015bli korzystamy z funkcji narz\u0119dzi (tool calls), mo\u017cemy u\u017cy\u0107 zodFunction, by automatycznie zmapowa\u0107 argumenty na typy Zod:&nbsp;&nbsp;<\/p>\n\n\n\n<p><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">const queryArgs = z.object({ ... });\n\nconst completion = await client.beta.chat.completions.parse({\n  model: 'gpt-4o',\n  messages: [...],\n  tools: [zodFunction({ name: 'query', parameters: QueryArgs })],\n});\n<\/pre>\n\n\n\n<p>Zod daje nam kontrol\u0119 nad struktur\u0105 danych \u2013 zar\u00f3wno tych zwracanych przez model, jak i tych przekazywanych do funkcji. Dzi\u0119ki temu unikamy b\u0142\u0119d\u00f3w wynikaj\u0105cych z niesp\u00f3jno\u015bci formatu i mamy wi\u0119ksz\u0105 przewidywalno\u015b\u0107 dzia\u0142ania aplikacji.&nbsp;&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"Zastosowanie-Zod-w-preprocessingu-danych\"><strong>Zastosowanie Zod w preprocessingu danych&nbsp;<\/strong>&nbsp;<\/h2>\n\n\n\n<p>Zod sprawdza si\u0119 nie tylko po stronie odbioru danych z modelu AI, ale r\u00f3wnie\u017c wcze\u015bniej \u2013 podczas przygotowania danych wej\u015bciowych. Preprocessing to moment, w kt\u00f3rym mo\u017cemy upewni\u0107 si\u0119, \u017ce to, co wysy\u0142amy do modelu, jest kompletne, poprawnie sformatowane i zgodne z oczekiwanym typem.&nbsp;&nbsp;<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Typowe zastosowania Zod w preprocessingu:&nbsp;&nbsp;<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>walidacja danych wprowadzanych przez u\u017cytkownika przed wys\u0142aniem zapytania do AI,&nbsp;&nbsp;<\/li>\n\n\n\n<li>konwersja typ\u00f3w, np. zamiana ci\u0105g\u00f3w znak\u00f3w (stringa) na daty,&nbsp;&nbsp;<\/li>\n\n\n\n<li>czyszczenie i porz\u0105dkowanie danych z zewn\u0119trznych \u017ar\u00f3de\u0142, jak API czy formularze.&nbsp;&nbsp;<\/li>\n<\/ul>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">const dateSchema = z.string().transform(str => new Date(str));\nconst parsedDate = dateSchema.parse(\"2024-08-06\"); \/\/ => obiekt typu Date\n<\/pre>\n\n\n\n<p>Dzi\u0119ki funkcji <strong>.transform()<\/strong> mo\u017cemy nie tylko sprawdzi\u0107, czy dane maj\u0105 odpowiedni format, ale te\u017c przekszta\u0142ci\u0107 wprowadzone dane do postaci, kt\u00f3ra jest odpowiednio dostosowana do dalszego przetwarzania w aplikacji. To szczeg\u00f3lnie przydatne, gdy dane maj\u0105 s\u0142u\u017cy\u0107 jako prompt lub parametr w zapytaniu do modelu AI.&nbsp;&nbsp;<\/p>\n\n\n\n<p>Preprocessing z u\u017cyciem Zod to prosty spos\u00f3b na zminimalizowanie b\u0142\u0119d\u00f3w i zwi\u0119kszenie kontroli nad danymi, zanim jeszcze trafi\u0105 do modelu.&nbsp;&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"Jak-Zod-usprawnia-deployment-modeli-AI?\"><strong>Jak Zod usprawnia deployment modeli AI?&nbsp;<\/strong>&nbsp;<\/h2>\n\n\n\n<p>Zod to nie tylko narz\u0119dzie deweloperskie \u2013 jego zastosowanie ma realne prze\u0142o\u017cenie na jako\u015b\u0107 wdro\u017ce\u0144 modeli AI w \u015brodowiskach produkcyjnych. Pozwala budowa\u0107 solidny bufor bezpiecze\u0144stwa pomi\u0119dzy cz\u0119sto nieprzewidywalnym modelem AI a wymaganiami naszej aplikacji.&nbsp;&nbsp;<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Biblioteka Zod w procesie deploymentu pomaga:&nbsp;&nbsp;<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Zwi\u0119kszy\u0107 odporno\u015b\u0107 aplikacji na zmiany \u2013 zmiana prompta, wersji modelu czy struktury danych nie musi oznacza\u0107 b\u0142\u0119d\u00f3w, je\u015bli dane przechodz\u0105 przez schematy walidacyjne tworzone przez Zoda.&nbsp;&nbsp;<\/li>\n\n\n\n<li>Szybciej debugowa\u0107 problemy \u2013 zamiast domy\u015bla\u0107 si\u0119, co posz\u0142o nie tak, dostajemy jasne, czytelne komunikaty o b\u0142\u0119dach.&nbsp;&nbsp;<\/li>\n\n\n\n<li>Pisa\u0107 testy jednostkowe \u2013 schematy Zod mog\u0105 pe\u0142ni\u0107 funkcj\u0119 walidator\u00f3w i \u017ar\u00f3d\u0142a przyk\u0142adowych danych wej\u015bciowych do test\u00f3w.&nbsp;&nbsp;<\/li>\n<\/ul>\n\n\n\n<p>Zamiast wi\u0119c opiera\u0107 si\u0119 na za\u0142o\u017ceniu, \u017ce wszystko w ko\u0144cowej fazie projektu dzia\u0142a, mo\u017cemy zbudowa\u0107 system, kt\u00f3ry rzeczywi\u015bcie przewiduje b\u0142\u0119dy i potrafi si\u0119 przed nimi obroni\u0107.&nbsp;&nbsp;<\/p>\n\n\n\n<p>Z perspektywy wdro\u017ceniowej oznacza to mniej awarii, wi\u0119ksz\u0105 sp\u00f3jno\u015b\u0107 danych i \u0142atwiejsze utrzymanie ca\u0142ego pipeline\u2019u \u2013 od prompta po ko\u0144cowy interfejs u\u017cytkownika.&nbsp;&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"Kluczowe-cechy-Zod-w-JavaScript\"><strong>Kluczowe cechy Zod w JavaScript&nbsp;<\/strong>&nbsp;<\/h2>\n\n\n\n<p>Zod oferuje nowoczesne podej\u015bcie do walidacji danych w JavaScript i TypeScript. Jego g\u0142\u00f3wne zalety to:&nbsp;&nbsp;<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Deklaratywno\u015b\u0107 \u2013 schematy s\u0105 czytelne, przejrzyste i proste do napisania. Mo\u017cemy z \u0142atwo\u015bci\u0105 tworzy\u0107 z\u0142o\u017cone struktury bez nadmiaru kodu.&nbsp;&nbsp;<\/li>\n<\/ul>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">const UserSchema = z.object({\n  name: z.string().min(3),\n  age: z.number().int().positive(),\n  email: z.string().email(),\n});\n<\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Bezpo\u015brednia integracja z TypeScriptem \u2013 Zod automatycznie wyci\u0105ga typy z definicji schemat\u00f3w (z.infer), dzi\u0119ki czemu nie musimy pisa\u0107 typ\u00f3w dwa razy.&nbsp;&nbsp;<\/li>\n<\/ul>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">type User = z.infer&lt;typeof UserSchema>;<\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Walidacja i transformacja w jednym miejscu \u2013 mo\u017cemy nie tylko sprawdza\u0107 dane, ale te\u017c odpowiednio je przekszta\u0142ca\u0107 (np. string \u2192 Date, liczba \u2192 boolean, itp.).&nbsp;&nbsp;<\/li>\n<\/ul>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">const DateSchema = z.string().transform(str => new Date(str));\nconst parsedDate = DateSchema.parse(\"2024-08-06\");\n<\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Obs\u0142uga b\u0142\u0119d\u00f3w \u2013 metody safeParse i parse pozwalaj\u0105 wygodnie obs\u0142ugiwa\u0107 b\u0142\u0119dy. Pierwsza nie rzuca wyj\u0105tku, a druga daje pe\u0142n\u0105 kontrol\u0119 nad b\u0142\u0119dami typu ZodError.&nbsp;&nbsp;<\/li>\n<\/ul>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">const result = UserSchema.safeParse(userData);\nif (!result.success) {\n  console.log(result.error.format());\n}\n<\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Czytelne komunikaty walidacyjne \u2013 b\u0142\u0119dy mo\u017cna formatowa\u0107, w pe\u0142ni kontrolowa\u0107, mapowa\u0107 i wy\u015bwietla\u0107 w aplikacjach frontendowych w spos\u00f3b przyjazny dla u\u017cytkownika.&nbsp;&nbsp;<\/li>\n<\/ul>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">function formatZodErrors(error: z.ZodError) {\n  return error.errors.reduce((acc, err) => {\n    const field = err.path.join(\".\");\n    acc[field] = err.message;\n    return acc;\n  }, {} as Record&lt;string, string>);\n}\n<\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Rozszerzalno\u015b\u0107 \u2013 dzi\u0119ki metodzie <strong>.refine()<\/strong> mo\u017cemy \u0142atwo dodawa\u0107 w\u0142asne warunki i logik\u0119 walidacyjn\u0105.&nbsp;&nbsp;<\/li>\n<\/ul>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">const PasswordSchema = z.string()\n  .min(8, \"Has\u0142o musi mie\u0107 min. 8 znak\u00f3w\")\n  .refine(val => \/\\d\/.test(val), {\n    message: \"Has\u0142o musi zawiera\u0107 cyfr\u0119\",\n  });\n<\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Chaining \u2013 mo\u017cemy \u0142\u0105czy\u0107 wiele regu\u0142 walidacyjnych w \u0142a\u0144cuchach co u\u0142atwia tworzenie z\u0142o\u017conych walidacji, np. <strong>.min(3).max(20).regex(&#8230;),.&nbsp;<\/strong>&nbsp;<\/li>\n<\/ul>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">const NameSchema = z.string()\n  .min(3, \"Za kr\u00f3tkie\")\n  .max(50, \"Za d\u0142ugie\")\n  .regex(\/^[a-zA-Z\\s]+$\/, \"Tylko litery i spacje\");\n\n<\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>U\u017cyteczno\u015b\u0107 w ca\u0142ym stacku \u2013 Zod sprawdza si\u0119 zar\u00f3wno walidacji danych u\u017cytkownika w formularzach (React Hook Form), jak i walidacji odpowiedzi API czy typ\u00f3w w bazach danych&nbsp;&nbsp;<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"Jak-zaimplementowa\u0107-walidacj\u0119-formularza-z-u\u017cyciem-Zod?\"><strong>Jak zaimplementowa\u0107 walidacj\u0119 formularza z u\u017cyciem Zod?&nbsp;<\/strong>&nbsp;<\/h2>\n\n\n\n<p>Zod doskonale integruje si\u0119 z popularnymi narz\u0119dziami do obs\u0142ugi formularzy, takimi jak React Hook Form. Dzi\u0119ki temu mo\u017cemy w prosty spos\u00f3b po\u0142\u0105czy\u0107 walidacj\u0119 danych z typowaniem w TypeScript i uzyska\u0107 czytelny kod oraz sp\u00f3jne komunikaty b\u0142\u0119d\u00f3w.&nbsp;&nbsp;<\/p>\n\n\n\n<p>Za\u0142\u00f3\u017cmy, \u017ce tworzymy prosty formularz rejestracyjny. Najpierw definiujemy schema:&nbsp;&nbsp;<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">const RegisterSchema = z.object({\n  name: z.string().min(3, \"Imi\u0119 musi mie\u0107 co najmniej 3 znaki\"),\n  email: z.string().email(\"Niepoprawny adres e-mail\"),\n  password: z.string()\n    .min(8, \"Has\u0142o musi mie\u0107 co najmniej 8 znak\u00f3w\")\n    .refine(val => \/\\d\/.test(val), {\n      message: \"Has\u0142o musi zawiera\u0107 cyfr\u0119\",\n    }),\n});\n<\/pre>\n\n\n\n<p>Nast\u0119pnie \u0142\u0105czymy schema z formularzem:&nbsp;&nbsp;<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">import { useForm } from 'react-hook-form';\nimport { zodResolver } from '@hookform\/resolvers\/zod';\n\nconst form = useForm({\n  resolver: zodResolver(RegisterSchema),\n});\n\nconst { register, handleSubmit, formState: { errors } } = form;\n<\/pre>\n\n\n\n<p>W JSX podpinamy pola i wy\u015bwietlamy b\u0142\u0119dy:&nbsp;&nbsp;<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;form onSubmit={handleSubmit(formDetails => console.log(formDetails))}>\n  &lt;input {...register(\"name\")} placeholder=\"Imi\u0119\" \/>\n  {errors.name &amp;&amp; &lt;p>{errors.name.message}&lt;\/p>}\n\n  &lt;input {...register(\"email\")} placeholder=\"Email\" \/>\n  {errors.email &amp;&amp; &lt;p>{errors.email.message}&lt;\/p>}\n\n  &lt;input {...register(\"password\")} placeholder=\"Has\u0142o\" type=\"password\" \/>\n  {errors.password &amp;&amp; &lt;p>{errors.password.message}&lt;\/p>}\n\n  &lt;button type=\"submit\">Zarejestruj si\u0119&lt;\/button>\n&lt;\/form>\n<\/pre>\n\n\n\n<p>Taka integracja daje nam:&nbsp;&nbsp;<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>automatyczn\u0105 walidacj\u0119 p\u00f3l,&nbsp;&nbsp;<\/li>\n\n\n\n<li>pe\u0142ne typowanie danych,&nbsp;&nbsp;<\/li>\n\n\n\n<li>sp\u00f3jne i konfigurowalne komunikaty b\u0142\u0119d\u00f3w,&nbsp;&nbsp;<\/li>\n\n\n\n<li>prost\u0105 integracj\u0119 z istniej\u0105cym kodem Reacta.&nbsp;&nbsp;<\/li>\n<\/ul>\n\n\n\n<\/style><div class=\"promotion-box promotion-box--image-left \"><div class=\"tiles latest-news-once\"><div class=\"tile\"><div class=\"tile-image\"><img decoding=\"async\" src=\"https:\/\/nearshore-it.eu\/wp-content\/uploads\/2025\/02\/Code-Faster-Tlo-2.jpg\" alt=\"\" title=\"\"><\/div><div class=\"tile-content\"><p class=\"entry-title client-name\">AI w programowaniu | bezp\u0142atny e-book<\/p>\r\nZautomatyzuj kodowanie z AI! Pobierz darmowy e-book i odkryj nowe mo\u017cliwo\u015bci\r\n<br \/><br \/>\r\n<a class=\"btn btn-primary\" href=\"https:\/\/www.engage.inetum.com\/ebook-code-faster-build-smarter\/\" target=\"_blank\" rel=\"noopener\">Pobierz teraz!<\/a><\/div><\/div><\/div><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Podsumowanie&nbsp;<\/strong>&nbsp;<\/h2>\n\n\n\n<p>W \u015bwiecie, gdzie <strong>dane generowane przez AI s\u0105 dynamiczne i cz\u0119sto nieprzewidywalne, <\/strong>warto zadba\u0107 o silne fundamenty naszych projekt\u00f3w. Zod mo\u017ce pe\u0142ni\u0107 rol\u0119 warstwy ochronnej \u2013 zapewniaj\u0105c <strong>walidacj\u0119, transformacj\u0119 i typowanie danych <\/strong>w jednym miejscu. To nie tylko techniczny dodatek, ale kluczowy element architektury, kt\u00f3ry pozwala budowa\u0107 odporne, stabilne i \u0142atwe w utrzymaniu integracj\u0119 z modelami AI.&nbsp;&nbsp;<\/p>\n\n\n\n<p>Zod to solidna biblioteka z rosn\u0105c\u0105 spo\u0142eczno\u015bci\u0105 i aktywnym wsparciem, kt\u00f3r\u0105 z powodzeniem mo\u017cna wykorzysta\u0107 nie tylko w integracjach z wykorzystaniem AI, ale tak\u017ce w codziennych projektach frontendowych \u2013 od formularzy po obs\u0142ug\u0119 API.&nbsp;&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>W pracy z AI najwi\u0119kszym wyzwaniem jest cz\u0119sto\u2026 samo AI. Modele generuj\u0105 dane w r\u00f3\u017cnym formacie, czasem brakuje klucza, czasem typ si\u0119 nie zgadza \u2013 a nasz projekt musi ca\u0142y czas dzia\u0142a\u0107 bezb\u0142\u0119dnie. Wystarczy drobna zmiana prompta, nowa wersja modelu albo niespodziewany fallback, by struktura danych zacz\u0119\u0142a robi\u0107 problemy w najmniej oczekiwanym momencie.  <\/p>\n","protected":false},"author":119,"featured_media":37256,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"iawp_total_views":102,"footnotes":""},"categories":[1,582],"tags":[620],"offering":[522],"class_list":["post-37201","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-artykuly","category-technologie","tag-ai-2","offering-tech-blog"],"acf":[],"_links":{"self":[{"href":"https:\/\/nearshore-it.eu\/pl\/wp-json\/wp\/v2\/posts\/37201","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nearshore-it.eu\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nearshore-it.eu\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nearshore-it.eu\/pl\/wp-json\/wp\/v2\/users\/119"}],"replies":[{"embeddable":true,"href":"https:\/\/nearshore-it.eu\/pl\/wp-json\/wp\/v2\/comments?post=37201"}],"version-history":[{"count":10,"href":"https:\/\/nearshore-it.eu\/pl\/wp-json\/wp\/v2\/posts\/37201\/revisions"}],"predecessor-version":[{"id":37367,"href":"https:\/\/nearshore-it.eu\/pl\/wp-json\/wp\/v2\/posts\/37201\/revisions\/37367"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/nearshore-it.eu\/pl\/wp-json\/wp\/v2\/media\/37256"}],"wp:attachment":[{"href":"https:\/\/nearshore-it.eu\/pl\/wp-json\/wp\/v2\/media?parent=37201"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nearshore-it.eu\/pl\/wp-json\/wp\/v2\/categories?post=37201"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nearshore-it.eu\/pl\/wp-json\/wp\/v2\/tags?post=37201"},{"taxonomy":"offering","embeddable":true,"href":"https:\/\/nearshore-it.eu\/pl\/wp-json\/wp\/v2\/offering?post=37201"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}