Comprehensive TypeScript type definitions and interfaces for the Slidev presentation framework ecosystem
—
Command-line interface types for Slidev's build, export, and development commands.
Base interface for common command-line arguments.
/**
* Common arguments interface for CLI commands
*/
interface CommonArgs {
/** Entry file path for the presentation */
entry: string;
/** Theme name to use for the presentation */
theme?: string;
}Arguments interface for export commands.
/**
* Export command arguments interface
*/
interface ExportArgs extends CommonArgs {
/** Output file or directory path */
'output'?: string;
/** Export format (pdf, png, md, etc.) */
'format'?: string;
/** Timeout for export operations in milliseconds */
'timeout'?: number;
/** Wait time before capturing in milliseconds */
'wait'?: number;
/** Wait until condition for export */
'wait-until'?: string;
/** Page range for export (e.g., "1-5,8,10-12") */
'range'?: string;
/** Use dark theme for export */
'dark'?: boolean;
/** Include click animations in export */
'with-clicks'?: boolean;
/** Path to executable for export engine */
'executable-path'?: string;
/** Include table of contents in export */
'with-toc'?: boolean;
/** Export each slide as separate file */
'per-slide'?: boolean;
/** Scale factor for export output */
'scale'?: number;
/** Omit background in export */
'omit-background'?: boolean;
}Arguments interface for build commands.
/**
* Build command arguments interface
*/
interface BuildArgs extends ExportArgs {
/** Output directory for built files */
out: string;
/** Base URL for the built application */
base?: string;
/** Enable download functionality in build */
download?: boolean;
/** Enable Vite inspect plugin */
inspect: boolean;
}CLI Command Type Usage:
import type { CommonArgs, ExportArgs, BuildArgs } from "@slidev/types";
// Function using common arguments
function processEntry(args: CommonArgs) {
console.log(`Processing entry: ${args.entry}`);
if (args.theme) {
console.log(`Using theme: ${args.theme}`);
}
}
// Function for export operations
function handleExport(args: ExportArgs) {
processEntry(args);
const options = {
output: args.output || './output',
format: args.format || 'pdf',
timeout: args.timeout || 30000,
darkTheme: args.dark || false,
includeClicks: args['with-clicks'] || false
};
console.log('Export options:', options);
if (args.range) {
console.log(`Exporting pages: ${args.range}`);
}
if (args['per-slide']) {
console.log('Exporting each slide separately');
}
}
// Function for build operations
function handleBuild(args: BuildArgs) {
handleExport(args);
console.log(`Building to: ${args.out}`);
if (args.base) {
console.log(`Base URL: ${args.base}`);
}
if (args.download) {
console.log('Download functionality enabled');
}
if (args.inspect) {
console.log('Vite inspect plugin enabled');
}
}Command Validation:
function validateExportArgs(args: Partial<ExportArgs>): args is ExportArgs {
if (!args.entry) {
throw new Error('Entry file is required');
}
if (args.timeout && args.timeout < 1000) {
console.warn('Timeout less than 1 second may cause issues');
}
if (args.scale && (args.scale < 0.1 || args.scale > 5)) {
throw new Error('Scale must be between 0.1 and 5');
}
if (args.range && !isValidRange(args.range)) {
throw new Error('Invalid page range format');
}
return true;
}
function isValidRange(range: string): boolean {
// Simple validation for range format like "1-5,8,10-12"
const rangePattern = /^(\d+(-\d+)?)(,\d+(-\d+)?)*$/;
return rangePattern.test(range);
}CLI Parser Integration:
interface CLIConfig {
dev: CommonArgs & {
port?: number;
host?: string;
open?: boolean;
};
build: BuildArgs;
export: ExportArgs;
}
function parseCliArgs(command: keyof CLIConfig, rawArgs: string[]): CLIConfig[typeof command] {
const args: any = {};
for (let i = 0; i < rawArgs.length; i++) {
const arg = rawArgs[i];
if (arg.startsWith('--')) {
const key = arg.slice(2);
const value = rawArgs[i + 1];
// Handle boolean flags
if (!value || value.startsWith('--')) {
args[key] = true;
} else {
// Handle typed values
if (key === 'timeout' || key === 'wait' || key === 'scale') {
args[key] = parseFloat(value);
} else if (key === 'dark' || key === 'with-clicks' || key === 'per-slide' ||
key === 'with-toc' || key === 'omit-background' || key === 'inspect') {
args[key] = true;
} else {
args[key] = value;
}
i++; // Skip the value
}
} else if (!args.entry) {
args.entry = arg;
}
}
return args;
}Export Options Builder:
class ExportOptionsBuilder {
private options: Partial<ExportArgs> = {};
entry(path: string): this {
this.options.entry = path;
return this;
}
theme(name: string): this {
this.options.theme = name;
return this;
}
output(path: string): this {
this.options.output = path;
return this;
}
format(fmt: string): this {
this.options.format = fmt;
return this;
}
timeout(ms: number): this {
this.options.timeout = ms;
return this;
}
range(pageRange: string): this {
this.options.range = pageRange;
return this;
}
withClicks(enabled = true): this {
this.options['with-clicks'] = enabled;
return this;
}
darkMode(enabled = true): this {
this.options.dark = enabled;
return this;
}
scale(factor: number): this {
this.options.scale = factor;
return this;
}
build(): ExportArgs {
if (!this.options.entry) {
throw new Error('Entry is required');
}
return this.options as ExportArgs;
}
}
// Usage
const exportOptions = new ExportOptionsBuilder()
.entry('./slides.md')
.theme('academic')
.format('pdf')
.withClicks(true)
.darkMode(false)
.range('1-10')
.build();Install with Tessl CLI
npx tessl i tessl/npm-slidev--types