@bernierllc/content-type-blog-post
Version:
Blog post content type with rich TipTap editor, SEO metadata, database storage, and web publishing
215 lines (214 loc) • 6.36 kB
TypeScript
import { z } from 'zod';
/**
* Blog post SEO metadata schema
* Note: Allows empty strings for draft posts. Use validateSEOCompleteness() to enforce completeness before publishing.
*/
export declare const BlogPostSEOSchema: z.ZodObject<{
metaTitle: z.ZodString;
metaDescription: z.ZodString;
keywords: z.ZodArray<z.ZodString, "many">;
ogImage: z.ZodOptional<z.ZodString>;
ogType: z.ZodDefault<z.ZodLiteral<"article">>;
canonicalUrl: z.ZodOptional<z.ZodString>;
}, "strip", z.ZodTypeAny, {
metaTitle: string;
metaDescription: string;
keywords: string[];
ogType: "article";
ogImage?: string | undefined;
canonicalUrl?: string | undefined;
}, {
metaTitle: string;
metaDescription: string;
keywords: string[];
ogImage?: string | undefined;
ogType?: "article" | undefined;
canonicalUrl?: string | undefined;
}>;
export type BlogPostSEO = z.infer<typeof BlogPostSEOSchema>;
/**
* Blog post author metadata schema
*/
export declare const BlogPostAuthorSchema: z.ZodObject<{
name: z.ZodString;
email: z.ZodOptional<z.ZodString>;
avatar: z.ZodOptional<z.ZodString>;
bio: z.ZodOptional<z.ZodString>;
}, "strip", z.ZodTypeAny, {
name: string;
email?: string | undefined;
avatar?: string | undefined;
bio?: string | undefined;
}, {
name: string;
email?: string | undefined;
avatar?: string | undefined;
bio?: string | undefined;
}>;
export type BlogPostAuthor = z.infer<typeof BlogPostAuthorSchema>;
/**
* Blog post workflow status
*/
export declare const BlogPostStatusSchema: z.ZodEnum<["draft", "published", "scheduled", "archived"]>;
export type BlogPostStatus = z.infer<typeof BlogPostStatusSchema>;
/**
* Blog post metadata schema (extends text content metadata)
*/
export declare const BlogPostMetadataSchema: z.ZodObject<{
content: z.ZodString;
createdAt: z.ZodDate;
updatedAt: z.ZodDate;
title: z.ZodString;
slug: z.ZodString;
excerpt: z.ZodOptional<z.ZodString>;
seo: z.ZodObject<{
metaTitle: z.ZodString;
metaDescription: z.ZodString;
keywords: z.ZodArray<z.ZodString, "many">;
ogImage: z.ZodOptional<z.ZodString>;
ogType: z.ZodDefault<z.ZodLiteral<"article">>;
canonicalUrl: z.ZodOptional<z.ZodString>;
}, "strip", z.ZodTypeAny, {
metaTitle: string;
metaDescription: string;
keywords: string[];
ogType: "article";
ogImage?: string | undefined;
canonicalUrl?: string | undefined;
}, {
metaTitle: string;
metaDescription: string;
keywords: string[];
ogImage?: string | undefined;
ogType?: "article" | undefined;
canonicalUrl?: string | undefined;
}>;
author: z.ZodObject<{
name: z.ZodString;
email: z.ZodOptional<z.ZodString>;
avatar: z.ZodOptional<z.ZodString>;
bio: z.ZodOptional<z.ZodString>;
}, "strip", z.ZodTypeAny, {
name: string;
email?: string | undefined;
avatar?: string | undefined;
bio?: string | undefined;
}, {
name: string;
email?: string | undefined;
avatar?: string | undefined;
bio?: string | undefined;
}>;
tags: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
categories: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
status: z.ZodDefault<z.ZodEnum<["draft", "published", "scheduled", "archived"]>>;
publishedAt: z.ZodOptional<z.ZodDate>;
scheduledFor: z.ZodOptional<z.ZodDate>;
featuredImage: z.ZodOptional<z.ZodString>;
readingTime: z.ZodOptional<z.ZodNumber>;
wordCount: z.ZodDefault<z.ZodNumber>;
}, "strip", z.ZodTypeAny, {
status: "draft" | "published" | "scheduled" | "archived";
content: string;
createdAt: Date;
updatedAt: Date;
title: string;
slug: string;
seo: {
metaTitle: string;
metaDescription: string;
keywords: string[];
ogType: "article";
ogImage?: string | undefined;
canonicalUrl?: string | undefined;
};
author: {
name: string;
email?: string | undefined;
avatar?: string | undefined;
bio?: string | undefined;
};
tags: string[];
categories: string[];
wordCount: number;
excerpt?: string | undefined;
publishedAt?: Date | undefined;
scheduledFor?: Date | undefined;
featuredImage?: string | undefined;
readingTime?: number | undefined;
}, {
content: string;
createdAt: Date;
updatedAt: Date;
title: string;
slug: string;
seo: {
metaTitle: string;
metaDescription: string;
keywords: string[];
ogImage?: string | undefined;
ogType?: "article" | undefined;
canonicalUrl?: string | undefined;
};
author: {
name: string;
email?: string | undefined;
avatar?: string | undefined;
bio?: string | undefined;
};
status?: "draft" | "published" | "scheduled" | "archived" | undefined;
excerpt?: string | undefined;
tags?: string[] | undefined;
categories?: string[] | undefined;
publishedAt?: Date | undefined;
scheduledFor?: Date | undefined;
featuredImage?: string | undefined;
readingTime?: number | undefined;
wordCount?: number | undefined;
}>;
export type BlogPostMetadata = z.infer<typeof BlogPostMetadataSchema>;
/**
* TipTap editor configuration for blog posts
*/
export interface TipTapEditorConfig {
type: 'tiptap-wysiwyg';
extensions: string[];
placeholder?: string;
editable?: boolean;
autofocus?: boolean | 'start' | 'end';
}
/**
* Database storage configuration
*/
export interface DatabaseStorageConfig {
type: 'database';
table: string;
client?: any;
}
/**
* Web publishing configuration
*/
export interface WebPublishingConfig {
type: 'web';
urlPattern: string;
baseUrl?: string;
}
/**
* Blog post content result
*/
export interface BlogPostResult<T = unknown> {
success: boolean;
data?: T;
error?: string;
}
/**
* Blog post content type configuration
*/
export interface BlogPostContentTypeConfig {
id?: string;
name?: string;
editor?: TipTapEditorConfig;
metadata?: z.ZodType<BlogPostMetadata>;
storage?: DatabaseStorageConfig;
publishing?: WebPublishingConfig;
}