Conditional Extraction
Four spec-level combinators handle missing data, fallbacks, value transforms, and validation. All four work across every format and compose freely with each other.
optional
Section titled “optional”Wrap any extraction so failures return a default value (or undefined) instead of failing. Works across all formats and failure kinds.
import { optional } from '@origints/core'
// Returns undefined on failureoptional($.get('nickname').string())
// Returns null on failureoptional($.get('score').number(), null)
// Returns 0 on failureoptional($.get('count').number(), 0)In XLSX
Section titled “In XLSX”optional( row.colWhere(header, cell.equals('Ownership')).number(), null)tryExtract
Section titled “tryExtract”Ordered fallback chain. Tries specs in order, returns the first success. If all fail, returns the last failure.
import { tryExtract, mapSpec, literal } from '@origints/core'
tryExtract( // Try extracting as number directly $.get('price').number(), // Fall back to parsing a string as float mapSpec( $.get('price').string(), v => parseFloat(v as string), 'parseFloat' ), // Last resort: null literal(null))TrySpec type:
interface TrySpec<T extends Spec = Spec> { readonly kind: 'try' readonly specs: readonly T[]}mapSpec
Section titled “mapSpec”Transform a successful extraction result with a function.
import { mapSpec } from '@origints/core'
mapSpec( $.get('date').string(), v => new Date(v as string).getFullYear(), 'getYear')MapSpec type:
interface MapSpec<T extends Spec = Spec> { readonly kind: 'map' readonly source: T readonly fn: (value: unknown) => unknown readonly description: string}Validate extracted values. Fails with 'constraint' kind if the predicate returns false.
import { guard } from '@origints/core'
guard( $.get('age').number(), v => (v as number) > 0, 'Age must be positive')GuardSpec type:
interface GuardSpec<T extends Spec = Spec> { readonly kind: 'guard' readonly source: T readonly predicate: (value: unknown) => boolean readonly description: string readonly reason?: string}Composition
Section titled “Composition”These combinators compose freely. A guard inside a tryExtract becomes a fallback when validation fails:
tryExtract( guard( $.get('age').number(), v => (v as number) >= 0, 'Age must be non-negative' ), literal(0) // fallback when guard fails)All four are supported in:
executeSpec— runtime executionwalkSpec— source map derivationderiveOutputSchemaFromSpec— JSON Schema derivationInferOutput— TypeScript type inference