create-roadkit
Version:
Beautiful Next.js roadmap website generator with full-screen kanban boards, dark/light mode, and static export
296 lines (273 loc) • 8.63 kB
text/typescript
/**
* Configuration types and interfaces for the RoadKit project scaffolding system.
*
* This module defines the core configuration structure, user choices, project settings,
* and validation schemas used throughout the scaffolding process. All configurations
* are strongly typed to ensure type safety and proper validation.
*/
import { z } from 'zod';
/**
* Available project themes for customizing the generated roadmap websites
* Each theme provides a different visual style and component set
*/
export const AVAILABLE_THEMES = ['modern', 'classic', 'minimal', 'corporate'] as const;
export type Theme = typeof AVAILABLE_THEMES[number];
/**
* Available project templates that define the base structure and features
* Each template provides different functionality and use cases
*/
export const AVAILABLE_TEMPLATES = ['basic', 'advanced', 'enterprise', 'custom'] as const;
export type Template = typeof AVAILABLE_TEMPLATES[number];
/**
* Project configuration schema for validation using Zod
* This ensures all configuration data is properly structured and valid
*/
export const ProjectConfigSchema = z.object({
// Basic project information
name: z.string()
.min(1, 'Project name is required')
.max(50, 'Project name must be 50 characters or less')
.regex(/^[a-zA-Z0-9-_]+$/, 'Project name must contain only alphanumeric characters, hyphens, and underscores'),
description: z.string()
.min(1, 'Project description is required')
.max(200, 'Project description must be 200 characters or less'),
version: z.string()
.regex(/^\d+\.\d+\.\d+$/, 'Version must follow semantic versioning (e.g., 1.0.0)')
.default('1.0.0'),
author: z.object({
name: z.string().min(1, 'Author name is required'),
email: z.string().email('Valid email is required').optional(),
url: z.string().url('Valid URL is required').optional(),
}),
// Project structure and features
template: z.enum(AVAILABLE_TEMPLATES),
theme: z.enum(AVAILABLE_THEMES),
// Advanced configuration options
features: z.object({
analytics: z.boolean().default(false),
seo: z.boolean().default(true),
pwa: z.boolean().default(false),
authentication: z.boolean().default(false),
database: z.boolean().default(false),
api: z.boolean().default(true),
testing: z.boolean().default(true),
deployment: z.boolean().default(true),
}).default({}),
// Customization options
customization: z.object({
primaryColor: z.string().regex(/^#[0-9A-Fa-f]{6}$/, 'Primary color must be a valid hex color').default('#3b82f6'),
secondaryColor: z.string().regex(/^#[0-9A-Fa-f]{6}$/, 'Secondary color must be a valid hex color').default('#64748b'),
fontFamily: z.enum(['inter', 'roboto', 'open-sans', 'poppins']).default('inter'),
logoUrl: z.string().url().optional(),
faviconUrl: z.string().url().optional(),
}).default({}),
// Technical configuration
technical: z.object({
nodeVersion: z.string().default('20'),
bunVersion: z.string().default('latest'),
typescript: z.boolean().default(true),
eslint: z.boolean().default(true),
prettier: z.boolean().default(true),
tailwind: z.boolean().default(true),
shadcnUi: z.boolean().default(true),
}).default({}),
// Output configuration
output: z.object({
directory: z.string().min(1, 'Output directory is required'),
overwrite: z.boolean().default(false),
gitInit: z.boolean().default(true),
installDependencies: z.boolean().default(true),
}),
// Metadata for tracking and validation
metadata: z.object({
created: z.date().default(() => new Date()),
generator: z.string().default('roadkit'),
version: z.string().default('1.0.0'),
}).default({}),
});
/**
* Inferred TypeScript type from the Zod schema
* This provides full type safety throughout the application
*/
export type ProjectConfig = z.infer<typeof ProjectConfigSchema>;
/**
* User choices collected during the interactive CLI setup
* This interface represents the raw user input before validation
*/
export interface UserChoices {
projectName: string;
description: string;
author: {
name: string;
email?: string;
url?: string;
};
template: Template;
theme: Theme;
outputDirectory: string;
features: {
analytics?: boolean;
seo?: boolean;
pwa?: boolean;
authentication?: boolean;
database?: boolean;
api?: boolean;
testing?: boolean;
deployment?: boolean;
};
customization: {
primaryColor?: string;
secondaryColor?: string;
fontFamily?: string;
logoUrl?: string;
faviconUrl?: string;
};
technical: {
typescript?: boolean;
eslint?: boolean;
prettier?: boolean;
tailwind?: boolean;
shadcnUi?: boolean;
};
overwrite?: boolean;
gitInit?: boolean;
installDependencies?: boolean;
}
/**
* Configuration validation result with detailed error information
* This provides comprehensive feedback for configuration issues
*/
export interface ConfigValidationResult {
success: boolean;
config?: ProjectConfig;
errors?: Array<{
field: string;
message: string;
code: string;
}>;
}
/**
* Project generation context passed throughout the scaffolding process
* This contains all necessary information for generating the complete project
*/
export interface ProjectContext {
config: ProjectConfig;
templatePath: string;
themePath: string;
outputPath: string;
tempPath?: string;
startTime: Date;
progress: {
total: number;
current: number;
stage: string;
message?: string;
};
}
/**
* Template file processing context for customization and replacement
* This defines how template files should be processed and customized
*/
export interface TemplateContext {
projectName: string;
projectNamePascal: string;
projectNameKebab: string;
projectNameSnake: string;
description: string;
author: ProjectConfig['author'];
version: string;
primaryColor: string;
secondaryColor: string;
fontFamily: string;
currentYear: number;
timestamp: string;
features: ProjectConfig['features'];
technical: ProjectConfig['technical'];
[key: string]: unknown; // Allow for additional template variables
}
/**
* File operation result for tracking success/failure of individual operations
* This provides detailed feedback for file operations during scaffolding
*/
export interface FileOperationResult {
success: boolean;
path: string;
operation: 'copy' | 'create' | 'modify' | 'delete';
error?: string;
skipped?: boolean;
reason?: string;
}
/**
* Project generation result with comprehensive feedback and rollback information
* This provides complete information about the scaffolding operation outcome
*/
export interface ProjectGenerationResult {
success: boolean;
projectPath?: string;
config?: ProjectConfig;
filesCreated?: string[];
filesModified?: string[];
errors?: string[];
warnings?: string[];
rollbackInfo?: {
canRollback: boolean;
rollbackPath?: string;
rollbackInstructions?: string[];
};
duration?: number;
nextSteps?: string[];
}
/**
* Progress callback function type for reporting scaffolding progress
* This allows for real-time progress updates during project generation
*/
export type ProgressCallback = (stage: string, current: number, total: number, message?: string) => void;
/**
* Logger interface for consistent logging throughout the scaffolding system
* This ensures proper logging and debugging capabilities
*/
export interface Logger {
info: (message: string, data?: unknown) => void;
warn: (message: string, data?: unknown) => void;
error: (message: string, error?: Error | unknown) => void;
debug: (message: string, data?: unknown) => void;
success: (message: string, data?: unknown) => void;
}
/**
* Default project configuration values used as fallbacks
* This ensures consistent defaults across all project generations
*/
export const DEFAULT_CONFIG: Partial<ProjectConfig> = {
version: '1.0.0',
template: 'basic',
theme: 'modern',
features: {
analytics: false,
seo: true,
pwa: false,
authentication: false,
database: false,
api: true,
testing: true,
deployment: true,
},
customization: {
primaryColor: '#3b82f6',
secondaryColor: '#64748b',
fontFamily: 'inter',
},
technical: {
nodeVersion: '20',
bunVersion: 'latest',
typescript: true,
eslint: true,
prettier: true,
tailwind: true,
shadcnUi: true,
},
output: {
overwrite: false,
gitInit: true,
installDependencies: true,
},
};