import { pipe, flow } from 'ts-chas/pipe';
import { chas } from 'ts-chas';
interface RawProduct {
name: string;
price_cents: number;
tags: string | null;
}
interface Product {
name: string;
priceUsd: number;
tags: string[];
}
// Reusable transforms defined with flow
const centsToUsd = flow(
(cents: number) => cents / 100,
(usd) => Math.round(usd * 100) / 100
);
const parseTags = (raw: string | null): string[] =>
raw ? raw.split(',').map(t => t.trim()).filter(Boolean) : [];
// A single-value transformation using pipe
function toProduct(raw: RawProduct): Product {
return pipe(
raw,
(r) => ({ ...r, priceUsd: centsToUsd(r.price_cents) }),
(r) => ({ ...r, tags: parseTags(r.tags) }),
({ name, priceUsd, tags }) => ({ name, priceUsd, tags })
);
}
// Result-aware pipeline using the built-in .pipe() on Result
function parseAndTransform(input: unknown): chas.Result<Product, string> {
return chas
.tryCatch(
() => input as RawProduct,
() => 'Invalid product data'
)
.pipe(
(raw) => ({ ...raw, name: raw.name.trim() }),
toProduct
);
}
// Usage
const result = parseAndTransform({ name: ' Widget ', price_cents: 1999, tags: 'sale, new' });
if (result.isOk()) {
console.log(result.value);
// { name: 'Widget', priceUsd: 19.99, tags: ['sale', 'new'] }
}