Développement

Générez vos schémas Zod depuis Notion pour Astro, sans magie

Créez un schéma Zod strict depuis Notion pour Astro. Typage, validation et intégration automatisée grâce à @duocrafters/notion-database-zod.

Par ,

Intro

L’objectif de notre librairie NPM @duocrafters/notion-database-zod est très simple : interroger une base Notion, en déduire un schéma Zod strict et l’utiliser comme contrat de validation dans une pipeline de contenu (ici Astro).

Le besoin initial vient d’Astro : les Content Collections fonctionnent très bien avec des schémas Zod, mais dès qu’on sort du markdown et qu’on branche une source distante, on perd ce garde-fou au moment où l’on en a le plus besoin. Générer le schéma à partir du database schema Notion permet de rétablir ce filet de sécurité au build comme en dev.


Architecture du module

La librairie expose un schéma de base de page (métadonnées communes Notion : id, created_time, last_edited_time, archived, in_trash, cover…) et surtout une fonction :

import { generateDatabaseSchema } from '@duocrafters/notion-database-zod';

generateDatabaseSchema(database_id, options) instancie un Client Notion, récupère la définition de la base (databases.retrieve) puis mappe chaque propriété vers un sous-schéma Zod adapté. Le résultat est un ZodObject qui étend le schéma de page de base en remplaçant properties par un z.object({ ... }) dont les clés sont les noms Notion et dont les valeurs sont les schémas dérivés du type Notion. S’il y a une description côté Notion, elle est propagée via schema.describe(description) pour enrichir les messages d’erreur.

Concrètement, on se retrouve avec un objet Zod qui reflète fidèlement votre base Notion au moment où vous l’interrogez. Si quelqu’un renomme “Title” en “Name” dans Notion, le parse échoue immédiatement au prochain build.


Exemple minimal, bout en bout

Installation :

npm i @duocrafters/notion-database-zod zod @notionhq/client

Génération du schéma, fetch des pages, validation :

import { Client } from '@notionhq/client';
import { generateDatabaseSchema, richTextToPlainText } from '@duocrafters/notion-database-zod';

const notion = new Client({ auth: process.env.NOTION_TOKEN! });

// 1) Générer le schéma à partir de la structure de la base
const PageSchema = await generateDatabaseSchema('YOUR_DATABASE_ID', {
  auth: process.env.NOTION_TOKEN!,
});

// 2) Récupérer des pages
const { results } = await notion.databases.query({ database_id: 'YOUR_DATABASE_ID' });

// 3) Valider une par une (ou tout jeter si une seule échoue)
const parsed = results.map((p) => PageSchema.safeParse(p));

const ok = parsed.filter((r) => r.success).map((r) => r.data);
const ko = parsed.filter((r) => !r.success);

Ce code est volontairement direct : pas de cache ni de persistance. En production, vous voudrez probablement mémoriser le schéma par database_id (ou le générer au démarrage) et normaliser vos champs (ex. Titletitle) après validation.


Intégration Astro sans douleur

Côté Astro, l’approche pragmatique consiste à générer le schéma avant le chargement du contenu puis à valider les entrées à la volée, exactement comme si vous lisiez un front-matter markdown. Le loader Astro spécifique Notion que nous publierons open-source encapsule cette séquence et expose une API spécifique pour les Content Collections.


Détails techniques et garanties

Sur le plan du typage, le schéma retourné est standard Zod et donc inférable :

import { z } from 'zod';
type NotionPage = z.infer<typeof PageSchema>;

Limites actuelles et évolutions

Le mapping des propriétés couvre d’abord les types les plus utilisés. Les schémas avancés (certaines variantes de Rich Text, propriétés composées) viendront au fil de l’eau. Le choix de faire échouer le build lors d’un écart de structure est assumé : c’est précisément la garantie recherchée lorsque l’on couple une source externe avec un système de contenu typé.

Le loader Astro Notion sera publié dans les prochaines semaines. Il prendra en charge la génération du schéma, le fetch, la validation, et l’exposition à vos Content Collections via une API dédiée, de manière à n’avoir rien d’autre à écrire que votre schéma Zod et vos composants.


En résumé, @duocrafters/notion-database-zod vous donne un contrat de types concret entre Notion et votre site Astro, sans dérapage silencieux : si la base change, vous le saurez au moment où il faut, avec un message exploitable, et vous resterez maître du pipeline de contenu.

Les autres articles à explorer