Référence des types

Les types TypeScript que les auteurs de thèmes + de plugins utilisent le plus souvent, avec les définitions canoniques et ce qui est réellement dans chaque champ.

Les types TypeScript que les auteurs de thèmes + de plugins utilisent le plus souvent, avec les définitions canoniques et ce qui est réellement dans chaque champ.

Pour la liste exhaustive, voir la source : src/core/types.ts (types côté admin) et src/themes/types.ts (types côté thème).

Types de contenu

Post

Le même type couvre les posts (type: "post") et les pages (type: "page").

TS
interface Post {
  id: string;
  type: "post" | "page";
  title: string;
  slug: string;
  contentMarkdown: string;
  excerpt?: string;
  heroMediaId?: string;            // id du doc Media ; résoudre via `media.get(heroMediaId)`
  authorId: string;                // uid User
  primaryTermId?: string;          // catégorie principale (id de Term)
  termIds: string[];               // tous les termes (catégories + tags)
  status: "draft" | "online";
  publishedAt?: Timestamp;
  createdAt: Timestamp;
  updatedAt: Timestamp;
  lastPublishedPath?: string;       // chemin actuel sur Flexweg
  lastPublishedHash?: string;       // hash sha256 du HTML actuel
  previousPublishedPaths?: string[]; // chemins dont la suppression a échoué
  lastPublishedPathsByLocale?: Record<string, string>; // multilang
  seo?: SeoMeta;
  translations?: Record<string, unknown>; // données opaques de plugin (multilang)
}

Timestamp est firebase.firestore.Timestamp en mode Firebase, un objet équivalent (toMillis(), toDate()) en mode SQLite.

Term

Catégorie ou tag.

TS
interface Term {
  id: string;
  type: "category" | "tag";
  name: string;
  slug: string;
  description?: string;
  parentId?: string;                // catégories peuvent avoir un parent
  seo?: SeoMeta;
  translations?: Record<string, unknown>;
}

SeoMeta

TS
interface SeoMeta {
  title?: string;
  description?: string;
  ogImage?: string;
}

Sur un post : fallback vers title / excerpt / heroMedia. Sur un terme : fallback vers name / description.

Media

TS
interface Media {
  id: string;
  fileName: string;
  alt?: string;
  caption?: string;
  formats?: Record<string, MediaFormat>; // pipeline multi-variantes
  defaultFormat?: string;            // ex. "medium"
  url?: string;                      // legacy single-URL (ancienne version)
  size?: number;
  contentType?: string;
  uploadedBy?: string;
  createdAt: Timestamp;
}

interface MediaFormat {
  url: string;
  width: number;
  height: number;
  bytes?: number;
  format: string;                    // "webp", "svg", etc.
}

SiteSettings

TS
interface SiteSettings {
  title: string;
  description: string;
  language: string;                  // BCP-47
  baseUrl: string;                   // URL absolue du site
  activeThemeId: string;
  homeMode: "latest" | "static-page";
  homePageId?: string;
  paginationMode: "global" | "paginated";
  enabledPlugins: string[];
  menus: { header: MenuItem[]; footer: MenuItem[] };
  themeConfigs?: Record<string, unknown>;
  pluginConfigs?: Record<string, unknown>;
}

User

TS
interface User {
  uid: string;                       // Firebase Auth uid OU SQLite users.id
  email: string;
  firstName?: string;
  lastName?: string;
  bio?: string;
  avatarMediaId?: string;
  role: "admin" | "editor";
  preferences?: { adminLocale?: string };
  createdAt: Timestamp;
}

Types côté publication

PublishContext

Le contexte passé à chaque étape du pipeline de publication.

TS
interface PublishContext {
  settings: SiteSettings;
  posts: Post[];                     // tous les posts
  pages: Post[];                     // toutes les pages
  terms: Term[];                     // catégories + tags
  media: Map<string, Media>;
}

SiteContext

Le contexte passé au template du thème pour le rendu.

TS
interface SiteContext {
  settings: SiteSettings;
  resolvedMenus: { header: ResolvedMenuItem[]; footer: ResolvedMenuItem[] };
  themeCssPath: string;              // ex. "theme-assets/default.css"
  themeConfig?: unknown;             // la config résolue du thème
  homePath?: string;                 // pour le lien du logo (utile en multilang)
}

BaseLayoutProps

Les props du BaseLayout du thème.

TS
interface BaseLayoutProps {
  site: SiteContext;
  pageTitle: string;
  pageDescription?: string;
  ogImage?: string;
  currentPath: string;               // chemin de la page courante
  currentLocale?: string;            // langue courante (pour multilang)
  children: React.ReactNode;
}

Types de manifest

PluginManifest

TS
interface PluginManifest<TConfig = unknown> {
  id: string;
  name: string;
  version: string;
  description?: string;
  author?: string;
  readme?: string;
  register: (api: typeof pluginApi) => void;
  settings?: {
    navLabelKey: string;
    defaultConfig: TConfig;
    component: React.ComponentType<PluginSettingsPageProps<TConfig>>;
  };
  i18n?: Record<string, Record<string, unknown>>;
}

ThemeManifest

TS
interface ThemeManifest<TConfig = unknown> {
  id: string;
  name: string;
  version: string;
  description?: string;
  scssEntry?: string;
  cssText: string;
  compileCss?: (config: TConfig) => string;
  templates: {
    base: React.ComponentType<BaseLayoutProps>;
    home: React.ComponentType<unknown>;
    single: React.ComponentType<unknown>;
    category: React.ComponentType<unknown>;
    author: React.ComponentType<unknown>;
    notFound: React.ComponentType<unknown>;
  };
  formats?: ImageFormat[];           // pipeline d'images
  blocks?: BlockManifest[];
  settings?: {
    navLabelKey: string;
    defaultConfig: TConfig;
    component: React.ComponentType<unknown>;
  };
  i18n?: Record<string, Record<string, unknown>>;
}

BlockManifest

TS
interface BlockManifest {
  id: string;                        // "<namespace>/<name>"
  titleKey: string;
  namespace?: string;
  icon: React.ComponentType;
  category: "text" | "media" | "layout" | "embed" | "advanced";
  insert: (chain: Chain, ctx: { pickMedia: () => Promise<Media | null> }) => void;
  extensions?: Tiptap.Extension[];
  isActive?: (editor: Tiptap.Editor) => boolean;
  inspector?: React.ComponentType<{ attrs, updateAttrs, editor }>;
}

Types de hook

NewsLocaleEntry (sitemap.news.locales)

TS
interface NewsLocaleEntry {
  language: string;
  path: string;
  entities: SitemapEntity[];
}

RssLocaleEntry (rss.site.locales)

TS
interface RssLocaleEntry {
  language: string;
  path: string;
  channelTitle: string;
  channelLink: string;
  channelDescription: string;
  items: RssItem[];
}

RssItem

TS
interface RssItem {
  title: string;
  link: string;
  guid: string;
  description: string;
  pubDateMs: number;
  category?: string;
  enclosure?: { url: string; length: number; type: string };
}

AdditionalRender (publish.additional)

TS
interface AdditionalRender {
  path: string;
  html: string;
}

AdditionalListingRender (publish.extraListings)

Idem AdditionalRender.

MenuJson

Le format de /menu.json uploadé à la racine du site.

TS
interface MenuJson {
  header: ResolvedMenuItem[];
  footer: ResolvedMenuItem[];
  branding?: {
    siteTitle: string;
    logoUrl?: string;
  };
}

interface ResolvedMenuItem {
  id: string;
  label: string;
  href: string;
  children?: ResolvedMenuItem[];
  translations?: Record<string, { label: string }>;
}

Types côté thème

MediaView

Le shape Media consommable par les composants de thème — résolu par le publisher avant le rendu.

TS
interface MediaView {
  alt: string;
  caption?: string;
  default: string;                    // URL de la variante par défaut
  formats: Record<string, MediaFormatView>;
}

interface MediaFormatView {
  url: string;
  width: number;
  height: number;
}

AuthorView

TS
interface AuthorView {
  uid: string;
  displayName: string;                // "Prénom Nom"
  bio?: string;
  avatarUrl?: string;
}

ResolvedMenuItem

Voir MenuJson ci-dessus.

SingleTemplateProps

TS
interface SingleTemplateProps {
  site: SiteContext;
  post: CardPost;                     // forme enrichie de Post avec URL, hero, category
  bodyHtml: string;                   // HTML rendu du markdown du post
  author?: AuthorView;
  relatedPosts?: CardPost[];          // si le thème en surface
}

CategoryTemplateProps

TS
interface CategoryTemplateProps {
  site: SiteContext;
  term: Term;
  posts: CardPost[];                  // posts dans cette catégorie
  archivesLink?: string;
  popularTags?: Term[];
}