// An upload-date bound as a tool caller may spell it, normalised to the index's // YYYYMMDD. // // THE INDEX COMPARES YYYYMMDD LEXICOGRAPHICALLY, so a date in any other shape // cannot be used as given. It used to be dropped with a footer warning, and the // search ran with NO bound — a complete-set count over the whole corpus that // read exactly like the bounded count the caller asked for. Now the common // spellings are accepted, and anything else is refused (`null`) so the caller // gets an error and nothing is searched. // // Returns the YYYYMMDD string, `undefined` for an absent or blank value, or // `null` for a value that is not a date. export function normalizeDateArg(raw: unknown): string | undefined | null { if (raw === undefined || raw === null) return undefined; if (typeof raw !== "string") return null; const v = raw.trim(); if (!v) return undefined; const m = /^(\d{4})(\d{2})(\d{2})$/.exec(v) ?? /^(\d{4})[-/.](\d{2})[-/.](\d{2})(?:[T ][\d:.]+(?:Z|[+-]\d{2}:?\d{2})?)?$/.exec(v); if (!m) return null; const [, y, mo, d] = m; const month = Number(mo); const day = Number(d); if (month < 1 || month > 12 || day < 1) return null; const last = new Date(Date.UTC(Number(y), month, 0)).getUTCDate(); if (day > last) return null; return `${y}${mo}${d}`; }