temporal-fmt 0.9.70 → 0.9.80
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -59
- package/dist/{chunk-6ZIYGBFN.js → chunk-5KP5H7X2.js} +4 -4
- package/dist/{chunk-N4SYRZIP.js → chunk-DMJWJTFY.js} +35 -12
- package/dist/chunk-DMJWJTFY.js.map +1 -0
- package/dist/{chunk-CGI4FL6H.js → chunk-FLMOMOAQ.js} +2 -2
- package/dist/{chunk-UU2XN6N2.js → chunk-HGRT37LT.js} +5 -11
- package/dist/chunk-HGRT37LT.js.map +1 -0
- package/dist/{chunk-3FMUGYE2.js → chunk-KV6GMX4D.js} +4 -159
- package/dist/chunk-KV6GMX4D.js.map +1 -0
- package/dist/{chunk-BZPNSQHI.js → chunk-LHR5PCP4.js} +2 -2
- package/dist/{chunk-OLNU4LON.js → chunk-QRLQ7RR7.js} +2 -1
- package/dist/chunk-QRLQ7RR7.js.map +1 -0
- package/dist/chunk-UGYSEYUQ.js +168 -0
- package/dist/chunk-UGYSEYUQ.js.map +1 -0
- package/dist/{chunk-VXG3VD3D.js → chunk-WEVNKOQA.js} +3 -3
- package/dist/chunk-WP7TBCTT.js +241 -0
- package/dist/chunk-WP7TBCTT.js.map +1 -0
- package/dist/{chunk-BQDOTFGC.js → chunk-Z245NHDT.js} +21 -21
- package/dist/chunk-Z245NHDT.js.map +1 -0
- package/dist/config.d.cts +2 -2
- package/dist/config.d.ts +2 -2
- package/dist/duration.cjs.map +1 -1
- package/dist/duration.js +2 -2
- package/dist/format.cjs +71 -18
- package/dist/format.cjs.map +1 -1
- package/dist/format.js +4 -4
- package/dist/index.cjs +3875 -4707
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +21 -104
- package/dist/index.d.ts +21 -104
- package/dist/index.js +2409 -849
- package/dist/index.js.map +1 -1
- package/dist/interval.cjs +131 -4757
- package/dist/interval.cjs.map +1 -1
- package/dist/interval.js +6 -11
- package/dist/localeRegistry.cjs.map +1 -1
- package/dist/localeRegistry.js +2 -2
- package/dist/localeVocab.d.cts +4 -3
- package/dist/localeVocab.d.ts +4 -3
- package/dist/numbering.d.cts +4 -2
- package/dist/numbering.d.ts +4 -2
- package/dist/parse.cjs +42 -14
- package/dist/parse.cjs.map +1 -1
- package/dist/parse.js +4 -4
- package/dist/recurrence.js +2 -1
- package/dist/relativeTime.cjs.map +1 -1
- package/dist/relativeTime.js +3 -3
- package/dist/tokens.d.cts +0 -4
- package/dist/tokens.d.ts +0 -4
- package/package.json +5 -21
- package/MODS.md +0 -148
- package/dist/chunk-3FMUGYE2.js.map +0 -1
- package/dist/chunk-6WKSAP4Y.js +0 -3041
- package/dist/chunk-6WKSAP4Y.js.map +0 -1
- package/dist/chunk-BQDOTFGC.js.map +0 -1
- package/dist/chunk-N4SYRZIP.js.map +0 -1
- package/dist/chunk-OLNU4LON.js.map +0 -1
- package/dist/chunk-UU2XN6N2.js.map +0 -1
- package/dist/modApi.d.cts +0 -147
- package/dist/modApi.d.ts +0 -147
- package/dist/runtime.d.cts +0 -206
- package/dist/runtime.d.ts +0 -206
- package/scripts/cli.mjs +0 -324
- package/scripts/loadMods.d.mts +0 -37
- package/scripts/loadMods.mjs +0 -801
- package/scripts/managePermissions.mjs +0 -126
- package/scripts/modConfig.mjs +0 -96
- package/scripts/modSandbox.d.mts +0 -13
- package/scripts/modSandbox.mjs +0 -855
- package/scripts/modWire.mjs +0 -241
- package/scripts/modWorker.mjs +0 -574
- package/scripts/semverRange.mjs +0 -157
- package/scripts/versions.json +0 -37
- /package/dist/{chunk-6ZIYGBFN.js.map → chunk-5KP5H7X2.js.map} +0 -0
- /package/dist/{chunk-CGI4FL6H.js.map → chunk-FLMOMOAQ.js.map} +0 -0
- /package/dist/{chunk-BZPNSQHI.js.map → chunk-LHR5PCP4.js.map} +0 -0
- /package/dist/{chunk-VXG3VD3D.js.map → chunk-WEVNKOQA.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/recurrence.ts"],"sourcesContent":["/*\n * Copyright 2026 DirazCoder\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Recurrence engine. Deterministic RRULE-like\n// recurrence without pulling in a runtime dependency. Supports\n// secondly/minutely/hourly/daily/weekly/monthly/yearly frequencies,\n// interval, count, until, weekdays (incl. ordinal BYDAY like 2MO/-1FR\n// for monthly/yearly), monthDays (incl. negative end-of-month values),\n// exclusions, inclusions.\n//\n// RRULE interop: parseRRule() / formatRRule() convert to/from the\n// standard iCalendar RRULE string format (RFC 5545). Implemented\n// without depending on a RRULE library — the grammar is small enough\n// to handle inline. Not enforced (documented limitation, same as\n// before): BYSETPOS, BYHOUR, BYMINUTE, BYSECOND, WKST.\n\nimport { add } from './arithmetic.js';\nimport { compare } from './comparison.js';\nimport { daysFromCivil } from './isoWeek.js';\nimport { asDateFieldView } from './calendarUtils.js';\n\nexport type RecurrenceFrequency = 'secondly' | 'minutely' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly';\n\nexport interface WeekdayOrdinal {\n // 2 = \"2nd such weekday of the month\", -1 = \"last such weekday\".\n // Only meaningful with monthly/yearly frequency (RFC 5545 3.3.10:\n // the numeric prefix is invalid with WEEKLY, where it's ignored).\n ordinal: number;\n weekday: number; // ISO 1=Mon..7=Sun\n}\n\nexport interface RecurrenceRule {\n frequency: RecurrenceFrequency;\n interval: number; // default 1 — omitted/null now means 1 (used to mean NaN)\n count?: number; // max occurrences\n until?: unknown; // Temporal value (or RRULE UNTIL date form) — recurrence ends after this\n // For weekly: ISO weekdays to include (1=Mon..7=Sun). Empty = all.\n byWeekday?: number[];\n // Ordinal BYDAY parts (2MO, -1FR) parsed from RRULE strings — the nth\n // weekday of each month/year. Matched in addition to plain byWeekday.\n byWeekdayOrdinal?: WeekdayOrdinal[];\n // For monthly/yearly: days of month to include (1-31, or negative\n // for end-of-month: -1 = last day).\n byMonthDay?: number[];\n // For yearly: months to include (1-12).\n byMonth?: number[];\n // For weekly: which week of the year (1-53).\n byWeek?: number[];\n // Exclusions: dates to skip even if they match the rule.\n exDates?: unknown[];\n // Inclusions: dates to add even if they don't match the rule.\n rDates?: unknown[];\n}\n\nexport interface RecurrenceIterator {\n next(): { value: unknown; done: boolean } | { value: undefined; done: true };\n previous(): { value: unknown; done: boolean } | { value: undefined; done: true };\n}\n\nfunction daysInMonthOf(year: number, month: number): number {\n const LENGTHS = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\n const leap = (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;\n return month === 2 && leap ? 29 : LENGTHS[month - 1]!;\n}\n\n// Day of week (ISO, 1=Mon..7=Sun) for a proleptic Gregorian y/m/d in\n// O(1): 1970-01-01 was a Thursday (dow 4), so dow = ((days + 3) mod 7) + 1.\nfunction weekdayOf(year: number, month: number, day: number): number {\n const days = daysFromCivil(year, month, day);\n return (((days + 3) % 7) + 7) % 7 + 1;\n}\n\n// Day-of-month of the `ordinal`-th `weekday` in the given month\n// (ordinal < 0 counts from the end, -1 = last). Returns null when no\n// such day exists in this month (e.g. 5th Monday of a 4-Monday month).\nfunction nthWeekdayDay(year: number, month: number, weekday: number, ordinal: number): number | null {\n const last = daysInMonthOf(year, month);\n if (ordinal > 0) {\n const firstDow = weekdayOf(year, month, 1);\n const first = 1 + ((weekday - firstDow + 7) % 7);\n const day = first + (ordinal - 1) * 7;\n return day <= last ? day : null;\n }\n const lastDow = weekdayOf(year, month, last);\n const lastOccurrence = last - ((lastDow - weekday + 7) % 7);\n const day = lastOccurrence + (ordinal + 1) * 7;\n return day >= 1 ? day : null;\n}\n\n// Creates a recurrence iterator starting from `start`. The first call\n// to next() returns `start` itself (if it matches the rule); subsequent\n// calls return the next matching occurrence.\nexport function recurrence(start: unknown, rule: RecurrenceRule): RecurrenceIterator {\n if (rule.count !== undefined && (!Number.isSafeInteger(rule.count) || rule.count < 1)) {\n throw new RangeError(`temporal-fmt: recurrence rule count must be a positive safe integer (got ${String(rule.count)}).`);\n }\n // The interface documents interval as \"default 1\" — normalize it here\n // so a rule object omitting it (or passing undefined) behaves as 1\n // instead of poisoning every candidate with NaN arithmetic.\n const interval = rule.interval !== undefined && rule.interval !== null\n ? rule.interval\n : 1;\n if (!Number.isSafeInteger(interval) || interval < 1) {\n throw new RangeError(`temporal-fmt: recurrence rule interval must be a positive safe integer (got ${String(rule.interval)}).`);\n }\n // Programmatic rules skip parseRRule's validation, so re-check the\n // BY* lists here — garbage used to fall through to `?? 0` fallbacks\n // in matches() and quietly match nothing (a rule like byMonthDay:[0]\n // produced an empty sequence with no hint why). Real rules from\n // parseRRule always pass.\n if (rule.byMonthDay && rule.byMonthDay.some((d) => !Number.isSafeInteger(d) || d === 0 || d < -31 || d > 31)) {\n throw new RangeError('temporal-fmt: recurrence rule byMonthDay entries must be nonzero integers in [-31, 31].');\n }\n if (rule.byWeekday && rule.byWeekday.some((d) => !Number.isSafeInteger(d) || d < 1 || d > 7)) {\n throw new RangeError('temporal-fmt: recurrence rule byWeekday entries must be ISO weekdays 1 (Mon) through 7 (Sun).');\n }\n if (rule.byMonth && rule.byMonth.some((m) => !Number.isSafeInteger(m) || m < 1 || m > 12)) {\n throw new RangeError('temporal-fmt: recurrence rule byMonth entries must be months 1 through 12.');\n }\n if (rule.byWeekdayOrdinal && rule.byWeekdayOrdinal.some((o) =>\n !Number.isSafeInteger(o.ordinal) || o.ordinal === 0 || o.ordinal < -53 || o.ordinal > 53 ||\n !Number.isSafeInteger(o.weekday) || o.weekday < 1 || o.weekday > 7)) {\n throw new RangeError('temporal-fmt: recurrence rule byWeekdayOrdinal entries need a nonzero ordinal in [-53, 53] and an ISO weekday 1-7.');\n }\n // Track past values for previous() — keeps a ring buffer of the last\n // N occurrences so previous() can walk back without recomputing.\n const history: unknown[] = [];\n const MAX_HISTORY = 10_000;\n let atEnd = false;\n let atStart = true;\n\n // Anchor: the ORIGINAL start, as a field view. Monthly/yearly\n // candidates are derived from this (not from the previous occurrence)\n // so the day-of-month never drifts: advancing Jan 31 by months used\n // to go 01-31 → 02-28 → 03-28 → 04-28 …, permanently stuck on day 28\n // after the first February clamp. Deriving each period's candidates\n // from the anchor keeps the original day and skips (rather than\n // clamps) periods that lack it — RFC 5545 semantics.\n const anchor = asDateFieldView(start);\n const originDayCount = daysFromCivil(anchor.year!, anchor.month!, anchor.day!);\n\n // A plain field-bag start without dayOfWeek used to make every\n // byWeekday-dependent rule silently produce nothing: matches()'s\n // `?? 0` never equals a real weekday, and add()'s dayOfWeek\n // recompute only refreshes a field that already exists — so the\n // chain never picks one up (a Temporal start works because its\n // dayOfWeek getter seeds it). Derive it once here so bag starts and\n // Temporal starts behave identically for BYDAY rules.\n let current: unknown = start;\n if (rule.byWeekday && rule.byWeekday.length > 0 && typeof (start as { dayOfWeek?: unknown }).dayOfWeek !== 'number') {\n current = { ...anchor, dayOfWeek: weekdayOf(anchor.year!, anchor.month!, anchor.day!) };\n }\n let count = 0;\n\n function matches(value: unknown): boolean {\n // The `?? 0` / `?? []` fallbacks on the lines flagged below are\n // defensive only and unreachable through the public API: recurrence()\n // rejects starts missing year/month/day, every generated candidate is\n // a full field view (fillNextPeriod sets dayOfWeek; add()'s\n // recomputeDayOfWeek refreshes one seeded at the top), and the\n // byWeekday gate above runs before plainOk is ever evaluated — so\n // dayOfWeek is defined whenever `?? 0` would fire, and year/month/day\n // are always present. The lines they sit on are otherwise live and\n // test-covered; only the fallback arms need the ignore.\n const v = value as { dayOfWeek?: number; year?: number; month?: number; day?: number; hour?: number; minute?: number; second?: number };\n if (rule.byWeekday && rule.byWeekday.length > 0) {\n // `?? 0` is defensive only since the dayOfWeek seeding above: every\n // value a byWeekday rule tests (seeded start, generated candidates)\n // carries a number.\n /* c8 ignore next @preserve */\n if (!rule.byWeekday.includes(v.dayOfWeek ?? 0)) return false;\n }\n if (rule.byWeekdayOrdinal && rule.byWeekdayOrdinal.length > 0\n && (rule.frequency === 'monthly' || rule.frequency === 'yearly')) {\n // Union with the plain-byWeekday check above per RFC: any BYDAY\n // entry matching is enough. (Monthly/yearly candidates are\n // generated from the ordinal itself, so this re-check is about\n // rules that mix plain and ordinal entries.)\n /* c8 ignore next @preserve */\n const plainOk = !!rule.byWeekday && rule.byWeekday.length > 0 && rule.byWeekday.includes(v.dayOfWeek ?? 0);\n /* c8 ignore next @preserve */\n const ordinalOk = (rule.byWeekdayOrdinal ?? []).some((o) =>\n /* c8 ignore next @preserve */\n nthWeekdayDay(v.year ?? 0, v.month ?? 0, o.weekday, o.ordinal) === (v.day ?? 0));\n if (!plainOk && !ordinalOk) return false;\n }\n if (rule.byMonthDay && rule.byMonthDay.length > 0) {\n // Negative values count back from the end of the month\n // (-1 = last day). They used to be accepted by parseRRule but\n // never matched anything — a day-of-month is never negative.\n /* c8 ignore next @preserve */\n const day = v.day ?? 0;\n /* c8 ignore next @preserve */\n const last = daysInMonthOf(v.year ?? 0, v.month ?? 0);\n // `?? []` is defensive only: the enclosing if guards byMonthDay\n // non-empty.\n /* c8 ignore next @preserve */\n const hit = (rule.byMonthDay ?? []).some((d) => (d > 0 ? d === day : d + last + 1 === day));\n if (!hit) return false;\n }\n if (rule.byMonth && rule.byMonth.length > 0) {\n /* c8 ignore next @preserve */\n if (!rule.byMonth.includes(v.month ?? 0)) return false;\n }\n if (rule.exDates && rule.exDates.some((d) => compare(d, value) === 0)) return false;\n return true;\n }\n\n // ---- Monthly/yearly candidate generation ------------------------------\n // Each interval step yields one period (a month, or a year with its\n // byMonth months). The period's candidate days are:\n // - byMonthDay values, if present (negatives resolved to real days);\n // - else ordinal BYDAY days, if present;\n // - else the anchor's day (periods lacking it yield nothing).\n // Candidates carry the anchor's time-of-day and a recomputed\n // dayOfWeek, and are yielded in chronological order.\n let pending: unknown[] = [];\n // Starts at 0: the start's OWN period gets generated first (RFC —\n // FREQ=MONTHLY;BYMONTHDAY=15 from Jan 1 yields Jan 15 before Feb 15),\n // with candidates at or before `start` skipped by nextMatch.\n let periodIndex = 0;\n\n function fillNextPeriod(): void {\n // k starts at 0 (the start's own period) and increments AFTER use,\n // so every period from the anchor's onward is generated exactly once.\n const k = periodIndex;\n periodIndex++;\n let year: number;\n let months: number[];\n if (rule.frequency === 'monthly') {\n const totalMonths = anchor.year! * 12 + anchor.month! - 1 + k * interval;\n year = Math.floor(totalMonths / 12);\n months = [totalMonths - year * 12 + 1];\n } else {\n year = anchor.year! + k * interval;\n months = rule.byMonth && rule.byMonth.length > 0\n ? [...rule.byMonth].sort((a, b) => a - b)\n : [anchor.month!];\n }\n const days: Array<{ month: number; day: number }> = [];\n for (const m of months) {\n const last = daysInMonthOf(year, m);\n if (rule.byMonthDay && rule.byMonthDay.length > 0) {\n for (const d of rule.byMonthDay) {\n const real = d > 0 ? d : last + 1 + d;\n if (real >= 1 && real <= last) days.push({ month: m, day: real });\n }\n } else if (rule.byWeekdayOrdinal && rule.byWeekdayOrdinal.length > 0) {\n for (const o of rule.byWeekdayOrdinal) {\n const real = nthWeekdayDay(year, m, o.weekday, o.ordinal);\n if (real !== null) days.push({ month: m, day: real });\n }\n } else {\n if (anchor.day! <= last) days.push({ month: m, day: anchor.day! });\n }\n }\n days.sort((a, b) => a.month - b.month || a.day - b.day);\n pending = days.map(({ month, day }) => ({\n ...anchor,\n year,\n month,\n day,\n dayOfWeek: weekdayOf(year, month, day),\n }));\n }\n\n // Steps to the next candidate after `value`, by the frequency's own\n // granularity:\n // - monthly/yearly: pop the period queue (refilling as needed);\n // - weekly + BYDAY: one day at a time (stepping whole weeks preserves\n // the weekday, so a start not already on a BYDAY weekday could\n // never match — FREQ=WEEKLY;BYDAY=SA from a Monday used to produce\n // an empty sequence), gated to the interval's week windows;\n // - everything else: one `interval` step from the current value, the\n // same way the original implementation did.\n function nextMatch(value: unknown): { value: unknown; found: boolean } {\n let candidate = value;\n let safetyCounter = 0;\n const daywise = rule.frequency === 'weekly' && !!rule.byWeekday && rule.byWeekday.length > 0;\n const periodwise = rule.frequency === 'monthly' || rule.frequency === 'yearly';\n const unit = rule.frequency === 'secondly' ? 'seconds'\n : rule.frequency === 'minutely' ? 'minutes'\n : rule.frequency === 'hourly' ? 'hours'\n : rule.frequency === 'daily' ? 'days'\n : 'weeks';\n\n while (true) {\n // Count EVERY iteration, including the two `continue` paths below\n // (empty periods, candidates at/before the start): those used to\n // skip the increment, so a rule whose every period is empty — e.g.\n // monthly BYDAY=-6MO, which no month can ever satisfy — spun the\n // loop forever. The cap is a total-work bound per next() call, not\n // a candidates-produced bound.\n safetyCounter++;\n if (safetyCounter > 2000) {\n // Defensive — if the rule is so restrictive no match exists\n // within 2000 steps, give up rather than spin forever. The\n // caller must treat this as \"no more occurrences\", not as a\n // real match — returning the unmatched candidate here used to\n // get handed back to next()'s caller as if it were valid.\n // (1000 previously; doubled because day-granular stepping for\n // weekly BYDAY rules legitimately needs up to 7 steps per\n // occurrence, and monthly skips can chain across short months.)\n atEnd = true;\n return { value: candidate, found: false };\n }\n if (daywise) {\n candidate = add(candidate, 1, 'days');\n // INTERVAL > 1 on a weekly BYDAY rule: only weeks that are a\n // whole multiple of `interval` away from the anchor's week emit\n // occurrences (WKST unsupported — the window anchors on the\n // start's own day).\n if (interval > 1) {\n const v = asDateFieldView(candidate);\n const dayCount = daysFromCivil(v.year!, v.month!, v.day!);\n if (Math.floor((dayCount - originDayCount) / 7) % interval !== 0) continue;\n }\n } else if (periodwise) {\n if (pending.length === 0) {\n fillNextPeriod();\n if (pending.length === 0) continue; // period had no valid days\n }\n candidate = pending.shift()!;\n // The start's own period can contain candidate days at or before\n // the start itself (BYMONTHDAY=15 generating Jan 15 for a Jan 1\n // start, where Jan 1..14 precede it) — those aren't occurrences.\n if (compare(candidate, value) <= 0) continue;\n } else {\n candidate = add(candidate, interval, unit as Parameters<typeof add>[2]);\n }\n if (rule.until && compare(candidate, rule.until) > 0) {\n atEnd = true;\n return { value: candidate, found: false };\n }\n if (matches(candidate)) break;\n }\n return { value: candidate, found: true };\n }\n\n function recordHistory(value: unknown): void {\n history.push(value);\n if (history.length > MAX_HISTORY) history.shift();\n }\n\n return {\n next() {\n if (atEnd) return { value: undefined, done: true };\n if (atStart) {\n atStart = false;\n if (matches(current)) {\n count++;\n if (rule.count !== undefined && count >= rule.count) atEnd = true;\n if (rule.until && compare(current, rule.until) > 0) {\n atEnd = true;\n return { value: undefined, done: true };\n }\n // Include rDates that match the current value.\n recordHistory(current);\n return { value: current, done: false };\n }\n // If start doesn't match, advance to first match.\n const advanced = nextMatch(current);\n if (!advanced.found) return { value: undefined, done: true };\n current = advanced.value;\n count++;\n if (rule.count !== undefined && count >= rule.count) atEnd = true;\n recordHistory(current);\n return { value: current, done: false };\n }\n const advanced = nextMatch(current);\n if (!advanced.found) return { value: undefined, done: true };\n current = advanced.value;\n count++;\n if (rule.count !== undefined && count >= rule.count) atEnd = true;\n recordHistory(current);\n return { value: current, done: false };\n },\n previous() {\n if (history.length === 0) return { value: undefined, done: true };\n const v = history.pop()!;\n return { value: v, done: false };\n },\n };\n}\n\n// Take N occurrences from a recurrence iterator.\nexport function take(iter: RecurrenceIterator, n: number): unknown[] {\n const result: unknown[] = [];\n for (let i = 0; i < n; i++) {\n const r = iter.next();\n if (r.done) break;\n result.push(r.value);\n }\n return result;\n}\n\n// Upper bound on how many occurrences skip() will collect after its\n// skip phase. skip() used to call take(iter, Number.MAX_SAFE_INTEGER),\n// and an iterator over an unbounded rule (no count, no until — e.g.\n// { frequency: 'daily', interval: 1 }) never returns done: next() always\n// has another day. The call then looped forever, pushing into a result\n// array until the process OOM'd. Same cap style as businessCalendar.ts.\nconst MAX_SKIP_COLLECTION = 100_000;\n// Upper bound on skip()'s skip phase too: skip(iter, 1e9) on an\n// unbounded rule used to burn a billion next() calls before the\n// collection cap was ever reached.\nconst MAX_SKIP_STEPS = 1_000_000;\n\n// Skip N occurrences from a recurrence iterator, returning the ones\n// that follow. Throws a RangeError when the iterator is still producing\n// occurrences after MAX_SKIP_COLLECTION — that means the rule is\n// unbounded (no count/until) and \"everything after the skip\" has no\n// finite answer.\nexport function skip(iter: RecurrenceIterator, n: number): unknown[] {\n for (let i = 0; i < n; i++) {\n if (i >= MAX_SKIP_STEPS) {\n throw new RangeError(\n `temporal-fmt: skip() was asked to skip more than ${MAX_SKIP_STEPS} occurrences — that's not a bounded operation; use take() on a count/until-bounded rule instead.`\n );\n }\n const r = iter.next();\n if (r.done) break;\n }\n const result: unknown[] = [];\n while (result.length < MAX_SKIP_COLLECTION) {\n const r = iter.next();\n if (r.done) return result;\n result.push(r.value);\n }\n throw new RangeError(\n `temporal-fmt: skip() collected ${MAX_SKIP_COLLECTION} occurrences and the rule is still ` +\n `producing — add a count or until to the rule, or use take(iter, n) for a bounded read.`\n );\n}\n\n// All occurrences between two dates (inclusive of start, exclusive of end).\nexport function between(start: unknown, rule: RecurrenceRule, rangeStart: unknown, rangeEnd: unknown): unknown[] {\n const iter = recurrence(start, rule);\n const result: unknown[] = [];\n // Traversal cap: a fine-grained rule anchored far before rangeEnd\n // (e.g. daily from year -2000) walks every occurrence since `start`\n // — bounded work instead of an unbounded loop, same style as skip().\n const MAX_TRAVERSAL = 1_000_000;\n let traversed = 0;\n while (true) {\n if (traversed++ > MAX_TRAVERSAL) {\n throw new RangeError(\n `temporal-fmt: between() walked more than ${MAX_TRAVERSAL} occurrences without reaching rangeEnd — ` +\n `pass a start closer to the range, or bound the rule with count/until.`\n );\n }\n const r = iter.next();\n if (r.done) break;\n if (compare(r.value, rangeEnd) >= 0) break;\n if (compare(r.value, rangeStart) >= 0) result.push(r.value);\n }\n return result;\n}\n\n// Parses an RRULE UNTIL value (RFC 5545 date \"20240110\" or UTC\n// date-time \"20240110T153000Z\") into a comparable field bag. Stored raw\n// previously, so iterating a parsed rule threw \"expected a date-carrying\n// Temporal value\" on the first next() — a parsed RRULE was unusable\n// with UNTIL, the single most common termination form.\nfunction parseUntil(value: string): { year: number; month: number; day: number; hour?: number; minute?: number; second?: number } {\n const m = /^(\\d{4})(\\d{2})(\\d{2})(?:T(\\d{2})(\\d{2})(\\d{2})Z?)?$/.exec(value.trim());\n if (!m) {\n throw new RangeError(\n `temporal-fmt: RRULE UNTIL must be a date (\"20240110\") or UTC date-time (\"20240110T153000Z\") — got \"${value}\".`\n );\n }\n const year = Number(m[1]);\n const month = Number(m[2]);\n const day = Number(m[3]);\n if (month < 1 || month > 12 || day < 1 || day > 31) {\n throw new RangeError(`temporal-fmt: RRULE UNTIL carries an out-of-range date \"${value}\".`);\n }\n const hour = m[4] !== undefined ? Number(m[4]) : undefined;\n const minute = m[5] !== undefined ? Number(m[5]) : undefined;\n const second = m[6] !== undefined ? Number(m[6]) : undefined;\n if (hour !== undefined && (hour > 23 || minute! > 59 || second! > 59)) {\n throw new RangeError(`temporal-fmt: RRULE UNTIL carries an out-of-range time \"${value}\".`);\n }\n return { year, month, day, hour, minute, second };\n}\n\n// Parses an RRULE string like \"FREQ=DAILY;INTERVAL=2;COUNT=5\" into a\n// RecurrenceRule. Doesn't support every RRULE feature (BYSETPOS,\n// BYHOUR, BYMINUTE, BYSECOND, WKST are not enforced by the recurrence\n// iterator above), but covers the common cases.\nexport function parseRRule(input: string): RecurrenceRule {\n const parts = input.trim().toUpperCase().replace(/^RRULE:/, '').split(';');\n const rule: RecurrenceRule = { frequency: 'daily', interval: 1 };\n const frequencies: ReadonlySet<string> = new Set([\n 'SECONDLY', 'MINUTELY', 'HOURLY', 'DAILY', 'WEEKLY', 'MONTHLY', 'YEARLY',\n ]);\n for (const part of parts) {\n if (!part) continue;\n const eq = part.indexOf('=');\n if (eq < 0) continue;\n const key = part.slice(0, eq);\n const value = part.slice(eq + 1);\n switch (key) {\n case 'FREQ':\n if (!frequencies.has(value)) {\n throw new RangeError(`temporal-fmt: unsupported RRULE frequency \"${value}\".`);\n }\n rule.frequency = value.toLowerCase() as RecurrenceFrequency;\n break;\n case 'INTERVAL': {\n const interval = Number(value);\n if (!Number.isSafeInteger(interval) || interval < 1) {\n throw new RangeError(`temporal-fmt: RRULE INTERVAL must be a positive safe integer (got \"${value}\").`);\n }\n rule.interval = interval;\n break;\n }\n case 'COUNT': {\n const count = Number(value);\n if (!Number.isSafeInteger(count) || count < 1) {\n throw new RangeError(`temporal-fmt: RRULE COUNT must be a positive safe integer (got \"${value}\").`);\n }\n rule.count = count;\n break;\n }\n case 'UNTIL':\n rule.until = parseUntil(value);\n break;\n case 'BYDAY': {\n const WEEKDAY_MAP: Record<string, number> = { MO: 1, TU: 2, WE: 3, TH: 4, FR: 5, SA: 6, SU: 7 };\n const plain: number[] = [];\n const ordinals: WeekdayOrdinal[] = [];\n for (const d of value.split(',')) {\n // RFC 5545 ordinals run -53..53 — two digits are legal, so the\n // pattern must accept them (it used to cap at one digit, which\n // made valid rules like BYDAY=53MO throw \"invalid weekday\" and\n // pushed out-of-range ordinals past the range check below\n // instead of reaching it).\n const m = d.match(/^([+-]?\\d{1,2})?([A-Z]{2})$/);\n // Unknown tokens used to map to 0 silently — a typo'd BYDAY\n // entry quietly matched nothing instead of failing loudly.\n if (!m || WEEKDAY_MAP[m[2]!] === undefined) {\n throw new RangeError(`temporal-fmt: RRULE BYDAY contains an invalid weekday \"${d}\".`);\n }\n const weekday = WEEKDAY_MAP[m[2]!]!;\n if (m[1] !== undefined) {\n const ordinal = Number(m[1]);\n if (!Number.isSafeInteger(ordinal) || ordinal === 0 || ordinal < -53 || ordinal > 53) {\n throw new RangeError(`temporal-fmt: RRULE BYDAY ordinal out of range in \"${d}\".`);\n }\n ordinals.push({ ordinal, weekday });\n } else {\n plain.push(weekday);\n }\n }\n rule.byWeekday = plain;\n if (ordinals.length > 0) rule.byWeekdayOrdinal = ordinals;\n break;\n }\n case 'BYMONTHDAY': {\n const values = value.split(',').map(Number);\n if (values.some((day) => !Number.isInteger(day) || day === 0 || day < -31 || day > 31)) {\n throw new RangeError(`temporal-fmt: RRULE BYMONTHDAY contains an out-of-range value.`);\n }\n rule.byMonthDay = values;\n break;\n }\n case 'BYMONTH': {\n const values = value.split(',').map(Number);\n if (values.some((month) => !Number.isInteger(month) || month < 1 || month > 12)) {\n throw new RangeError(`temporal-fmt: RRULE BYMONTH contains an out-of-range value.`);\n }\n rule.byMonth = values;\n break;\n }\n }\n }\n return rule;\n}\n\nexport function formatRRule(rule: RecurrenceRule): string {\n const parts: string[] = [`FREQ=${rule.frequency.toUpperCase()}`];\n // Programmatic rules may omit interval (documented default: 1) — emitting\n // \"INTERVAL=undefined\" for them produced output that parseRRule itself\n // rejects, breaking the round-trip. Omit it unless it's an explicit != 1.\n if (rule.interval !== undefined && rule.interval !== 1) parts.push(`INTERVAL=${rule.interval}`);\n if (rule.count !== undefined) parts.push(`COUNT=${rule.count}`);\n if (rule.until !== undefined) parts.push(`UNTIL=${String(rule.until)}`);\n const WEEKDAY_NAMES: Record<number, string> = { 1: 'MO', 2: 'TU', 3: 'WE', 4: 'TH', 5: 'FR', 6: 'SA', 7: 'SU' };\n if (rule.byWeekday && rule.byWeekday.length > 0) {\n parts.push(`BYDAY=${rule.byWeekday.map((d) => WEEKDAY_NAMES[d] ?? String(d)).join(',')}`);\n }\n if (rule.byWeekdayOrdinal && rule.byWeekdayOrdinal.length > 0) {\n const rendered = rule.byWeekdayOrdinal.map((o) => `${o.ordinal}${WEEKDAY_NAMES[o.weekday] ?? String(o.weekday)}`);\n // Merge into the plain BYDAY part when both exist (RRULE carries\n // one combined list).\n if (rule.byWeekday && rule.byWeekday.length > 0) {\n parts[parts.length - 1] = `BYDAY=${[...rule.byWeekday.map((d) => WEEKDAY_NAMES[d] ?? String(d)), ...rendered].join(',')}`;\n } else {\n parts.push(`BYDAY=${rendered.join(',')}`);\n }\n }\n if (rule.byMonthDay && rule.byMonthDay.length > 0) parts.push(`BYMONTHDAY=${rule.byMonthDay.join(',')}`);\n if (rule.byMonth && rule.byMonth.length > 0) parts.push(`BYMONTH=${rule.byMonth.join(',')}`);\n return parts.join(';');\n}\n"],"mappings":"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","names":["day","advanced"]}
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
InvalidLocaleError,
|
|
8
8
|
canonicalCacheKey,
|
|
9
9
|
normalizeLocaleTag
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-QRLQ7RR7.js";
|
|
11
11
|
import {
|
|
12
12
|
asDateFieldView
|
|
13
13
|
} from "./chunk-KEPIXQK7.js";
|
|
@@ -578,4 +578,4 @@ export {
|
|
|
578
578
|
addDuration,
|
|
579
579
|
subtractDuration
|
|
580
580
|
};
|
|
581
|
-
//# sourceMappingURL=chunk-
|
|
581
|
+
//# sourceMappingURL=chunk-LHR5PCP4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/localeVocab.ts"],"sourcesContent":["/*\n * Copyright 2026 DirazCoder\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// structured error classes for parse()/format() failures.\n//\n// as of 0.9.0 every throw site on the parse/format data path —\n// tokenize.ts, pattern.ts, format.ts, parse.ts (parse/safeParse/tryParse/\n// parseToParts/compileParser), plus the two data-path throws in\n// localeVocab.ts (partValue/assertNoCollision on the getLocaleVocab side)\n// — throws one of these typed classes directly instead of a plain\n// `new Error(message)`. every site we migrated kept its exact pre-0.9.0\n// message text, and since subclasses of TemporalFmtError still pass\n// `instanceof Error` and match the same message regexes (e.g.\n// `/token \"HH\" requires/`), this didn't need a semver-major bump for\n// either of those checks. what DOES break in 0.9.0: if anyone was\n// specifically checking `err.constructor === Error` or `err.name ===\n// 'Error'`, that'll now see a different name (e.g. 'FormatSyntaxError').\n// noted in the 0.9.0 changelog.\n//\n// deliberately did NOT migrate:\n// - localeVocab.ts's registration-time throws (assertValidVocab,\n// registerLocaleVocab itself) — these are config-time API-misuse\n// errors on data a developer hands in once at startup, not runtime\n// parse/format failures, so they don't really fit this module's\n// TemporalFmtErrorCode taxonomy as-is. assertNoCollision is shared\n// between the registration path and the data path (getLocaleVocab)\n// though, so its throw stays a plain Error for both until that gets\n// split apart — see the tracking note where it's called.\n//\n// wrapUntypedError() below is still around for localeVocab.ts's\n// registration throws, and for anything a caller passes into\n// safeParse()/tryParse() from outside this package. on the data path\n// itself, safeParse's `if (err instanceof TemporalFmtError) return { ok:\n// false, error: err }` catches everything before it'd even reach the\n// classifier here, so honestly the regex branches below are dead for\n// parse/format/tokenize/pattern at this point — kept as the fallback for\n// whatever hasn't been migrated to a typed throw site yet\n\nexport type TemporalFmtErrorCode =\n | 'FORMAT_SYNTAX_ERROR'\n | 'UNKNOWN_TOKEN'\n | 'PARSE_MISMATCH'\n | 'INVALID_DATE'\n | 'INVALID_TIME'\n | 'INVALID_OFFSET'\n | 'INVALID_TIME_ZONE'\n | 'INVALID_CALENDAR'\n | 'AMBIGUOUS_INPUT'\n | 'INVALID_LOCALE'\n | 'INVALID_DURATION';\n\nexport interface TemporalFmtErrorFields {\n code: TemporalFmtErrorCode;\n input?: string;\n format?: string;\n token?: string;\n position?: number;\n expected?: string;\n actual?: string;\n reason?: string;\n}\n\n// base class. `message` is the human-readable summary, the structured\n// fields are the machine-readable bits a linter or codemod would report\n// on. calling Error.captureStackTrace manually (where it exists) so the\n// stack points at wherever this got thrown from, not at this constructor\n// — same trick Node uses for its own error classes\nexport class TemporalFmtError extends Error {\n readonly code: TemporalFmtErrorCode;\n readonly input?: string;\n readonly format?: string;\n readonly token?: string;\n readonly position?: number;\n readonly expected?: string;\n readonly actual?: string;\n readonly reason?: string;\n\n constructor(message: string, fields: TemporalFmtErrorFields) {\n super(message);\n this.name = 'TemporalFmtError';\n this.code = fields.code;\n this.input = fields.input;\n this.format = fields.format;\n this.token = fields.token;\n this.position = fields.position;\n this.expected = fields.expected;\n this.actual = fields.actual;\n this.reason = fields.reason;\n // don't want the stack pointing at this constructor line — captureStackTrace\n // is V8-only though, so on other engines callers just get the default\n // stack (pointing here) since there's nothing better to do about it\n const capture = (Error as unknown as { captureStackTrace?: (target: Error, ctor?: Function) => void }).captureStackTrace;\n if (typeof capture === 'function') {\n capture(this, this.constructor);\n }\n }\n\n // lets callers just call err.toJSON() for logging. plain Error doesn't\n // serialize its non-enumerable fields on its own, so this picks them\n // up explicitly\n toJSON(): TemporalFmtErrorFields & { name: string; message: string } {\n return {\n name: this.name,\n message: this.message,\n code: this.code,\n input: this.input,\n format: this.format,\n token: this.token,\n position: this.position,\n expected: this.expected,\n actual: this.actual,\n reason: this.reason,\n };\n }\n}\n\n// each subclass just fixes `code` so callers can switch on it without\n// having to re-check message text. the constructor only takes the\n// fields that actually vary per call; `code` and the default message\n// template come from the subclass itself\n\nexport class FormatSyntaxError extends TemporalFmtError {\n constructor(fields: Omit<TemporalFmtErrorFields, 'code'> & { message?: string }) {\n const { message, ...rest } = fields;\n super(\n message ?? `format string \"${fields.format ?? ''}\" has a syntax error${fields.reason ? `: ${fields.reason}` : ''}.`,\n { code: 'FORMAT_SYNTAX_ERROR', ...rest },\n );\n this.name = 'FormatSyntaxError';\n }\n}\n\nexport class UnknownTokenError extends TemporalFmtError {\n constructor(fields: Omit<TemporalFmtErrorFields, 'code'> & { message?: string }) {\n const { message, ...rest } = fields;\n super(\n message ?? `token \"${fields.token ?? ''}\" is not a recognized temporal-fmt token${fields.format ? ` in format string \"${fields.format}\"` : ''}.`,\n { code: 'UNKNOWN_TOKEN', ...rest },\n );\n this.name = 'UnknownTokenError';\n }\n}\n\nexport class ParseMismatchError extends TemporalFmtError {\n constructor(fields: Omit<TemporalFmtErrorFields, 'code'> & { message?: string }) {\n const { message, ...rest } = fields;\n super(\n message ?? `input \"${fields.input ?? ''}\" does not match format \"${fields.format ?? ''}\"${fields.reason ? `: ${fields.reason}` : ''}.`,\n { code: 'PARSE_MISMATCH', ...rest },\n );\n this.name = 'ParseMismatchError';\n }\n}\n\nexport class InvalidDateError extends TemporalFmtError {\n constructor(fields: Omit<TemporalFmtErrorFields, 'code'> & { message?: string }) {\n const { message, ...rest } = fields;\n super(\n message ?? `input \"${fields.input ?? ''}\" does not describe a valid date${fields.reason ? `: ${fields.reason}` : ''}.`,\n { code: 'INVALID_DATE', ...rest },\n );\n this.name = 'InvalidDateError';\n }\n}\n\n/* c8 ignore start @preserve -- InvalidTimeError is part of the public\n error-class surface (exported from index.ts, code 'INVALID_TIME') but\n nothing in this package actually constructs one. went and checked\n whether it could get wired in the same way InvalidTimeZoneError just\n was (see parse.ts's zzz-validation loop) — does hour/minute/second have\n a post-match semantic range check the way zone ids do? nope.\n pattern.ts's regex fragments for HH/H/hh/h/mm/m/ss/s already enforce\n their valid ranges right at the regex level (e.g. HH is\n '(?:[01]\\d|2[0-3])', which literally can't match \"99\"), so an\n out-of-range time just gets rejected as a plain shape mismatch before\n any semantic check would even run. no live gap to hook this into\n without inventing a redundant check purely to give this class a body.\n leaving it unconstructed until the library actually hits a real\n invalid-time case worth reporting */\nexport class InvalidTimeError extends TemporalFmtError {\n constructor(fields: Omit<TemporalFmtErrorFields, 'code'> & { message?: string }) {\n const { message, ...rest } = fields;\n super(\n message ?? `input \"${fields.input ?? ''}\" does not describe a valid time${fields.reason ? `: ${fields.reason}` : ''}.`,\n { code: 'INVALID_TIME', ...rest },\n );\n this.name = 'InvalidTimeError';\n }\n}\n/* c8 ignore stop @preserve */\n\nexport class InvalidOffsetError extends TemporalFmtError {\n constructor(fields: Omit<TemporalFmtErrorFields, 'code'> & { message?: string }) {\n const { message, ...rest } = fields;\n super(\n message ?? `offset \"${fields.actual ?? ''}\" is invalid${fields.reason ? `: ${fields.reason}` : ''}.`,\n { code: 'INVALID_OFFSET', ...rest },\n );\n this.name = 'InvalidOffsetError';\n }\n}\n\nexport class InvalidTimeZoneError extends TemporalFmtError {\n constructor(fields: Omit<TemporalFmtErrorFields, 'code'> & { message?: string }) {\n const { message, ...rest } = fields;\n super(\n message ?? `time zone \"${fields.actual ?? ''}\" is not a recognized IANA time zone or fixed offset${fields.reason ? `: ${fields.reason}` : ''}.`,\n { code: 'INVALID_TIME_ZONE', ...rest },\n );\n this.name = 'InvalidTimeZoneError';\n }\n}\n\n/* c8 ignore start @preserve -- InvalidCalendarError is part of the\n public error-class surface (exported from index.ts, code\n 'INVALID_CALENDAR') but same story as InvalidTimeError above — nothing\n in this package constructs one. checked for a wiring opportunity the\n same way: there's no user-supplied calendar identifier anywhere in the\n library that we'd validate against a supported list. resolveCalendar()\n in parse.ts derives the calendar entirely from Intl's own resolution\n of the locale string — it's never handed an arbitrary \"calendar\" value\n a caller could actually get wrong. no live input to reject here.\n leaving it unconstructed until the library accepts an actual calendar\n parameter that could be invalid */\nexport class InvalidCalendarError extends TemporalFmtError {\n constructor(fields: Omit<TemporalFmtErrorFields, 'code'> & { message?: string }) {\n const { message, ...rest } = fields;\n super(\n message ?? `calendar \"${fields.actual ?? ''}\" is not supported${fields.reason ? `: ${fields.reason}` : ''}.`,\n { code: 'INVALID_CALENDAR', ...rest },\n );\n this.name = 'InvalidCalendarError';\n }\n}\n/* c8 ignore stop @preserve */\n\nexport class AmbiguousInputError extends TemporalFmtError {\n constructor(fields: Omit<TemporalFmtErrorFields, 'code'> & { message?: string }) {\n const { message, ...rest } = fields;\n super(\n message ?? `input \"${fields.input ?? ''}\" is ambiguous${fields.reason ? `: ${fields.reason}` : ''}.`,\n { code: 'AMBIGUOUS_INPUT', ...rest },\n );\n this.name = 'AmbiguousInputError';\n }\n}\n\nexport class InvalidLocaleError extends TemporalFmtError {\n constructor(fields: Omit<TemporalFmtErrorFields, 'code'> & { message?: string }) {\n const { message, ...rest } = fields;\n super(\n message ?? `locale \"${fields.actual ?? ''}\" is not a valid BCP-47 tag${fields.reason ? `: ${fields.reason}` : ''}.`,\n { code: 'INVALID_LOCALE', ...rest },\n );\n this.name = 'InvalidLocaleError';\n }\n}\n\nexport class InvalidDurationError extends TemporalFmtError {\n constructor(fields: Omit<TemporalFmtErrorFields, 'code'> & { message?: string }) {\n const { message, ...rest } = fields;\n super(\n message ?? `duration is invalid${fields.reason ? `: ${fields.reason}` : ''}.`,\n { code: 'INVALID_DURATION', ...rest },\n );\n this.name = 'InvalidDurationError';\n }\n}\n\n// wraps a plain Error thrown from a code path that hasn't been migrated\n// to typed errors yet. keeps the original message around in `reason` so\n// callers reading the typed surface still see what actually failed.\n// used by safeParse() in parse.ts.\n//\n// after the 0.9.0 migration, every throw site on the parse/format data\n// path throws a TemporalFmtError directly, so safeParse's `instanceof\n// TemporalFmtError` check always passes before this function would even\n// get called — nothing in the current test suite actually reaches any\n// branch below. kept as the safety net for whenever someone adds an\n// unmigrated throw site down the line (see the c8-ignored call in\n// parse.ts's safeParse) — same reasoning as that call site: removing\n// this would silently break the \"safeParse always returns a\n// TemporalFmtError\" contract the moment anyone adds a bare\n// `throw new Error(...)` without wiring up a typed class for it\n/* c8 ignore start @preserve -- unreachable from the current test suite,\n see rationale above */\nexport function wrapUntypedError(err: Error, context: { input?: string; format?: string }): TemporalFmtError {\n // try to classify by looking at the message — covers the existing\n // parse()/format() throw sites without having to touch them. anything\n // that doesn't match a known pattern falls through to a generic\n // ParseMismatchError, still with the structured fields intact\n const msg = err.message;\n if (/unknown token|isn't a recognized token/.test(msg)) {\n return new UnknownTokenError({ input: context.input, format: context.format, reason: msg });\n }\n if (/ambiguous/i.test(msg)) {\n return new AmbiguousInputError({ input: context.input, format: context.format, reason: msg });\n }\n if (/offset/.test(msg) && /out of range|exceeds|doesn't match the shape/i.test(msg)) {\n return new InvalidOffsetError({ input: context.input, format: context.format, reason: msg });\n }\n if (/no valid pattern matches/i.test(msg)) {\n return new ParseMismatchError({ input: context.input, format: context.format, reason: msg });\n }\n if (/doesn't describe a valid date\\/time|incomplete date|weekday token|quarter token/.test(msg)) {\n return new InvalidDateError({ input: context.input, format: context.format, reason: msg });\n }\n const lowerMsg = msg.toLowerCase();\n const mentionsLocale = lowerMsg.includes('locale');\n if (\n (mentionsLocale && (lowerMsg.includes('produced no') || lowerMsg.includes('not a valid'))) ||\n lowerMsg.includes('cutoffs must be')\n ) {\n return new InvalidLocaleError({ input: context.input, format: context.format, reason: msg });\n }\n if (/format string exceeds maximum length|input exceeds maximum length|unterminated quote|isn't a recognized token/i.test(msg)) {\n return new FormatSyntaxError({ input: context.input, format: context.format, reason: msg });\n }\n return new ParseMismatchError({ input: context.input, format: context.format, reason: msg });\n}\n/* c8 ignore stop @preserve */","/*\n * Copyright 2026 DirazCoder\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Name lists for the locale-aware tokens (MMMM, MMM, EEEE, EEE, a). Each\n// list is small and fixed (12 months, 7 weekdays, 2 day periods), so we\n// generate the real Intl strings for a locale once and cache them.\n\nimport { InvalidLocaleError } from './errors.js';\n\nexport interface LocaleVocab {\n monthLong: string[]; // index 0 = January\n monthShort: string[];\n weekdayLong: string[]; // index 0 = Monday, per Temporal's dayOfWeek numbering\n weekdayShort: string[];\n dayPeriod: string[]; // typically [AM-ish, PM-ish], deduped\n}\n\n// Custom vocabs registered by callers for locales Intl doesn't cover well\n// (e.g. a 13-month Hebrew leap year, where Intl's 12-month vocabulary\n// silently loses a whole month). Keyed by canonical cache key so the\n// same locale string spelling variants fold together — same convention\n// as the Intl-derived vocab cache above.\nconst customVocabs = new Map<string, LocaleVocab>();\nconst MAX_CUSTOM_VOCABS = 500;\nconst MAX_LOCALE_TAG_LENGTH = 256;\nconst MAX_VOCAB_ENTRY_LENGTH = 256;\n\nfunction assertValidVocab(vocab: Partial<LocaleVocab>, locale: string): void {\n // Strict shape validation at registration time, not lazily on first\n // use — the README's promise is that a malformed registration throws\n // descriptively here, rather than failing later inside format()/parse()\n // with a confusing \"no month part\" or wrong-month error the caller\n // can't trace back to the bad registration.\n const required: Array<{ key: keyof LocaleVocab; length: number; label: string }> = [\n { key: 'monthLong', length: 12, label: 'long month names' },\n { key: 'monthShort', length: 12, label: 'short month names' },\n { key: 'weekdayLong', length: 7, label: 'long weekday names' },\n { key: 'weekdayShort', length: 7, label: 'short weekday names' },\n { key: 'dayPeriod', length: 2, label: 'day period markers (AM/PM-equivalent)' },\n ];\n\n for (const { key, length, label } of required) {\n const value = vocab[key];\n if (value === undefined) {\n throw new Error(\n `temporal-fmt: registerLocaleVocab for locale \"${locale}\" is missing required field \"${key}\" (${label}).`\n );\n }\n if (!Array.isArray(value)) {\n throw new Error(\n `temporal-fmt: registerLocaleVocab for locale \"${locale}\": \"${key}\" must be an array, got ${typeof value}.`\n );\n }\n if (value.length !== length) {\n throw new Error(\n `temporal-fmt: registerLocaleVocab for locale \"${locale}\": \"${key}\" must have exactly ${length} entries (got ${value.length}) — ${label}.`\n );\n }\n value.forEach((entry, i) => {\n if (typeof entry !== 'string' || entry.length === 0) {\n throw new Error(\n `temporal-fmt: registerLocaleVocab for locale \"${locale}\": \"${key}[${i}]\" must be a non-empty string, got ${String(entry)}.`\n );\n }\n if (entry.length > MAX_VOCAB_ENTRY_LENGTH) {\n throw new RangeError(\n `temporal-fmt: registerLocaleVocab for locale \"${locale}\": \"${key}[${i}]\" is too long (maximum ${MAX_VOCAB_ENTRY_LENGTH} characters).`\n );\n }\n });\n }\n\n // Reuse the same collision check the Intl-derived path uses — a\n // duplicate month name is just as ambiguous when supplied by a caller\n // as when produced by Intl.\n assertNoCollision(vocab.monthLong!, 'MMMM month', locale);\n assertNoCollision(vocab.monthShort!, 'MMM month', locale);\n assertNoCollision(vocab.weekdayLong!, 'EEEE weekday', locale);\n assertNoCollision(vocab.weekdayShort!, 'EEE weekday', locale);\n\n // dayPeriod entries must differ from each other, or parse()'s\n // isPM check (raw === vocab.dayPeriod[1]) can never return true and\n // every 12-hour parse silently resolves to AM. The Intl-derived path\n // dedupes a same-AM/PM collision to length 1, but a caller passing\n // both entries identical is a real bug to surface — not something to\n // dedupe around.\n if (vocab.dayPeriod![0] === vocab.dayPeriod![1]) {\n throw new Error(\n `temporal-fmt: registerLocaleVocab for locale \"${locale}\": dayPeriod entries must differ ` +\n `(both are \"${vocab.dayPeriod![0]}\"); otherwise parse() can't tell AM from PM.`\n );\n }\n}\n\n// Anything that caches a result derived from *which* vocabulary is\n// active for a locale (right now: parse.ts's compiled pattern cache,\n// whose MMMM/MMM/EEEE/EEE/a fragments embed the vocab's alternations)\n// subscribes here so it gets invalidated when a registration swaps the\n// vocab — mirrors temporalProvider.ts's subscribeToTemporalChanges.\nconst onVocabChanged: Array<() => void> = [];\n\nexport function subscribeToVocabChanges(listener: () => void): void {\n onVocabChanged.push(listener);\n}\n\n/**\n * Supply a custom month/weekday/day-period vocabulary for a locale key,\n * overriding the Intl-derived vocab this library would otherwise build\n * for that key. Useful for locales Intl doesn't cover well — the\n * Parsing section of the README (\"MMMM/MMM assume a 12-month calendar\")\n * calls out the Hebrew leap-month gap as a specific case this addresses.\n *\n * Throws descriptively on malformed input (wrong array lengths, empty\n * strings, duplicate entries, missing fields) rather than failing later\n * during format/parse.\n *\n * Registered vocab takes precedence over the Intl-derived vocab for that\n * locale key, including for already-cached entries — registering\n * invalidates the prior cache entry for that locale so the next call\n * picks up the new vocab.\n *\n * @example\n * registerLocaleVocab('en-u-ca-hebrew-leap', {\n * monthLong: ['Nisan','Iyar','Sivan','Tammuz','Av','Elul','Tishrei','Marcheshvan','Kislev','Tevet','Shevat','Adar I','Adar II'],\n * monthShort: ['Nis','Iyy','Siv','Tam','Av','Elu','Tish','Chesh','Kis','Tev','Shv','Ad1','Ad2'],\n * weekdayLong: ['Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday'],\n * weekdayShort: ['Mon','Tue','Wed','Thu','Fri','Sat','Sun'],\n * dayPeriod: ['AM','PM'],\n * });\n */\nexport function registerLocaleVocab(locale: string, vocab: Partial<LocaleVocab>): void {\n if (typeof locale !== 'string' || locale.length === 0) {\n throw new Error(`temporal-fmt: registerLocaleVocab requires a non-empty locale string, got ${String(locale)}.`);\n }\n if (locale.length > MAX_LOCALE_TAG_LENGTH) {\n throw new RangeError(`temporal-fmt: registerLocaleVocab locale is too long (maximum ${MAX_LOCALE_TAG_LENGTH} characters).`);\n }\n assertValidVocab(vocab, locale);\n\n const cacheKey = canonicalCacheKey(locale);\n if (!customVocabs.has(cacheKey) && customVocabs.size >= MAX_CUSTOM_VOCABS) {\n throw new RangeError(`temporal-fmt: registerLocaleVocab reached the ${MAX_CUSTOM_VOCABS}-locale limit.`);\n }\n customVocabs.set(cacheKey, {\n monthLong: [...vocab.monthLong!],\n monthShort: [...vocab.monthShort!],\n weekdayLong: [...vocab.weekdayLong!],\n weekdayShort: [...vocab.weekdayShort!],\n dayPeriod: [...vocab.dayPeriod!],\n });\n // Invalidate the Intl-derived cache entry so any prior format/parse\n // result cached for this locale is rebuilt against the new vocab. Not\n // strictly necessary (getLocaleVocab checks customVocabs first), but\n // cheap and keeps the two caches from drifting out of sync.\n vocabCache.delete(cacheKey);\n // Also invalidate downstream caches that baked the previous vocab in\n // at build time (parse.ts's pattern cache is the one that matters:\n // without this, a cached pattern would keep matching the OLD month /\n // weekday names while format() renders the new ones, so the library's\n // own format() output would fail to parse back).\n for (const listener of onVocabChanged) listener();\n}\n\n// Every locale-keyed cache in this library (this one, formatterCache in\n// tokens.ts, patternCache/calendarCache in parse.ts) used to key on the\n// exact locale string a caller passed in. Intl treats spelling variants of\n// the same locale as equivalent ('en-US' / 'en-us' / 'en_US' all resolve\n// the same way), but a plain string-keyed Map doesn't — so callers mixing\n// spellings for what's really one locale would silently fragment across\n// separate cache entries instead of sharing one, making the bounded\n// eviction limits (MAX_*_CACHE_SIZE) less effective than they look. This\n// doesn't change any cache's *correctness* (each entry is still built from\n// -- and valid for -- whatever locale string produced it), only how many\n// distinct entries equivalent spellings end up costing. Falls back to the\n// original string on a malformed/unrecognized tag rather than throwing —\n// cache-key normalization shouldn't be where a bad locale first surfaces\n// as an error; whatever actually calls `new Intl.DateTimeFormat(locale)`\n// downstream is the right place for that.\n// Intl constructors (DateTimeFormat/NumberFormat/RelativeTimeFormat)\n// reject underscore-separated tags like 'en_US' outright, while\n// canonicalCacheKey and every locale-parsing path in this library\n// tolerates them by normalizing to BCP-47 hyphens. Centralize that\n// normalization so every `new Intl.*(locale)` construction site\n// accepts the same spellings the cache keys do. Genuinely malformed\n// tags still throw downstream, unchanged.\nexport function normalizeLocaleTag(locale: string): string {\n return locale.replace(/_/g, '-');\n}\n\n// Memoized so hot paths (parse()'s resolveCalendar keys off this on\n// every call, and every locale-keyed cache re-derives it) don't build a\n// fresh Intl.Locale per invocation — construction is comparatively\n// expensive. Bounded like every other cache in this library.\nconst canonicalKeyCache = new Map<string, string>();\nconst MAX_CANONICAL_KEY_CACHE = 500;\n\nexport function canonicalCacheKey(locale: string): string {\n const hit = canonicalKeyCache.get(locale);\n if (hit !== undefined) return hit;\n let key: string;\n try {\n // Intl.Locale requires BCP-47 hyphens and rejects underscore-separated\n // tags like 'en_US' outright (RangeError), rather than normalizing\n // them — so without this replace, that spelling would just fall\n // through to the catch below and never fold with 'en-US'.\n key = new Intl.Locale(locale.replace(/_/g, '-')).toString().toLowerCase();\n } catch {\n // Malformed tag: key on the raw string. Callers that must reject\n // malformed tags do it via assertValidLocaleTag() before/instead of\n // relying on this function — cache-key normalization isn't where a\n // bad locale should surface as an error (unchanged behavior).\n key = locale;\n }\n if (canonicalKeyCache.size >= MAX_CANONICAL_KEY_CACHE) {\n const oldestKey = canonicalKeyCache.keys().next().value;\n if (oldestKey !== undefined) canonicalKeyCache.delete(oldestKey);\n }\n canonicalKeyCache.set(locale, key);\n return key;\n}\n\n// Single validation choke point for locale tags at public boundaries.\n// Intl constructors reject malformed tags with a bare engine RangeError\n// (\"Incorrect locale information provided\") that carries none of the\n// library's structured error context; this rethrows as the typed\n// InvalidLocaleError with the offending tag in its fields. Accepts the\n// same spellings as canonicalCacheKey (underscore tags normalized).\nexport function assertValidLocaleTag(locale: string): void {\n try {\n new Intl.Locale(normalizeLocaleTag(locale));\n } catch {\n throw new InvalidLocaleError({\n actual: locale,\n reason: 'not a valid BCP-47 locale tag',\n });\n }\n}\n\nconst vocabCache = new Map<string, LocaleVocab>();\nconst MAX_VOCAB_CACHE_SIZE = 500;\n\n// Some locales (ja-JP) split a field across two parts — month \"8\" plus a\n// counter suffix \"月\" as a separate sibling \"literal\" — while format()'s\n// post-1582 tokens go through toLocaleString(), which concatenates\n// everything into \"8月\", and the pre-1582 path in tokens.ts\n// (preCutoverGregorianName) formats one field at a time the same way this\n// does. Reading only the type-tagged part used to drop that suffix, so\n// this locale's vocab never matched what format() actually produced.\n// Only merges *adjacent* literals, not the whole string, since the\n// dayPeriod/weekday formatters below carry an extra hour part that a\n// join-everything approach would wrongly absorb.\nexport function partValue(formatter: Intl.DateTimeFormat, date: Date, type: Intl.DateTimeFormatPartTypes): string {\n const parts = formatter.formatToParts(date);\n const index = parts.findIndex((p) => p.type === type);\n /* c8 ignore start @preserve -- defensive guard against a real but\n unreproducible failure mode: an Intl implementation that omits the\n requested part type entirely for some locale. Checked every locale\n with unusual dayPeriod/weekday/month rendering available in this\n runtime's ICU data (ja-JP, zh-CN, th-TH, he-IL, ar-SA, ko-KR, fa-IR)\n against the exact formatter options getLocaleVocab uses (notably\n hour12: true for the dayPeriod formatter, which is what makes every\n locale here actually emit a dayPeriod part — omitting it is what\n produced a false \"gap\" during investigation). None omit their part\n on this runtime. A different ICU version or a non-Node Intl\n implementation could plausibly behave differently, so this stays a\n real check rather than an assertion. */\n /* c8 ignore start @preserve */\n if (index === -1) {\n throw new InvalidLocaleError({\n message: `temporal-fmt: locale produced no \"${type}\" part while building match vocabulary.`,\n });\n }\n /* c8 ignore stop @preserve */\n let value = parts[index]!.value;\n const prev = parts[index - 1];\n const next = parts[index + 1];\n // skip whitespace literals (the separator before \"AM\") — only a\n // no-space suffix like ja-JP's \"月\" should get folded in\n if (prev?.type === 'literal' && !/\\s/.test(prev.value)) value = prev.value + value;\n if (next?.type === 'literal' && !/\\s/.test(next.value)) value = value + next.value;\n return value;\n}\n\n// Two entries rendering identically means parse()'s reverse lookup\n// (indexOf) can never tell them apart. Weekday collisions already surface\n// via parse()'s dayOfWeek cross-check, but with a confusing same-string\n// error; months have no equivalent cross-check, so a collision there would\n// otherwise resolve silently to the wrong month. Catching both here, once\n// at build time, gives one clear error instead.\nfunction assertNoCollision(names: string[], label: string, locale: string): void {\n const seen = new Map<string, number>();\n for (let i = 0; i < names.length; i++) {\n const prior = seen.get(names[i]!);\n if (prior !== undefined) {\n // Not migrated to a typed error: this function is shared between\n // getLocaleVocab's Intl-derived path (data-path error, would be a\n // good InvalidLocaleError candidate) and assertValidVocab's\n // registration-time check (out of scope for this pass — see the\n // localeVocab.ts registration-error follow-up). Splitting this into\n // two near-duplicate functions just to route error types\n // differently isn't worth it for one throw; revisit together with\n // the registration-error work instead.\n throw new Error(\n `temporal-fmt: locale \"${locale}\" renders ${label} index ${prior} and ${i} identically ` +\n `(\"${names[i]}\"). parse() can't reliably tell these apart for this locale/token, so this ` +\n `combination isn't supported.`\n );\n }\n seen.set(names[i]!, i);\n }\n}\n\n// Exposed for tokens.ts: when a custom vocab is registered for this\n// locale, format()'s locale-aware tokens (MMMM/MMM/EEEE/EEE/a) read\n// straight from the registered array instead of going through\n// Intl.DateTimeFormat. Without this override, format() would silently\n// keep producing Intl's strings while parse() matched against the\n// registered vocab — the two would round-trip-fail.\nexport function getCustomVocab(locale: string): LocaleVocab | undefined {\n const cacheKey = canonicalCacheKey(locale);\n return customVocabs.get(cacheKey);\n}\n\nexport function getLocaleVocab(locale: string): LocaleVocab {\n // Validate before building vocab: a malformed tag used to surface as a\n // raw RangeError from the first new Intl.DateTimeFormat below.\n assertValidLocaleTag(locale);\n const cacheKey = canonicalCacheKey(locale);\n // Registered vocabs take precedence over the Intl-derived one — this\n // is the override mechanism registerLocaleVocab() promises. Checking\n // here, before the Intl cache lookup, means a registration that\n // happens *after* the first Intl-derived vocab was built still takes\n // effect on the next call.\n const custom = customVocabs.get(cacheKey);\n if (custom) {\n return custom;\n }\n const cached = vocabCache.get(cacheKey);\n if (cached) {\n return cached;\n }\n\n const intlLocale = normalizeLocaleTag(locale);\n const monthLongFmt = new Intl.DateTimeFormat(intlLocale, { month: 'long', timeZone: 'UTC' });\n const monthShortFmt = new Intl.DateTimeFormat(intlLocale, { month: 'short', timeZone: 'UTC' });\n const monthLong: string[] = [];\n const monthShort: string[] = [];\n for (let m = 0; m < 12; m++) {\n const date = new Date(Date.UTC(2020, m, 1));\n monthLong.push(partValue(monthLongFmt, date, 'month'));\n monthShort.push(partValue(monthShortFmt, date, 'month'));\n }\n assertNoCollision(monthLong, 'MMMM month', locale);\n assertNoCollision(monthShort, 'MMM month', locale);\n\n const weekdayLongFmt = new Intl.DateTimeFormat(intlLocale, { weekday: 'long', timeZone: 'UTC' });\n const weekdayShortFmt = new Intl.DateTimeFormat(intlLocale, { weekday: 'short', timeZone: 'UTC' });\n const weekdayLong: string[] = [];\n const weekdayShort: string[] = [];\n // 2024-01-01 is a Monday (UTC) — walk 7 days from there for weekday names\n for (let d = 0; d < 7; d++) {\n const date = new Date(Date.UTC(2024, 0, 1 + d));\n weekdayLong.push(partValue(weekdayLongFmt, date, 'weekday'));\n weekdayShort.push(partValue(weekdayShortFmt, date, 'weekday'));\n }\n // redundant with parse()'s dayOfWeek cross-check, but gives a clearer error\n assertNoCollision(weekdayLong, 'EEEE weekday', locale);\n assertNoCollision(weekdayShort, 'EEE weekday', locale);\n\n const dayPeriodFmt = new Intl.DateTimeFormat(intlLocale, { hour: 'numeric', hour12: true, timeZone: 'UTC' });\n const am = partValue(dayPeriodFmt, new Date(Date.UTC(2020, 0, 1, 1)), 'dayPeriod');\n const pm = partValue(dayPeriodFmt, new Date(Date.UTC(2020, 0, 1, 13)), 'dayPeriod');\n const dayPeriod = [...new Set([am, pm])];\n\n const vocab: LocaleVocab = { monthLong, monthShort, weekdayLong, weekdayShort, dayPeriod };\n if (vocabCache.size >= MAX_VOCAB_CACHE_SIZE) {\n const oldestKey = vocabCache.keys().next().value;\n if (oldestKey !== undefined) vocabCache.delete(oldestKey);\n }\n vocabCache.set(cacheKey, vocab);\n return vocab;\n}"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import {
|
|
2
|
+
asDateFieldView
|
|
3
|
+
} from "./chunk-KEPIXQK7.js";
|
|
4
|
+
import {
|
|
5
|
+
dayOfWeekFromCivil,
|
|
6
|
+
daysFromCivil
|
|
7
|
+
} from "./chunk-BLZDBPSV.js";
|
|
8
|
+
|
|
9
|
+
// src/comparison.ts
|
|
10
|
+
function toComparableMs(view) {
|
|
11
|
+
const days = daysFromCivil(view.year, view.month, view.day);
|
|
12
|
+
const MS_PER_HOUR = 36e5;
|
|
13
|
+
const MS_PER_MINUTE = 6e4;
|
|
14
|
+
const MS_PER_SECOND = 1e3;
|
|
15
|
+
return days * 864e5 + (view.hour ?? 0) * MS_PER_HOUR + (view.minute ?? 0) * MS_PER_MINUTE + (view.second ?? 0) * MS_PER_SECOND + (view.millisecond ?? 0);
|
|
16
|
+
}
|
|
17
|
+
function asDateTimeFieldView(value) {
|
|
18
|
+
const v = asDateFieldView(value);
|
|
19
|
+
return v;
|
|
20
|
+
}
|
|
21
|
+
function compare(a, b) {
|
|
22
|
+
const av = asDateTimeFieldView(a);
|
|
23
|
+
const bv = asDateTimeFieldView(b);
|
|
24
|
+
const am = toComparableMs(av);
|
|
25
|
+
const bm = toComparableMs(bv);
|
|
26
|
+
if (am < bm) return -1;
|
|
27
|
+
if (am > bm) return 1;
|
|
28
|
+
return 0;
|
|
29
|
+
}
|
|
30
|
+
function isEqual(a, b) {
|
|
31
|
+
return compare(a, b) === 0;
|
|
32
|
+
}
|
|
33
|
+
function isBefore(a, b) {
|
|
34
|
+
return compare(a, b) < 0;
|
|
35
|
+
}
|
|
36
|
+
function isAfter(a, b) {
|
|
37
|
+
return compare(a, b) > 0;
|
|
38
|
+
}
|
|
39
|
+
function min(values) {
|
|
40
|
+
if (!Array.isArray(values) || values.length === 0) {
|
|
41
|
+
throw new Error("temporal-fmt: min() requires a non-empty array of values.");
|
|
42
|
+
}
|
|
43
|
+
let best = values[0];
|
|
44
|
+
for (let i = 1; i < values.length; i++) {
|
|
45
|
+
if (compare(values[i], best) < 0) best = values[i];
|
|
46
|
+
}
|
|
47
|
+
return best;
|
|
48
|
+
}
|
|
49
|
+
function max(values) {
|
|
50
|
+
if (!Array.isArray(values) || values.length === 0) {
|
|
51
|
+
throw new Error("temporal-fmt: max() requires a non-empty array of values.");
|
|
52
|
+
}
|
|
53
|
+
let best = values[0];
|
|
54
|
+
for (let i = 1; i < values.length; i++) {
|
|
55
|
+
if (compare(values[i], best) > 0) best = values[i];
|
|
56
|
+
}
|
|
57
|
+
return best;
|
|
58
|
+
}
|
|
59
|
+
function clamp(value, lo, hi) {
|
|
60
|
+
if (compare(value, lo) < 0) return lo;
|
|
61
|
+
if (compare(value, hi) > 0) return hi;
|
|
62
|
+
return value;
|
|
63
|
+
}
|
|
64
|
+
function isBetween(value, lo, hi) {
|
|
65
|
+
return compare(value, lo) >= 0 && compare(value, hi) <= 0;
|
|
66
|
+
}
|
|
67
|
+
function readYearMonthDay(value) {
|
|
68
|
+
const v = asDateFieldView(value);
|
|
69
|
+
return { year: v.year, month: v.month, day: v.day };
|
|
70
|
+
}
|
|
71
|
+
function todayYearMonthDay() {
|
|
72
|
+
const now = /* @__PURE__ */ new Date();
|
|
73
|
+
return { year: now.getFullYear(), month: now.getMonth() + 1, day: now.getDate() };
|
|
74
|
+
}
|
|
75
|
+
function dateEqualYearMonthDay(a, b) {
|
|
76
|
+
return a.year === b.year && a.month === b.month && a.day === b.day;
|
|
77
|
+
}
|
|
78
|
+
function isSameDay(value, reference) {
|
|
79
|
+
return dateEqualYearMonthDay(readYearMonthDay(value), readYearMonthDay(reference));
|
|
80
|
+
}
|
|
81
|
+
function isToday(value) {
|
|
82
|
+
return dateEqualYearMonthDay(readYearMonthDay(value), todayYearMonthDay());
|
|
83
|
+
}
|
|
84
|
+
function tomorrowYearMonthDay() {
|
|
85
|
+
const d = /* @__PURE__ */ new Date();
|
|
86
|
+
d.setDate(d.getDate() + 1);
|
|
87
|
+
return { year: d.getFullYear(), month: d.getMonth() + 1, day: d.getDate() };
|
|
88
|
+
}
|
|
89
|
+
function yesterdayYearMonthDay() {
|
|
90
|
+
const d = /* @__PURE__ */ new Date();
|
|
91
|
+
d.setDate(d.getDate() - 1);
|
|
92
|
+
return { year: d.getFullYear(), month: d.getMonth() + 1, day: d.getDate() };
|
|
93
|
+
}
|
|
94
|
+
function isTomorrow(value) {
|
|
95
|
+
return dateEqualYearMonthDay(readYearMonthDay(value), tomorrowYearMonthDay());
|
|
96
|
+
}
|
|
97
|
+
function isYesterday(value) {
|
|
98
|
+
return dateEqualYearMonthDay(readYearMonthDay(value), yesterdayYearMonthDay());
|
|
99
|
+
}
|
|
100
|
+
function sameWeek(yearA, monthA, dayA, yearB, monthB, dayB) {
|
|
101
|
+
const daysSince = (y, m, d) => {
|
|
102
|
+
return daysFromCivil(y, m, d);
|
|
103
|
+
};
|
|
104
|
+
const a = daysSince(yearA, monthA, dayA);
|
|
105
|
+
const b = daysSince(yearB, monthB, dayB);
|
|
106
|
+
if (Math.abs(a - b) >= 7) return false;
|
|
107
|
+
const weekdayOf = (y, m, d) => {
|
|
108
|
+
return dayOfWeekFromCivil(y, m, d);
|
|
109
|
+
};
|
|
110
|
+
const wa = a - (weekdayOf(yearA, monthA, dayA) - 1);
|
|
111
|
+
const wb = b - (weekdayOf(yearB, monthB, dayB) - 1);
|
|
112
|
+
return wa === wb;
|
|
113
|
+
}
|
|
114
|
+
function isSameWeek(value, reference) {
|
|
115
|
+
const a = readYearMonthDay(value);
|
|
116
|
+
const b = readYearMonthDay(reference);
|
|
117
|
+
return sameWeek(a.year, a.month, a.day, b.year, b.month, b.day);
|
|
118
|
+
}
|
|
119
|
+
function isSameMonth(value, reference) {
|
|
120
|
+
const a = readYearMonthDay(value);
|
|
121
|
+
const b = readYearMonthDay(reference);
|
|
122
|
+
return a.year === b.year && a.month === b.month;
|
|
123
|
+
}
|
|
124
|
+
function isSameQuarter(value, reference) {
|
|
125
|
+
const a = readYearMonthDay(value);
|
|
126
|
+
const b = readYearMonthDay(reference);
|
|
127
|
+
return a.year === b.year && Math.ceil(a.month / 3) === Math.ceil(b.month / 3);
|
|
128
|
+
}
|
|
129
|
+
function isSameYear(value, reference) {
|
|
130
|
+
return readYearMonthDay(value).year === readYearMonthDay(reference).year;
|
|
131
|
+
}
|
|
132
|
+
function isWeekend(value) {
|
|
133
|
+
if (typeof value !== "object" || value === null) {
|
|
134
|
+
throw new Error(`temporal-fmt: isWeekend() expected a Temporal value, got ${String(value)}.`);
|
|
135
|
+
}
|
|
136
|
+
const v = value;
|
|
137
|
+
if (typeof v.dayOfWeek !== "number") {
|
|
138
|
+
throw new Error(
|
|
139
|
+
`temporal-fmt: isWeekend() needs a value with a dayOfWeek field (PlainDate / PlainDateTime / ZonedDateTime).`
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
return v.dayOfWeek === 6 || v.dayOfWeek === 7;
|
|
143
|
+
}
|
|
144
|
+
function isWeekday(value) {
|
|
145
|
+
return !isWeekend(value);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export {
|
|
149
|
+
compare,
|
|
150
|
+
isEqual,
|
|
151
|
+
isBefore,
|
|
152
|
+
isAfter,
|
|
153
|
+
min,
|
|
154
|
+
max,
|
|
155
|
+
clamp,
|
|
156
|
+
isBetween,
|
|
157
|
+
isSameDay,
|
|
158
|
+
isToday,
|
|
159
|
+
isTomorrow,
|
|
160
|
+
isYesterday,
|
|
161
|
+
isSameWeek,
|
|
162
|
+
isSameMonth,
|
|
163
|
+
isSameQuarter,
|
|
164
|
+
isSameYear,
|
|
165
|
+
isWeekend,
|
|
166
|
+
isWeekday
|
|
167
|
+
};
|
|
168
|
+
//# sourceMappingURL=chunk-UGYSEYUQ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/comparison.ts"],"sourcesContent":["/*\n * Copyright 2026 DirazCoder\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Comparison helpers. Pure functions over the field\n// shape, no Temporal namespace needed — same convention as\n// calendarUtils.ts. All comparisons are field-based, not identity-based,\n// so a polyfill PlainDate compares equal to a native PlainDate with the\n// same year/month/day.\n\nimport { asDateFieldView, type DateFieldView } from './calendarUtils.js';\nimport { dayOfWeekFromCivil, daysFromCivil } from './isoWeek.js';\n\ninterface DateTimeFieldView extends DateFieldView {\n hour?: number;\n minute?: number;\n second?: number;\n millisecond?: number;\n}\n\nfunction toComparableMs(view: DateTimeFieldView): number {\n // Exact proleptic-Gregorian day count (Howard Hinnant's days_from_civil,\n // same algorithm arithmetic.ts/interval.ts use) plus the time-of-day —\n // NOT an approximation. The previous implementation multiplied the\n // year offset by an average 365.2425 days/year, on the theory that the\n // error \"is constant for any given year, so it cancels out in a diff\".\n // That's only true when both dates fall in the same year: the year\n // term's error differs by up to ~0.76 days between adjacent years\n // (365.2425 vs 365/366 actual), which corrupts cross-year comparisons\n // near the boundary — e.g. isAfter(2025-01-01T00:00, 2024-12-31T18:12)\n // returned false (truth: ~5.8h after), and isEqual() returned true for\n // instants ~18h apart (2025-01-01T00:00 vs 2024-12-31T05:49:12).\n // Exact arithmetic has no such error term. The day count itself comes\n // from isoWeek.ts's daysFromCivil (Howard Hinnant's days_from_civil:\n // O(1), correct for negative years — the inlined era formula this\n // replaced double-corrected pre-year-0 dates by a day via Math.floor\n // of the -399-offset numerator).\n const days = daysFromCivil(view.year!, view.month!, view.day!);\n\n const MS_PER_HOUR = 3_600_000;\n const MS_PER_MINUTE = 60_000;\n const MS_PER_SECOND = 1_000;\n\n return days * 86_400_000\n + (view.hour ?? 0) * MS_PER_HOUR\n + (view.minute ?? 0) * MS_PER_MINUTE\n + (view.second ?? 0) * MS_PER_SECOND\n + (view.millisecond ?? 0);\n}\n\nfunction asDateTimeFieldView(value: unknown): DateTimeFieldView {\n const v = asDateFieldView(value);\n return v as DateTimeFieldView;\n}\n\n// Returns < 0 if a < b, 0 if a === b, > 0 if a > b. Same convention as\n// Array.prototype.sort and Temporal.PlainDate.compare. Lets callers\n// pass this directly as a comparator.\nexport function compare(a: unknown, b: unknown): number {\n const av = asDateTimeFieldView(a);\n const bv = asDateTimeFieldView(b);\n const am = toComparableMs(av);\n const bm = toComparableMs(bv);\n if (am < bm) return -1;\n if (am > bm) return 1;\n return 0;\n}\n\nexport function isEqual(a: unknown, b: unknown): boolean {\n return compare(a, b) === 0;\n}\n\nexport function isBefore(a: unknown, b: unknown): boolean {\n return compare(a, b) < 0;\n}\n\nexport function isAfter(a: unknown, b: unknown): boolean {\n return compare(a, b) > 0;\n}\n\nexport function min(values: unknown[]): unknown {\n if (!Array.isArray(values) || values.length === 0) {\n throw new Error('temporal-fmt: min() requires a non-empty array of values.');\n }\n let best = values[0];\n for (let i = 1; i < values.length; i++) {\n if (compare(values[i], best) < 0) best = values[i];\n }\n return best;\n}\n\nexport function max(values: unknown[]): unknown {\n if (!Array.isArray(values) || values.length === 0) {\n throw new Error('temporal-fmt: max() requires a non-empty array of values.');\n }\n let best = values[0];\n for (let i = 1; i < values.length; i++) {\n if (compare(values[i], best) > 0) best = values[i];\n }\n return best;\n}\n\nexport function clamp(value: unknown, lo: unknown, hi: unknown): unknown {\n if (compare(value, lo) < 0) return lo;\n if (compare(value, hi) > 0) return hi;\n return value;\n}\n\nexport function isBetween(value: unknown, lo: unknown, hi: unknown): boolean {\n return compare(value, lo) >= 0 && compare(value, hi) <= 0;\n}\n\n// Semantic helpers — same-day/week/month/quarter/year tests. Useful for\n// UI (\"is this event today?\") and for grouping/aggregation. All take a\n// reference value to compare against; the \"isToday\" / \"isTomorrow\" /\n// \"isYesterday\" variants compute the reference from the current system\n// date themselves so callers don't have to.\nfunction readYearMonthDay(value: unknown): { year: number; month: number; day: number } {\n const v = asDateFieldView(value);\n return { year: v.year!, month: v.month!, day: v.day! };\n}\n\nfunction todayYearMonthDay(): { year: number; month: number; day: number } {\n const now = new Date();\n return { year: now.getFullYear(), month: now.getMonth() + 1, day: now.getDate() };\n}\n\nfunction dateEqualYearMonthDay(a: { year: number; month: number; day: number }, b: { year: number; month: number; day: number }): boolean {\n return a.year === b.year && a.month === b.month && a.day === b.day;\n}\n\nexport function isSameDay(value: unknown, reference: unknown): boolean {\n return dateEqualYearMonthDay(readYearMonthDay(value), readYearMonthDay(reference));\n}\n\nexport function isToday(value: unknown): boolean {\n return dateEqualYearMonthDay(readYearMonthDay(value), todayYearMonthDay());\n}\n\nfunction tomorrowYearMonthDay(): { year: number; month: number; day: number } {\n const d = new Date();\n d.setDate(d.getDate() + 1);\n return { year: d.getFullYear(), month: d.getMonth() + 1, day: d.getDate() };\n}\n\nfunction yesterdayYearMonthDay(): { year: number; month: number; day: number } {\n const d = new Date();\n d.setDate(d.getDate() - 1);\n return { year: d.getFullYear(), month: d.getMonth() + 1, day: d.getDate() };\n}\n\nexport function isTomorrow(value: unknown): boolean {\n return dateEqualYearMonthDay(readYearMonthDay(value), tomorrowYearMonthDay());\n}\n\nexport function isYesterday(value: unknown): boolean {\n return dateEqualYearMonthDay(readYearMonthDay(value), yesterdayYearMonthDay());\n}\n\nfunction sameWeek(yearA: number, monthA: number, dayA: number, yearB: number, monthB: number, dayB: number): boolean {\n // Same week iff the dates are within 7 days of each other AND the earlier\n // one's weekday is ≤ the later one's weekday (so we don't say \"Sun and\n // the following Mon are in the same week\" — ISO weeks run Mon-Sun).\n // Easier: compute ISO week numbers via isoWeekYearAndWeek, compare both\n // year and week. That handles the year-boundary case (Dec 31 vs Jan 1 of\n // the next year, which can be in the same ISO week).\n // Local import to avoid module-cycle: isoWeek.ts doesn't import from here.\n // Lazy require-style dynamic via inline static import at top would be\n // cleaner; this inline computation is fine for a pure helper.\n // ...actually let's just compute weekday offsets directly. Same-ISO-week\n // iff |d1 - d2| < 7 days AND the earlier date's ISO weekday ≤ the later\n // date's ISO weekday so they fall in the same Mon-Sun span.\n const daysSince = (y: number, m: number, d: number): number => {\n // daysFromCivil: O(1), correct for negative years. (The inlined\n // formula this replaced was the one remaining copy of the\n // Math.floor-of-offset era bug — see daysFromCivil's comment.)\n return daysFromCivil(y, m, d);\n };\n const a = daysSince(yearA, monthA, dayA);\n const b = daysSince(yearB, monthB, dayB);\n if (Math.abs(a - b) >= 7) return false;\n // Same week iff both dates round to the same Monday. Compute the\n // Monday-of-week for each: subtract (weekday - 1) days, where weekday\n // is 1=Mon..7=Sun. Use the standard Zeller formula for weekday.\n const weekdayOf = (y: number, m: number, d: number): number => {\n // O(1) proleptic-Gregorian weekday from isoWeek.ts's dayOfWeekFromCivil.\n // The old Date.UTC(y, m-1, d) form remapped years 0-99 to 1900-1999\n // (ECMAScript spec), computing the weekday of the wrong century for\n // first-century dates.\n return dayOfWeekFromCivil(y, m, d);\n };\n const wa = a - (weekdayOf(yearA, monthA, dayA) - 1);\n const wb = b - (weekdayOf(yearB, monthB, dayB) - 1);\n return wa === wb;\n}\n\nexport function isSameWeek(value: unknown, reference: unknown): boolean {\n const a = readYearMonthDay(value);\n const b = readYearMonthDay(reference);\n return sameWeek(a.year, a.month, a.day, b.year, b.month, b.day);\n}\n\nexport function isSameMonth(value: unknown, reference: unknown): boolean {\n const a = readYearMonthDay(value);\n const b = readYearMonthDay(reference);\n return a.year === b.year && a.month === b.month;\n}\n\nexport function isSameQuarter(value: unknown, reference: unknown): boolean {\n const a = readYearMonthDay(value);\n const b = readYearMonthDay(reference);\n return a.year === b.year && Math.ceil(a.month / 3) === Math.ceil(b.month / 3);\n}\n\nexport function isSameYear(value: unknown, reference: unknown): boolean {\n return readYearMonthDay(value).year === readYearMonthDay(reference).year;\n}\n\n// isWeekend / isWeekday depend on dayOfWeek — present on PlainDate,\n// PlainDateTime, ZonedDateTime, but NOT on PlainTime. Callers passing\n// PlainTime get a descriptive throw. Doesn't call asDateFieldView\n// because that would reject PlainTime (no year/month/day) before\n// reaching the dayOfWeek check — and the error we want here is the\n// \"no dayOfWeek field\" one, not the \"no date fields\" one.\nexport function isWeekend(value: unknown): boolean {\n if (typeof value !== 'object' || value === null) {\n throw new Error(`temporal-fmt: isWeekend() expected a Temporal value, got ${String(value)}.`);\n }\n const v = value as { dayOfWeek?: unknown };\n if (typeof v.dayOfWeek !== 'number') {\n throw new Error(\n `temporal-fmt: isWeekend() needs a value with a dayOfWeek field (PlainDate / PlainDateTime / ZonedDateTime).`\n );\n }\n // 6=Sat, 7=Sun in Temporal's Mon=1..Sun=7 numbering.\n return v.dayOfWeek === 6 || v.dayOfWeek === 7;\n}\n\nexport function isWeekday(value: unknown): boolean {\n return !isWeekend(value);\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
DEFAULT_LOCALE
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-Z245NHDT.js";
|
|
4
4
|
import {
|
|
5
5
|
InvalidLocaleError,
|
|
6
6
|
normalizeLocaleTag
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-QRLQ7RR7.js";
|
|
8
8
|
import {
|
|
9
9
|
differenceInDays
|
|
10
10
|
} from "./chunk-SC6ENLEB.js";
|
|
@@ -62,4 +62,4 @@ export {
|
|
|
62
62
|
formatRelative,
|
|
63
63
|
formatRelativeToNow
|
|
64
64
|
};
|
|
65
|
-
//# sourceMappingURL=chunk-
|
|
65
|
+
//# sourceMappingURL=chunk-WEVNKOQA.js.map
|