All files / web/src/lib/abacus/print ticket-style.ts

100% Statements 37/37
100% Branches 23/23
100% Functions 3/3
100% Lines 37/37

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 382x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 37x 37x 37x 37x 37x 2x 26x 26x 26x 2x 2x 35x 28x 28x 35x 35x 18x 18x 35x 9x 9x 9x 9x 9x 9x  
import type { TicketProcessValue, TicketStyle } from '@eink/print-dialog'
 
/**
 * Runtime guard for a persisted TicketStyle — the print-settings overlay the
 * user tunes in the print dialog (base preset name + sparse process
 * overrides). `@eink/print-dialog` exports the TYPE but no runtime validator,
 * and the overlay round-trips through a DB text column, so writes are gated
 * here. Returns null on anything that isn't a structurally valid TicketStyle;
 * semantic validity against a capability doc (unknown preset, out-of-range
 * value) is the service's call at submit time, not ours.
 */
 
function isScalar(v: unknown): v is number | boolean | string {
  return (
    (typeof v === 'number' && Number.isFinite(v)) || typeof v === 'boolean' || typeof v === 'string'
  )
}
 
function isProcessValue(v: unknown): v is TicketProcessValue {
  return isScalar(v) || (Array.isArray(v) && v.length > 0 && v.every(isScalar))
}
 
export function parseTicketStyle(input: unknown): TicketStyle | null {
  if (typeof input !== 'object' || input === null || Array.isArray(input)) return null
  const { basePreset, process } = input as { basePreset?: unknown; process?: unknown }
 
  if (typeof basePreset !== 'string' || basePreset.length === 0) return null
  if (typeof process !== 'object' || process === null || Array.isArray(process)) return null
 
  const entries = Object.entries(process as Record<string, unknown>)
  if (!entries.every(([, v]) => isProcessValue(v))) return null
 
  return {
    basePreset,
    process: Object.fromEntries(entries) as Readonly<Record<string, TicketProcessValue>>,
  }
}