mirror of
https://github.com/amitwh/markdown-converter.git
synced 2026-08-02 18:10:18 +05:30
feat(renderer): zod validators for settings + export schemas
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
export const settingsSchema = z.object({
|
||||
fontSize: z.number().min(10).max(24).default(14),
|
||||
tabSize: z.union([z.literal(2), z.literal(4), z.literal(8)]).default(4),
|
||||
lineNumbers: z.boolean().default(true),
|
||||
wordWrap: z.boolean().default(true),
|
||||
minimap: z.boolean().default(true),
|
||||
theme: z.enum(['light', 'dark', 'auto']).default('auto'),
|
||||
accentColor: z.enum(['brand', 'blue', 'green', 'purple', 'orange']).default('brand'),
|
||||
fontFamily: z.enum(['system', 'jetbrains', 'fira']).default('system'),
|
||||
pdfFormat: z.enum(['letter', 'a4', 'legal']).default('a4'),
|
||||
pdfMargins: z.enum(['normal', 'narrow', 'wide']).default('normal'),
|
||||
pdfEmbedFonts: z.boolean().default(true),
|
||||
docxTemplate: z.enum(['standard', 'minimal', 'modern']).default('standard'),
|
||||
htmlHighlightStyle: z.enum(['github', 'monokai', 'nord', 'none']).default('github'),
|
||||
renderTablesAsAscii: z.boolean().default(false),
|
||||
welcomeDismissed: z.boolean().default(false),
|
||||
});
|
||||
export type Settings = z.infer<typeof settingsSchema>;
|
||||
|
||||
export const exportPdfSchema = z.object({
|
||||
format: z.enum(['letter', 'a4', 'legal']),
|
||||
margins: z.enum(['normal', 'narrow', 'wide']),
|
||||
embedFonts: z.boolean(),
|
||||
renderTablesAsAscii: z.boolean().optional(),
|
||||
});
|
||||
export type ExportPdfOptions = z.infer<typeof exportPdfSchema>;
|
||||
|
||||
export const exportDocxSchema = z.object({
|
||||
template: z.enum(['standard', 'minimal', 'modern']),
|
||||
renderTablesAsAscii: z.boolean().optional(),
|
||||
});
|
||||
export type ExportDocxOptions = z.infer<typeof exportDocxSchema>;
|
||||
|
||||
export const exportHtmlSchema = z.object({
|
||||
standalone: z.boolean(),
|
||||
highlightStyle: z.enum(['github', 'monokai', 'nord', 'none']),
|
||||
renderTablesAsAscii: z.boolean().optional(),
|
||||
});
|
||||
export type ExportHtmlOptions = z.infer<typeof exportHtmlSchema>;
|
||||
|
||||
export const exportBatchSchema = z.object({
|
||||
format: z.enum(['pdf', 'docx', 'html', 'png']),
|
||||
concurrency: z.number().int().min(1).max(16),
|
||||
filePaths: z.array(z.string()).min(1),
|
||||
});
|
||||
export type ExportBatchOptions = z.infer<typeof exportBatchSchema>;
|
||||
@@ -0,0 +1,53 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import {
|
||||
settingsSchema,
|
||||
exportPdfSchema,
|
||||
exportDocxSchema,
|
||||
exportHtmlSchema,
|
||||
exportBatchSchema,
|
||||
} from '@/lib/validators';
|
||||
|
||||
describe('settingsSchema', () => {
|
||||
it('accepts an empty object (all fields have defaults)', () => {
|
||||
const r = settingsSchema.safeParse({});
|
||||
expect(r.success).toBe(true);
|
||||
});
|
||||
|
||||
it('rejects out-of-range fontSize', () => {
|
||||
const r = settingsSchema.safeParse({ fontSize: 100 });
|
||||
expect(r.success).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('exportPdfSchema', () => {
|
||||
it('accepts a4 + normal margins + embedFonts true', () => {
|
||||
expect(exportPdfSchema.safeParse({ format: 'a4', margins: 'normal', embedFonts: true }).success).toBe(true);
|
||||
});
|
||||
it('rejects unknown format', () => {
|
||||
expect(exportPdfSchema.safeParse({ format: 'b4' }).success).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('exportDocxSchema', () => {
|
||||
it('accepts standard template', () => {
|
||||
expect(exportDocxSchema.safeParse({ template: 'standard' }).success).toBe(true);
|
||||
});
|
||||
it('rejects unknown template', () => {
|
||||
expect(exportDocxSchema.safeParse({ template: 'fancy' }).success).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('exportHtmlSchema', () => {
|
||||
it('accepts github highlight style', () => {
|
||||
expect(exportHtmlSchema.safeParse({ standalone: true, highlightStyle: 'github' }).success).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('exportBatchSchema', () => {
|
||||
it('accepts a non-empty file list', () => {
|
||||
expect(exportBatchSchema.safeParse({ format: 'pdf', concurrency: 4, filePaths: ['/a.md'] }).success).toBe(true);
|
||||
});
|
||||
it('rejects empty file list', () => {
|
||||
expect(exportBatchSchema.safeParse({ format: 'pdf', concurrency: 4, filePaths: [] }).success).toBe(false);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user