@pep/term-deck 1.0.15 → 1.0.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/term-deck.js +826 -630
- package/dist/bin/term-deck.js.map +1 -1
- package/dist/index.d.ts +10 -10
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -212,8 +212,9 @@ declare const DeckConfigSchema: z.ZodObject<{
|
|
|
212
212
|
height?: number;
|
|
213
213
|
fps?: number;
|
|
214
214
|
};
|
|
215
|
-
|
|
215
|
+
author?: string;
|
|
216
216
|
date?: string;
|
|
217
|
+
title?: string;
|
|
217
218
|
theme?: {
|
|
218
219
|
name?: string;
|
|
219
220
|
description?: string;
|
|
@@ -250,7 +251,6 @@ declare const DeckConfigSchema: z.ZodObject<{
|
|
|
250
251
|
};
|
|
251
252
|
};
|
|
252
253
|
};
|
|
253
|
-
author?: string;
|
|
254
254
|
settings?: {
|
|
255
255
|
startSlide?: number;
|
|
256
256
|
loop?: boolean;
|
|
@@ -264,8 +264,9 @@ declare const DeckConfigSchema: z.ZodObject<{
|
|
|
264
264
|
height?: number;
|
|
265
265
|
fps?: number;
|
|
266
266
|
};
|
|
267
|
-
|
|
267
|
+
author?: string;
|
|
268
268
|
date?: string;
|
|
269
|
+
title?: string;
|
|
269
270
|
theme?: {
|
|
270
271
|
name?: string;
|
|
271
272
|
description?: string;
|
|
@@ -302,7 +303,6 @@ declare const DeckConfigSchema: z.ZodObject<{
|
|
|
302
303
|
};
|
|
303
304
|
};
|
|
304
305
|
};
|
|
305
|
-
author?: string;
|
|
306
306
|
settings?: {
|
|
307
307
|
startSlide?: number;
|
|
308
308
|
loop?: boolean;
|
|
@@ -510,16 +510,16 @@ declare const SlideFrontmatterSchema: z.ZodObject<{
|
|
|
510
510
|
meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
511
511
|
}, "strip", z.ZodTypeAny, {
|
|
512
512
|
title?: string;
|
|
513
|
+
theme?: string;
|
|
513
514
|
bigText?: string | string[];
|
|
514
515
|
gradient?: string;
|
|
515
|
-
theme?: string;
|
|
516
516
|
transition?: "glitch" | "fade" | "instant" | "typewriter";
|
|
517
517
|
meta?: Record<string, unknown>;
|
|
518
518
|
}, {
|
|
519
519
|
title?: string;
|
|
520
|
+
theme?: string;
|
|
520
521
|
bigText?: string | string[];
|
|
521
522
|
gradient?: string;
|
|
522
|
-
theme?: string;
|
|
523
523
|
transition?: "glitch" | "fade" | "instant" | "typewriter";
|
|
524
524
|
meta?: Record<string, unknown>;
|
|
525
525
|
}>;
|
|
@@ -538,16 +538,16 @@ declare const SlideSchema: z.ZodObject<{
|
|
|
538
538
|
meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
539
539
|
}, "strip", z.ZodTypeAny, {
|
|
540
540
|
title?: string;
|
|
541
|
+
theme?: string;
|
|
541
542
|
bigText?: string | string[];
|
|
542
543
|
gradient?: string;
|
|
543
|
-
theme?: string;
|
|
544
544
|
transition?: "glitch" | "fade" | "instant" | "typewriter";
|
|
545
545
|
meta?: Record<string, unknown>;
|
|
546
546
|
}, {
|
|
547
547
|
title?: string;
|
|
548
|
+
theme?: string;
|
|
548
549
|
bigText?: string | string[];
|
|
549
550
|
gradient?: string;
|
|
550
|
-
theme?: string;
|
|
551
551
|
transition?: "glitch" | "fade" | "instant" | "typewriter";
|
|
552
552
|
meta?: Record<string, unknown>;
|
|
553
553
|
}>;
|
|
@@ -558,9 +558,9 @@ declare const SlideSchema: z.ZodObject<{
|
|
|
558
558
|
}, "strip", z.ZodTypeAny, {
|
|
559
559
|
frontmatter?: {
|
|
560
560
|
title?: string;
|
|
561
|
+
theme?: string;
|
|
561
562
|
bigText?: string | string[];
|
|
562
563
|
gradient?: string;
|
|
563
|
-
theme?: string;
|
|
564
564
|
transition?: "glitch" | "fade" | "instant" | "typewriter";
|
|
565
565
|
meta?: Record<string, unknown>;
|
|
566
566
|
};
|
|
@@ -571,9 +571,9 @@ declare const SlideSchema: z.ZodObject<{
|
|
|
571
571
|
}, {
|
|
572
572
|
frontmatter?: {
|
|
573
573
|
title?: string;
|
|
574
|
+
theme?: string;
|
|
574
575
|
bigText?: string | string[];
|
|
575
576
|
gradient?: string;
|
|
576
|
-
theme?: string;
|
|
577
577
|
transition?: "glitch" | "fade" | "instant" | "typewriter";
|
|
578
578
|
meta?: Record<string, unknown>;
|
|
579
579
|
};
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/schemas/theme.ts","../src/schemas/config.ts","../src/schemas/validation.ts","../src/core/theme.ts","../src/index.ts"],"names":["z","parseYaml"],"mappings":"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","file":"index.js","sourcesContent":["import { z } from 'zod'\n\n/**\n * Schema for validating hex color strings.\n * Accepts 6-digit hex colors with # prefix (e.g., #ff0066)\n */\nexport const HexColorSchema = z.string().regex(/^#[0-9a-fA-F]{6}$/, {\n message: 'Color must be a valid hex color (e.g., #ff0066)',\n})\n\nexport type HexColor = z.infer<typeof HexColorSchema>\n\n/**\n * Schema for validating gradient color arrays.\n * A gradient requires at least 2 hex colors.\n */\nexport const GradientSchema = z.array(HexColorSchema).min(2, {\n message: 'Gradient must have at least 2 colors',\n})\n\nexport type Gradient = z.infer<typeof GradientSchema>\n\n/**\n * Schema for validating theme objects.\n * Defines the visual appearance of the presentation deck.\n */\nexport const ThemeSchema = z.object({\n // Theme metadata\n name: z.string().min(1, { message: 'Theme name is required' }),\n description: z.string().optional(),\n author: z.string().optional(),\n version: z.string().optional(),\n\n // Color palette\n colors: z.object({\n primary: HexColorSchema,\n secondary: HexColorSchema.optional(),\n accent: HexColorSchema,\n background: HexColorSchema,\n text: HexColorSchema,\n muted: HexColorSchema,\n success: HexColorSchema.optional(),\n warning: HexColorSchema.optional(),\n error: HexColorSchema.optional(),\n }),\n\n // Named gradients for bigText\n gradients: z.record(z.string(), GradientSchema).refine(\n (g) => Object.keys(g).length >= 1,\n { message: 'At least one gradient must be defined' }\n ),\n\n // Glyph set for matrix rain background\n glyphs: z.string().min(10, {\n message: 'Glyph set must have at least 10 characters',\n }),\n\n // Animation settings\n animations: z.object({\n // Speed multiplier (1.0 = normal, 0.5 = half speed, 2.0 = double speed)\n revealSpeed: z.number().min(0.1).max(5.0).default(1.0),\n // Matrix rain density (number of drops)\n matrixDensity: z.number().min(10).max(200).default(50),\n // Glitch effect iterations\n glitchIterations: z.number().min(1).max(20).default(5),\n // Delay between lines during reveal (ms)\n lineDelay: z.number().min(0).max(500).default(30),\n // Matrix rain update interval (ms)\n matrixInterval: z.number().min(20).max(200).default(80),\n }),\n\n // Window appearance\n window: z.object({\n // Border style\n borderStyle: z.enum(['line', 'double', 'rounded', 'none']).default('line'),\n // Shadow effect\n shadow: z.boolean().default(true),\n // Padding inside windows\n padding: z.object({\n top: z.number().min(0).max(5).default(1),\n bottom: z.number().min(0).max(5).default(1),\n left: z.number().min(0).max(10).default(2),\n right: z.number().min(0).max(10).default(2),\n }).optional(),\n }).optional(),\n})\n\nexport type Theme = z.infer<typeof ThemeSchema>\n\n// ============================================================================\n// Color Token System\n// ============================================================================\n\n/**\n * Valid color tokens for inline styling in slide body content.\n * Tokens can be either:\n * - Built-in colors: GREEN, ORANGE, CYAN, PINK, WHITE, GRAY\n * - Theme-mapped colors: PRIMARY, SECONDARY, ACCENT, MUTED, TEXT, BACKGROUND\n *\n * Usage in slides: {GREEN}colored text{/}\n */\nexport const ColorTokens = [\n 'GREEN',\n 'ORANGE',\n 'CYAN',\n 'PINK',\n 'WHITE',\n 'GRAY',\n 'PRIMARY', // Maps to theme.colors.primary\n 'SECONDARY', // Maps to theme.colors.secondary\n 'ACCENT', // Maps to theme.colors.accent\n 'MUTED', // Maps to theme.colors.muted\n 'TEXT', // Maps to theme.colors.text\n 'BACKGROUND', // Maps to theme.colors.background\n] as const\n\n/**\n * Type for valid color token names.\n */\nexport type ColorToken = typeof ColorTokens[number]\n\n/**\n * Pattern for matching color tokens in slide content.\n * Matches: {GREEN}, {ORANGE}, {CYAN}, {PINK}, {WHITE}, {GRAY},\n * {PRIMARY}, {SECONDARY}, {ACCENT}, {MUTED}, {TEXT}, {BACKGROUND}, {/}\n *\n * The {/} token closes any open color tag.\n */\nexport const COLOR_TOKEN_PATTERN = /\\{(GREEN|ORANGE|CYAN|PINK|WHITE|GRAY|PRIMARY|SECONDARY|ACCENT|MUTED|TEXT|BACKGROUND|\\/)\\}/g\n\n// ============================================================================\n// Partial Theme for Extension\n// ============================================================================\n\n/**\n * Deep partial utility type that makes all nested properties optional.\n * Used for theme extension where only specific fields need to be overridden.\n */\nexport type DeepPartial<T> = T extends object ? {\n [P in keyof T]?: DeepPartial<T[P]>\n} : T\n\n/**\n * Partial theme type for use with theme.extend() functionality.\n * All fields (including nested) become optional.\n */\nexport type PartialTheme = DeepPartial<Theme>\n\n/**\n * Schema for validating partial theme objects.\n * All fields become optional recursively, allowing partial overrides.\n * Used for theme extension validation.\n */\nexport const PartialThemeSchema = ThemeSchema.deepPartial()\n\n// ============================================================================\n// Default Theme\n// ============================================================================\n\n/**\n * Default matrix/cyberpunk theme.\n * Used when no theme is specified or as a base for theme extension.\n */\nexport const DEFAULT_THEME: Theme = {\n name: 'matrix',\n description: 'Default cyberpunk/matrix theme',\n\n colors: {\n primary: '#00cc66',\n accent: '#ff6600',\n background: '#0a0a0a',\n text: '#ffffff',\n muted: '#666666',\n },\n\n gradients: {\n fire: ['#ff6600', '#ff3300', '#ff0066'],\n cool: ['#00ccff', '#0066ff', '#6600ff'],\n pink: ['#ff0066', '#ff0099', '#cc00ff'],\n hf: ['#99cc00', '#00cc66', '#00cccc'],\n },\n\n glyphs: 'アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン0123456789',\n\n animations: {\n revealSpeed: 1.0,\n matrixDensity: 50,\n glitchIterations: 5,\n lineDelay: 30,\n matrixInterval: 80,\n },\n\n window: {\n borderStyle: 'line',\n shadow: true,\n padding: {\n top: 1,\n bottom: 1,\n left: 2,\n right: 2,\n },\n },\n}\n","import { z } from 'zod'\nimport { ThemeSchema } from './theme'\n\n/**\n * Schema for presentation settings.\n * Controls how the presentation behaves during runtime.\n */\nexport const SettingsSchema = z.object({\n // Start slide (0-indexed)\n startSlide: z.number().min(0).default(0),\n // Loop back to first slide after last\n loop: z.boolean().default(false),\n // Auto-advance slides (ms, 0 = disabled)\n autoAdvance: z.number().min(0).default(0),\n // Show slide numbers\n showSlideNumbers: z.boolean().default(false),\n // Show progress bar\n showProgress: z.boolean().default(false),\n})\n\nexport type Settings = z.infer<typeof SettingsSchema>\n\n/**\n * Schema for export settings.\n * Controls the output dimensions and quality of exported videos/GIFs.\n */\nexport const ExportSettingsSchema = z.object({\n // Output width in characters (min 80, max 400)\n width: z.number().min(80).max(400).default(120),\n // Output height in characters (min 24, max 100)\n height: z.number().min(24).max(100).default(40),\n // Frames per second for video (min 10, max 60)\n fps: z.number().min(10).max(60).default(30),\n})\n\nexport type ExportSettings = z.infer<typeof ExportSettingsSchema>\n\n/**\n * Schema for validating deck configuration (deck.config.ts).\n * Defines the complete configuration for a presentation deck.\n */\nexport const DeckConfigSchema = z.object({\n // Presentation metadata\n title: z.string().optional(),\n author: z.string().optional(),\n date: z.string().optional(),\n\n // Theme (already validated Theme object)\n theme: ThemeSchema,\n\n // Presentation settings\n settings: SettingsSchema.optional(),\n\n // Export settings\n export: ExportSettingsSchema.optional(),\n})\n\nexport type DeckConfig = z.infer<typeof DeckConfigSchema>\n","import { z, ZodError } from 'zod'\n\n/**\n * Custom error class for validation failures.\n * Extends Error with a specific name for easy identification.\n */\nexport class ValidationError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'ValidationError'\n }\n}\n\n/**\n * Format Zod errors into user-friendly messages.\n * Formats each issue with its field path and message.\n *\n * @param error - The ZodError to format\n * @param context - A description of what was being validated (e.g., \"theme\", \"slide frontmatter\")\n * @returns A formatted string with all validation issues\n *\n * @example\n * const error = new ZodError([...])\n * formatZodError(error, 'theme')\n * // Returns:\n * // \"Invalid theme:\n * // - colors.primary: Color must be a valid hex color (e.g., #ff0066)\n * // - name: Theme name is required\"\n */\nexport function formatZodError(error: ZodError, context: string): string {\n const issues = error.issues.map((issue) => {\n const path = issue.path.join('.')\n return ` - ${path ? `${path}: ` : ''}${issue.message}`\n })\n\n return `Invalid ${context}:\\n${issues.join('\\n')}`\n}\n\n/**\n * Parse data with a Zod schema and throw a ValidationError with friendly messages on failure.\n *\n * @param schema - The Zod schema to validate against\n * @param data - The data to validate\n * @param context - A description of what's being validated (e.g., \"theme\", \"slide frontmatter\")\n * @returns The parsed and validated data\n * @throws {ValidationError} If validation fails\n *\n * @example\n * const theme = safeParse(ThemeSchema, rawData, 'theme')\n * // Throws ValidationError with formatted message if invalid\n */\nexport function safeParse<T>(\n schema: z.ZodSchema<T>,\n data: unknown,\n context: string\n): T {\n const result = schema.safeParse(data)\n\n if (!result.success) {\n throw new ValidationError(formatZodError(result.error, context))\n }\n\n return result.data\n}\n","import { parse as parseYaml } from 'yaml'\nimport deepmerge from 'deepmerge'\nimport gradient from 'gradient-string'\nimport { readFile, access } from 'fs/promises'\nimport type { Theme, PartialTheme } from '../schemas/theme'\nimport { ThemeSchema } from '../schemas/theme'\nimport { safeParse, ValidationError } from '../schemas/validation'\n\n/**\n * Error class for theme-related failures.\n * Includes optional source information (theme name and file path) for better debugging.\n */\nexport class ThemeError extends Error {\n /**\n * @param message - The error message\n * @param themeName - Optional name of the theme that caused the error\n * @param path - Optional path to the theme file or package\n */\n constructor(\n message: string,\n public readonly themeName?: string,\n public readonly path?: string\n ) {\n super(message)\n this.name = 'ThemeError'\n }\n}\n\n/**\n * Format any error into a user-friendly ThemeError.\n * Handles ValidationError, generic Error, and unknown error types.\n *\n * @param error - The error to format\n * @param source - Description of the theme source (e.g., file path or package name)\n * @returns A ThemeError with a user-friendly message\n *\n * @example\n * try {\n * await loadThemeFromFile('./theme.yml')\n * } catch (error) {\n * throw formatThemeError(error, './theme.yml')\n * }\n */\nexport function formatThemeError(error: unknown, source: string): ThemeError {\n if (error instanceof ValidationError) {\n return new ThemeError(\n `Invalid theme from ${source}:\\n${error.message}`,\n undefined,\n source\n )\n }\n\n if (error instanceof Error) {\n return new ThemeError(\n `Failed to load theme from ${source}: ${error.message}`,\n undefined,\n source\n )\n }\n\n return new ThemeError(`Unknown error loading theme from ${source}`)\n}\n\n/**\n * Theme object with extension capability.\n * Extends the base Theme type with an extend() method that allows\n * Tailwind-style theme customization.\n */\nexport interface ThemeObject extends Theme {\n /**\n * Create a new theme by merging overrides into this theme.\n * Uses deep merge with array replacement strategy.\n *\n * @param overrides - Partial theme object with values to override\n * @returns A new ThemeObject with the merged values\n *\n * @example\n * const custom = matrix.extend({\n * colors: { primary: '#ff0066' }\n * })\n *\n * @example\n * // Chained extensions\n * const custom = matrix\n * .extend({ colors: { primary: '#ff0066' } })\n * .extend({ animations: { revealSpeed: 0.5 } })\n */\n extend(overrides: PartialTheme): ThemeObject\n}\n\n/**\n * Theme package structure for npm packages or local theme files.\n * Contains the raw YAML source, parsed theme, and package metadata.\n */\nexport interface ThemePackage {\n /** Raw YAML content of the theme file */\n yaml: string\n\n /** Parsed and validated theme object */\n theme: ThemeObject\n\n /** Package metadata */\n meta: {\n /** Package or theme name */\n name: string\n /** Package version */\n version: string\n /** Path to the theme file or package */\n path: string\n }\n}\n\n/**\n * Create a ThemeObject from a validated Theme.\n * Internal helper that adds the extend() method to a Theme.\n *\n * @param validated - A validated Theme object\n * @returns A ThemeObject with extension capability\n */\nfunction createThemeFromMerge(base: Theme, overrides: PartialTheme): ThemeObject {\n // Deep merge, with overrides taking precedence\n const merged = deepmerge(base, overrides, {\n // Arrays should be replaced, not concatenated\n arrayMerge: (_, source) => source,\n }) as Theme\n\n // Re-validate the merged result\n const validated = safeParse(ThemeSchema, merged, 'merged theme')\n\n return {\n ...validated,\n extend(newOverrides: PartialTheme): ThemeObject {\n return createThemeFromMerge(validated, newOverrides)\n },\n }\n}\n\n/**\n * Create a theme from a YAML string.\n * Parses the YAML, validates it against ThemeSchema, and returns a ThemeObject\n * with extension capability.\n *\n * @param yaml - The YAML string containing the theme definition\n * @returns A validated ThemeObject with extend() method\n * @throws {Error} If the YAML syntax is invalid\n * @throws {ValidationError} If the parsed data doesn't match ThemeSchema\n *\n * @example\n * const theme = createTheme(`\n * name: custom\n * colors:\n * primary: \"#ff0066\"\n * accent: \"#00ff66\"\n * background: \"#000000\"\n * text: \"#ffffff\"\n * muted: \"#666666\"\n * gradients:\n * main:\n * - \"#ff0066\"\n * - \"#00ff66\"\n * glyphs: \"0123456789ABCDEF\"\n * animations:\n * revealSpeed: 1.0\n * matrixDensity: 30\n * glitchIterations: 3\n * lineDelay: 20\n * matrixInterval: 100\n * `)\n */\nexport function createTheme(yaml: string): ThemeObject {\n const parsed = parseYaml(yaml)\n const validated = safeParse(ThemeSchema, parsed, 'theme')\n\n return {\n ...validated,\n extend(overrides: PartialTheme): ThemeObject {\n return createThemeFromMerge(validated, overrides)\n },\n }\n}\n\n/**\n * Load a theme from a YAML file on the filesystem.\n * Reads the file contents and passes them to createTheme for parsing and validation.\n *\n * @param path - The filesystem path to the YAML theme file\n * @returns A validated ThemeObject with extend() method\n * @throws {Error} If the file cannot be read (e.g., file not found, permission denied)\n * @throws {Error} If the YAML syntax is invalid\n * @throws {ValidationError} If the parsed data doesn't match ThemeSchema\n *\n * @example\n * const theme = await loadThemeFromFile('./themes/matrix.yml')\n * const customTheme = theme.extend({ colors: { primary: '#ff0066' } })\n */\nexport async function loadThemeFromFile(path: string): Promise<ThemeObject> {\n try {\n await access(path)\n } catch {\n throw new Error(`Theme file not found: ${path}`)\n }\n\n const content = await readFile(path, 'utf-8')\n return createTheme(content)\n}\n\n/**\n * Load a theme from an npm package.\n * Packages must export a default ThemeObject.\n *\n * @param name - The npm package name (e.g., '@term-deck/theme-retro')\n * @returns A validated ThemeObject with extend() method\n * @throws {Error} If the package doesn't export a default theme\n * @throws {Error} If the package is not installed (with helpful install message)\n * @throws {ValidationError} If the exported theme doesn't match ThemeSchema\n *\n * @example\n * const theme = await loadThemeFromPackage('@term-deck/theme-retro')\n * const customTheme = theme.extend({ colors: { primary: '#ff0066' } })\n */\nexport async function loadThemeFromPackage(name: string): Promise<ThemeObject> {\n try {\n // Dynamic import of npm package\n const pkg = await import(name)\n\n if (!pkg.default) {\n throw new Error(`Theme package \"${name}\" must export a default theme`)\n }\n\n // Validate the exported theme\n const validated = safeParse(ThemeSchema, pkg.default, `theme from ${name}`)\n\n return {\n ...validated,\n extend(overrides: PartialTheme): ThemeObject {\n return createThemeFromMerge(validated, overrides)\n },\n }\n } catch (error) {\n // Handle module not found with helpful message\n // Bun's module resolution errors are not instanceof Error but have message/code properties\n const err = error as { message?: string; code?: string }\n const isModuleNotFound =\n err.message?.includes('Cannot find package') ||\n err.message?.includes('Cannot find module') ||\n err.code === 'MODULE_NOT_FOUND' ||\n err.code === 'ERR_MODULE_NOT_FOUND'\n\n if (isModuleNotFound) {\n throw new Error(\n `Theme package \"${name}\" not found. Install it with: bun add ${name}`\n )\n }\n throw error\n }\n}\n\n/**\n * Function type for applying a gradient to text.\n * Returns ANSI-colored text with the gradient applied.\n */\nexport interface GradientFunction {\n (text: string): string\n}\n\n/**\n * Create gradient functions from theme gradients.\n * Returns an object mapping gradient names to gradient functions that can be\n * applied to text to produce ANSI-colored output.\n *\n * @param theme - The theme containing gradient definitions\n * @returns Record mapping gradient names to gradient functions\n *\n * @example\n * const gradients = createGradients(theme)\n * const styledText = gradients.fire('Hello World')\n */\nexport function createGradients(theme: Theme): Record<string, GradientFunction> {\n const gradients: Record<string, GradientFunction> = {}\n\n for (const [name, colors] of Object.entries(theme.gradients)) {\n gradients[name] = gradient(colors)\n }\n\n return gradients\n}\n\n/**\n * Apply a gradient to text by name.\n * Looks up the gradient in the theme and applies it to the text.\n * Falls back gracefully if the gradient doesn't exist.\n *\n * @param text - The text to apply the gradient to\n * @param gradientName - The name of the gradient to use\n * @param theme - The theme containing gradient definitions\n * @returns The text with gradient applied, or unstyled text if gradient not found\n *\n * @example\n * const styledText = applyGradient('Hello World', 'fire', theme)\n */\nexport function applyGradient(\n text: string,\n gradientName: string,\n theme: Theme\n): string {\n const colors = theme.gradients[gradientName]\n\n if (!colors) {\n // Fall back gracefully - return unstyled text\n return text\n }\n\n return gradient(colors)(text)\n}\n\n/**\n * Built-in color mappings for color tokens in slide content.\n * These are fixed colors that don't change with the theme.\n */\nexport const BUILTIN_COLORS: Record<string, string> = {\n GREEN: '#00cc66',\n ORANGE: '#ff6600',\n CYAN: '#00ccff',\n PINK: '#ff0066',\n WHITE: '#ffffff',\n GRAY: '#666666',\n}\n\n/**\n * Resolve a color token to its hex value.\n * Theme colors (PRIMARY, ACCENT, etc.) are resolved from the theme.\n * Built-in colors (GREEN, ORANGE, etc.) use fixed values.\n *\n * @param token - The color token to resolve (e.g., 'PRIMARY', 'GREEN')\n * @param theme - The theme to resolve theme-specific tokens from\n * @returns The hex color value\n *\n * @example\n * const color = resolveColorToken('PRIMARY', theme) // '#00cc66'\n * const color = resolveColorToken('GREEN', theme) // '#00cc66'\n */\nexport function resolveColorToken(token: string, theme: Theme): string {\n // Check theme colors first\n switch (token) {\n case 'PRIMARY':\n return theme.colors.primary\n case 'SECONDARY':\n return theme.colors.secondary ?? theme.colors.primary\n case 'ACCENT':\n return theme.colors.accent\n case 'MUTED':\n return theme.colors.muted\n case 'TEXT':\n return theme.colors.text\n case 'BACKGROUND':\n return theme.colors.background\n }\n\n // Fall back to built-in colors\n return BUILTIN_COLORS[token] ?? theme.colors.text\n}\n\n/**\n * Convert color tokens in content to blessed tags.\n * Transforms tokens like {GREEN} to blessed color tags like {#00cc66-fg}.\n * Preserves closing tags {/} as-is.\n *\n * @param content - The content with color tokens\n * @param theme - The theme to resolve theme-specific tokens from\n * @returns Content with color tokens converted to blessed tags\n *\n * @example\n * const content = '{GREEN}Hello{/} {ORANGE}World{/}'\n * const result = colorTokensToBlessedTags(content, theme)\n * // '{#00cc66-fg}Hello{/} {#ff6600-fg}World{/}'\n */\nexport function colorTokensToBlessedTags(content: string, theme: Theme): string {\n return content.replace(\n /\\{(GREEN|ORANGE|CYAN|PINK|WHITE|GRAY|PRIMARY|SECONDARY|ACCENT|MUTED|TEXT|BACKGROUND|\\/)\\}/g,\n (_, token) => {\n if (token === '/') {\n return '{/}' // Close tag\n }\n const color = resolveColorToken(token, theme)\n return `{${color}-fg}`\n }\n )\n}\n","/**\n * Public API for term-deck\n *\n * Exports functions and types for use in deck.config.ts files\n * and external integrations.\n */\n\nimport { DeckConfigSchema, type DeckConfig } from './schemas/config.js';\nimport { type Theme } from './schemas/theme.js';\nimport { type Slide, type SlideFrontmatter } from './schemas/slide.js';\nimport { createTheme, type ThemeObject } from './core/theme.js';\n\n/**\n * Define deck configuration with validation\n *\n * Usage in deck.config.ts:\n * ```typescript\n * import { defineConfig } from 'term-deck'\n * import matrix from '@term-deck/theme-matrix'\n *\n * export default defineConfig({\n * title: 'My Presentation',\n * theme: matrix,\n * })\n * ```\n */\nexport function defineConfig(config: DeckConfig): DeckConfig {\n return DeckConfigSchema.parse(config);\n}\n\n// Re-export theme creation\nexport { createTheme };\nexport type { ThemeObject };\n\n// Re-export types for consumers\nexport type { DeckConfig, Theme, Slide, SlideFrontmatter };\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/schemas/theme.ts","../src/schemas/config.ts","../src/schemas/validation.ts","../src/core/theme.ts","../src/index.ts"],"names":["z","parseYaml"],"mappings":"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","file":"index.js","sourcesContent":["import { z } from 'zod'\n\n/**\n * Schema for validating hex color strings.\n * Accepts 6-digit hex colors with # prefix (e.g., #ff0066)\n */\nexport const HexColorSchema = z.string().regex(/^#[0-9a-fA-F]{6}$/, {\n message: 'Color must be a valid hex color (e.g., #ff0066)',\n})\n\nexport type HexColor = z.infer<typeof HexColorSchema>\n\n/**\n * Schema for validating gradient color arrays.\n * A gradient requires at least 2 hex colors.\n */\nexport const GradientSchema = z.array(HexColorSchema).min(2, {\n message: 'Gradient must have at least 2 colors',\n})\n\nexport type Gradient = z.infer<typeof GradientSchema>\n\n/**\n * Schema for validating theme objects.\n * Defines the visual appearance of the presentation deck.\n */\nexport const ThemeSchema = z.object({\n // Theme metadata\n name: z.string().min(1, { message: 'Theme name is required' }),\n description: z.string().optional(),\n author: z.string().optional(),\n version: z.string().optional(),\n\n // Color palette\n colors: z.object({\n primary: HexColorSchema,\n secondary: HexColorSchema.optional(),\n accent: HexColorSchema,\n background: HexColorSchema,\n text: HexColorSchema,\n muted: HexColorSchema,\n success: HexColorSchema.optional(),\n warning: HexColorSchema.optional(),\n error: HexColorSchema.optional(),\n }),\n\n // Named gradients for bigText\n gradients: z.record(z.string(), GradientSchema).refine(\n (g) => Object.keys(g).length >= 1,\n { message: 'At least one gradient must be defined' }\n ),\n\n // Glyph set for matrix rain background\n glyphs: z.string().min(10, {\n message: 'Glyph set must have at least 10 characters',\n }),\n\n // Animation settings\n animations: z.object({\n // Speed multiplier (1.0 = normal, 0.5 = half speed, 2.0 = double speed)\n revealSpeed: z.number().min(0.1).max(5.0).default(1.0),\n // Matrix rain density (number of drops)\n matrixDensity: z.number().min(10).max(200).default(50),\n // Glitch effect iterations\n glitchIterations: z.number().min(1).max(20).default(5),\n // Delay between lines during reveal (ms)\n lineDelay: z.number().min(0).max(500).default(30),\n // Matrix rain update interval (ms)\n matrixInterval: z.number().min(20).max(200).default(80),\n }),\n\n // Window appearance\n window: z.object({\n // Border style\n borderStyle: z.enum(['line', 'double', 'rounded', 'none']).default('line'),\n // Shadow effect\n shadow: z.boolean().default(true),\n // Padding inside windows\n padding: z.object({\n top: z.number().min(0).max(5).default(1),\n bottom: z.number().min(0).max(5).default(1),\n left: z.number().min(0).max(10).default(2),\n right: z.number().min(0).max(10).default(2),\n }).optional(),\n }).optional(),\n})\n\nexport type Theme = z.infer<typeof ThemeSchema>\n\n// ============================================================================\n// Color Token System\n// ============================================================================\n\n/**\n * Valid color tokens for inline styling in slide body content.\n * Tokens can be either:\n * - Built-in colors: GREEN, ORANGE, CYAN, PINK, WHITE, GRAY\n * - Theme-mapped colors: PRIMARY, SECONDARY, ACCENT, MUTED, TEXT, BACKGROUND\n *\n * Usage in slides: {GREEN}colored text{/}\n */\nexport const ColorTokens = [\n 'GREEN',\n 'ORANGE',\n 'CYAN',\n 'PINK',\n 'WHITE',\n 'GRAY',\n 'PRIMARY', // Maps to theme.colors.primary\n 'SECONDARY', // Maps to theme.colors.secondary\n 'ACCENT', // Maps to theme.colors.accent\n 'MUTED', // Maps to theme.colors.muted\n 'TEXT', // Maps to theme.colors.text\n 'BACKGROUND', // Maps to theme.colors.background\n] as const\n\n/**\n * Type for valid color token names.\n */\nexport type ColorToken = typeof ColorTokens[number]\n\n/**\n * Pattern for matching color tokens in slide content.\n * Matches: {GREEN}, {ORANGE}, {CYAN}, {PINK}, {WHITE}, {GRAY},\n * {PRIMARY}, {SECONDARY}, {ACCENT}, {MUTED}, {TEXT}, {BACKGROUND}, {/}\n *\n * The {/} token closes any open color tag.\n */\nexport const COLOR_TOKEN_PATTERN = /\\{(GREEN|ORANGE|CYAN|PINK|WHITE|GRAY|PRIMARY|SECONDARY|ACCENT|MUTED|TEXT|BACKGROUND|\\/)\\}/g\n\n// ============================================================================\n// Partial Theme for Extension\n// ============================================================================\n\n/**\n * Deep partial utility type that makes all nested properties optional.\n * Used for theme extension where only specific fields need to be overridden.\n */\nexport type DeepPartial<T> = T extends object ? {\n [P in keyof T]?: DeepPartial<T[P]>\n} : T\n\n/**\n * Partial theme type for use with theme.extend() functionality.\n * All fields (including nested) become optional.\n */\nexport type PartialTheme = DeepPartial<Theme>\n\n/**\n * Schema for validating partial theme objects.\n * All fields become optional recursively, allowing partial overrides.\n * Used for theme extension validation.\n */\nexport const PartialThemeSchema = ThemeSchema.deepPartial()\n\n// ============================================================================\n// Default Theme\n// ============================================================================\n\n/**\n * Default matrix/cyberpunk theme.\n * Used when no theme is specified or as a base for theme extension.\n */\nexport const DEFAULT_THEME: Theme = {\n name: 'matrix',\n description: 'Default cyberpunk/matrix theme',\n\n colors: {\n primary: '#00cc66',\n accent: '#ff6600',\n background: '#0a0a0a',\n text: '#ffffff',\n muted: '#666666',\n },\n\n gradients: {\n fire: ['#ff6600', '#ff3300', '#ff0066'],\n cool: ['#00ccff', '#0066ff', '#6600ff'],\n pink: ['#ff0066', '#ff0099', '#cc00ff'],\n hf: ['#99cc00', '#00cc66', '#00cccc'],\n },\n\n glyphs: 'アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン0123456789',\n\n animations: {\n revealSpeed: 1.0,\n matrixDensity: 50,\n glitchIterations: 5,\n lineDelay: 30,\n matrixInterval: 80,\n },\n\n window: {\n borderStyle: 'line',\n shadow: true,\n padding: {\n top: 1,\n bottom: 1,\n left: 2,\n right: 2,\n },\n },\n}\n","import { z } from 'zod'\nimport { ThemeSchema } from './theme'\n\n/**\n * Schema for presentation settings.\n * Controls how the presentation behaves during runtime.\n */\nexport const SettingsSchema = z.object({\n // Start slide (0-indexed)\n startSlide: z.number().min(0).default(0),\n // Loop back to first slide after last\n loop: z.boolean().default(false),\n // Auto-advance slides (ms, 0 = disabled)\n autoAdvance: z.number().min(0).default(0),\n // Show slide numbers\n showSlideNumbers: z.boolean().default(false),\n // Show progress bar\n showProgress: z.boolean().default(false),\n})\n\nexport type Settings = z.infer<typeof SettingsSchema>\n\n/**\n * Schema for export settings.\n * Controls the output dimensions and quality of exported videos/GIFs.\n */\nexport const ExportSettingsSchema = z.object({\n // Output width in characters (min 80, max 400)\n width: z.number().min(80).max(400).default(120),\n // Output height in characters (min 24, max 100)\n height: z.number().min(24).max(100).default(40),\n // Frames per second for video (min 10, max 60)\n fps: z.number().min(10).max(60).default(30),\n})\n\nexport type ExportSettings = z.infer<typeof ExportSettingsSchema>\n\n/**\n * Schema for validating deck configuration (deck.config.ts).\n * Defines the complete configuration for a presentation deck.\n */\nexport const DeckConfigSchema = z.object({\n // Presentation metadata\n title: z.string().optional(),\n author: z.string().optional(),\n date: z.string().optional(),\n\n // Theme (already validated Theme object)\n theme: ThemeSchema,\n\n // Presentation settings\n settings: SettingsSchema.optional(),\n\n // Export settings\n export: ExportSettingsSchema.optional(),\n})\n\nexport type DeckConfig = z.infer<typeof DeckConfigSchema>\n","import { z, ZodError } from 'zod'\n\n/**\n * Custom error class for validation failures.\n * Extends Error with a specific name for easy identification.\n */\nexport class ValidationError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'ValidationError'\n }\n}\n\n/**\n * Format Zod errors into user-friendly messages.\n * Formats each issue with its field path and message.\n *\n * @param error - The ZodError to format\n * @param context - A description of what was being validated (e.g., \"theme\", \"slide frontmatter\")\n * @returns A formatted string with all validation issues\n *\n * @example\n * const error = new ZodError([...])\n * formatZodError(error, 'theme')\n * // Returns:\n * // \"Invalid theme:\n * // - colors.primary: Color must be a valid hex color (e.g., #ff0066)\n * // - name: Theme name is required\"\n */\nexport function formatZodError(error: ZodError, context: string): string {\n const issues = error.issues.map((issue) => {\n const path = issue.path.join('.')\n return ` - ${path ? `${path}: ` : ''}${issue.message}`\n })\n\n return `Invalid ${context}:\\n${issues.join('\\n')}`\n}\n\n/**\n * Parse data with a Zod schema and throw a ValidationError with friendly messages on failure.\n *\n * @param schema - The Zod schema to validate against\n * @param data - The data to validate\n * @param context - A description of what's being validated (e.g., \"theme\", \"slide frontmatter\")\n * @returns The parsed and validated data\n * @throws {ValidationError} If validation fails\n *\n * @example\n * const theme = safeParse(ThemeSchema, rawData, 'theme')\n * // Throws ValidationError with formatted message if invalid\n */\nexport function safeParse<T>(\n schema: z.ZodSchema<T>,\n data: unknown,\n context: string\n): T {\n const result = schema.safeParse(data)\n\n if (!result.success) {\n throw new ValidationError(formatZodError(result.error, context))\n }\n\n return result.data\n}\n","import { parse as parseYaml } from 'yaml'\nimport deepmerge from 'deepmerge'\nimport type { Theme, PartialTheme } from '../schemas/theme'\nimport { ThemeSchema } from '../schemas/theme'\nimport { safeParse } from '../schemas/validation'\n\n/**\n * Theme object with extension capability.\n * Extends the base Theme type with an extend() method that allows\n * Tailwind-style theme customization.\n */\nexport interface ThemeObject extends Theme {\n /**\n * Create a new theme by merging overrides into this theme.\n * Uses deep merge with array replacement strategy.\n *\n * @param overrides - Partial theme object with values to override\n * @returns A new ThemeObject with the merged values\n *\n * @example\n * const custom = matrix.extend({\n * colors: { primary: '#ff0066' }\n * })\n *\n * @example\n * // Chained extensions\n * const custom = matrix\n * .extend({ colors: { primary: '#ff0066' } })\n * .extend({ animations: { revealSpeed: 0.5 } })\n */\n extend(overrides: PartialTheme): ThemeObject\n}\n\n/**\n * Create a ThemeObject from validated Theme and overrides.\n * Internal helper that merges themes and adds the extend() method.\n *\n * @param base - A validated Theme object\n * @param overrides - Partial theme with values to override\n * @returns A ThemeObject with extension capability\n */\nexport function createThemeFromMerge(base: Theme, overrides: PartialTheme): ThemeObject {\n // Deep merge, with overrides taking precedence\n const merged = deepmerge(base, overrides, {\n // Arrays should be replaced, not concatenated\n arrayMerge: (_, source) => source,\n }) as Theme\n\n // Re-validate the merged result\n const validated = safeParse(ThemeSchema, merged, 'merged theme')\n\n return {\n ...validated,\n extend(newOverrides: PartialTheme): ThemeObject {\n return createThemeFromMerge(validated, newOverrides)\n },\n }\n}\n\n/**\n * Create a theme from a YAML string.\n * Parses the YAML, validates it against ThemeSchema, and returns a ThemeObject\n * with extension capability.\n *\n * @param yaml - The YAML string containing the theme definition\n * @returns A validated ThemeObject with extend() method\n * @throws {Error} If the YAML syntax is invalid\n * @throws {ValidationError} If the parsed data doesn't match ThemeSchema\n *\n * @example\n * const theme = createTheme(`\n * name: custom\n * colors:\n * primary: \"#ff0066\"\n * accent: \"#00ff66\"\n * background: \"#000000\"\n * text: \"#ffffff\"\n * muted: \"#666666\"\n * gradients:\n * main:\n * - \"#ff0066\"\n * - \"#00ff66\"\n * glyphs: \"0123456789ABCDEF\"\n * animations:\n * revealSpeed: 1.0\n * matrixDensity: 30\n * glitchIterations: 3\n * lineDelay: 20\n * matrixInterval: 100\n * `)\n */\nexport function createTheme(yaml: string): ThemeObject {\n const parsed = parseYaml(yaml)\n const validated = safeParse(ThemeSchema, parsed, 'theme')\n\n return {\n ...validated,\n extend(overrides: PartialTheme): ThemeObject {\n return createThemeFromMerge(validated, overrides)\n },\n }\n}\n\n// Re-export commonly used functions for convenience\nexport { ThemeError, formatThemeError } from './theme-errors'\nexport {\n createGradients,\n applyGradient,\n resolveColorToken,\n colorTokensToBlessedTags,\n BUILTIN_COLORS,\n} from './theme-colors'\nexport type { GradientFunction } from './theme-colors'\n","/**\n * Public API for term-deck\n *\n * Exports functions and types for use in deck.config.ts files\n * and external integrations.\n */\n\nimport { DeckConfigSchema, type DeckConfig } from './schemas/config.js';\nimport { type Theme } from './schemas/theme.js';\nimport { type Slide, type SlideFrontmatter } from './schemas/slide.js';\nimport { createTheme, type ThemeObject } from './core/theme.js';\n\n/**\n * Define deck configuration with validation\n *\n * Usage in deck.config.ts:\n * ```typescript\n * import { defineConfig } from 'term-deck'\n * import matrix from '@term-deck/theme-matrix'\n *\n * export default defineConfig({\n * title: 'My Presentation',\n * theme: matrix,\n * })\n * ```\n */\nexport function defineConfig(config: DeckConfig): DeckConfig {\n return DeckConfigSchema.parse(config);\n}\n\n// Re-export theme creation\nexport { createTheme };\nexport type { ThemeObject };\n\n// Re-export types for consumers\nexport type { DeckConfig, Theme, Slide, SlideFrontmatter };\n"]}
|