63 lines
1.9 KiB
TypeScript
63 lines
1.9 KiB
TypeScript
import type { ProductSearchResult, ProductSpec } from "./types.js";
|
|
|
|
function parseDimensionNumber(text: string): number | undefined {
|
|
const match = text.match(/([0-9]+(?:\.[0-9]+)?)/);
|
|
return match ? Number(match[1]) : undefined;
|
|
}
|
|
|
|
function isOverallWidthSpec(spec: ProductSpec): boolean {
|
|
const name = spec.name.toLowerCase();
|
|
if (/seat|arm|door|package|box|back|cushion/.test(name)) {
|
|
return false;
|
|
}
|
|
return /width|dimensions?/.test(name);
|
|
}
|
|
|
|
function widthFromSpec(spec: ProductSpec): number | undefined {
|
|
if (!isOverallWidthSpec(spec)) {
|
|
return undefined;
|
|
}
|
|
|
|
const name = spec.name.toLowerCase();
|
|
const value = spec.value;
|
|
const labeledWidth = value.match(/([0-9]+(?:\.[0-9]+)?)\s*(?:"|in(?:ches?)?)?\s*W\b/i);
|
|
if (labeledWidth) {
|
|
return Number(labeledWidth[1]);
|
|
}
|
|
|
|
if (/width/.test(name)) {
|
|
return parseDimensionNumber(value);
|
|
}
|
|
|
|
const orderMatch = name.match(/\b([dwh])\s*x\s*([dwh])(?:\s*x\s*([dwh]))?\b/i);
|
|
if (orderMatch) {
|
|
const order = orderMatch.slice(1).filter(Boolean).map((part) => part.toLowerCase());
|
|
const widthIndex = order.indexOf("w");
|
|
const values = value.match(/[0-9]+(?:\.[0-9]+)?/g)?.map(Number) ?? [];
|
|
if (widthIndex >= 0 && values[widthIndex] !== undefined) {
|
|
return values[widthIndex];
|
|
}
|
|
}
|
|
|
|
return undefined;
|
|
}
|
|
|
|
export function extractWidthInches(product: ProductSearchResult): number | undefined {
|
|
for (const spec of product.specs) {
|
|
const width = widthFromSpec(spec);
|
|
if (width !== undefined) {
|
|
return width;
|
|
}
|
|
}
|
|
|
|
const titleMatch = product.title.match(/\b([0-9]+(?:\.[0-9]+)?)\s*(?:["”]|in(?:ch(?:es)?)?)\b/i);
|
|
return titleMatch ? Number(titleMatch[1]) : undefined;
|
|
}
|
|
|
|
export function formatWidthInches(width: number | undefined): string {
|
|
if (width === undefined) {
|
|
return "unknown";
|
|
}
|
|
return `${Number.isInteger(width) ? width.toFixed(0) : width.toFixed(1)}"`;
|
|
}
|