@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/index.d.ts CHANGED
@@ -212,8 +212,9 @@ declare const DeckConfigSchema: z.ZodObject<{
212
212
  height?: number;
213
213
  fps?: number;
214
214
  };
215
- title?: string;
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
- title?: string;
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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pep/term-deck",
3
- "version": "1.0.15",
3
+ "version": "1.0.16",
4
4
  "description": "Terminal presentation tool with a cyberpunk aesthetic",
5
5
  "type": "module",
6
6
  "bin": {