temporal-fmt 0.7.0 → 0.7.2

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 CHANGED
@@ -75,8 +75,8 @@ A few things worth knowing:
75
75
  - **`yy` (2-digit year)** emulates POSIX-style [strptime](https://www.man7.org/linux//man-pages/man3/strptime.3p.html): `00–68`
76
76
  becomes `2000–2068`, `69–99` becomes `1900–1999`.
77
77
  - this is an opinionated tradeoff but ensures `yy` is deterministic without an external date reference
78
- - **`hh`/`h` (12-hour) without an `a` token throws** — If both `HH`/`H` and `a` are present, the 24-hour value
79
- wins and `a` isn't cross-checked against it.
78
+ - **`hh`/`h` (12-hour) without an `a` token throws** — same if a format string mixes `HH`/`H` with `hh`/`h`,
79
+ even when both agree on the same hour. `parse` won't guess which one is authoritative; pick one.
80
80
  - **`MMMM`/`MMM` name matching assumes a 12-month calendar** — the vocabulary
81
81
  it matches against is generated from 12 Gregorian reference dates, so a
82
82
  calendar with a leap month (e.g. Hebrew's 13-month leap years) isn't fully
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";var U=Object.defineProperty;var B=Object.getOwnPropertyDescriptor;var J=Object.getOwnPropertyNames;var Q=Object.prototype.hasOwnProperty;var ee=(e,t)=>{for(var n in t)U(e,n,{get:t[n],enumerable:!0})},te=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of J(t))!Q.call(e,o)&&o!==n&&U(e,o,{get:()=>t[o],enumerable:!(r=B(t,o))||r.enumerable});return e};var ne=e=>te(U({},"__esModule",{value:!0}),e);var we={};ee(we,{format:()=>V,parse:()=>G});module.exports=ne(we);function l(e,t){return String(e).padStart(t,"0")}var C="en-US",M=new Map,re=500;function R(e,t){let n=e+JSON.stringify(t),r=M.get(n);if(r)return r;if(M.size>=re){let o=M.keys().next().value;o!==void 0&&M.delete(o)}return r=new Intl.DateTimeFormat(e,t),M.set(n,r),r}var L;function oe(){if(L===void 0){L=!1;let e=globalThis.Temporal;if(e?.PlainDate)try{new Intl.DateTimeFormat("en-US",{day:"numeric"}).formatToParts(e.PlainDate.from("1970-01-01")),L=!0}catch{}}return L}function O(e,t,n,r){let o=e?.calendarId,a={...n,...o&&o!=="iso8601"?{calendar:o}:{}};if(!oe())return e.toLocaleString(t,a);let{toInstant:i,timeZoneId:s}=e,m=typeof i=="function"&&typeof s=="string",g=m?e.toInstant():e,u={...a,...m?{timeZone:s}:{}},h=R(t,u).formatToParts(g).find(y=>y.type===r);if(!h)throw new Error(`temporal-fmt: locale "${t}" produced no "${r}" part for this token. This usually means the Temporal object is missing the field the token needs.`);return h.value}function ae(e,t){let n=new Date(Date.UTC(1970,0,1,e)),o=R(t,{hour:"numeric",hour12:!0,timeZone:"UTC"}).formatToParts(n).find(a=>a.type==="dayPeriod");if(!o)throw new Error(`temporal-fmt: locale "${t}" produced no "dayPeriod" part for token "a".`);return o.value}var $=[["yyyy",e=>l(e.year,4),"year"],["yy",e=>{if(e.year<0)throw new Error(`temporal-fmt: token "yy" doesn't support negative years (got ${e.year}), since truncating to 2 digits would make it indistinguishable from a positive year. Use "yyyy" instead.`);return l(e.year%100,2)},"year"],["MMMM",(e,t)=>O(e,t,{month:"long"},"month"),"month"],["MMM",(e,t)=>O(e,t,{month:"short"},"month"),"month"],["MM",e=>l(e.month,2),"month"],["M",e=>String(e.month),"month"],["dd",e=>l(e.day,2),"day"],["d",e=>String(e.day),"day"],["EEEE",(e,t)=>O(e,t,{weekday:"long"},"weekday"),"dayOfWeek"],["EEE",(e,t)=>O(e,t,{weekday:"short"},"weekday"),"dayOfWeek"],["HH",e=>l(e.hour,2),"hour"],["H",e=>String(e.hour),"hour"],["hh",e=>l(e.hour%12||12,2),"hour"],["h",e=>String(e.hour%12||12),"hour"],["mm",e=>l(e.minute,2),"minute"],["m",e=>String(e.minute),"minute"],["ss",e=>l(e.second,2),"second"],["s",e=>String(e.second),"second"],["SSS",e=>l(e.millisecond,3),"millisecond"],["a",(e,t)=>ae(e.hour,t),"hour"],["zzz",e=>e.timeZoneId,"timeZoneId"]];var ie=$.map(([e])=>e).sort((e,t)=>t.length-e.length);function S(e){let t=[],n=0;for(;n<e.length;){let r=e[n];if(r==="'"){if(e[n+1]==="'"){N(t,"'"),n+=2;continue}let a=n+1,i="",s=!1;for(;a<e.length;){if(e[a]==="'"){if(e[a+1]==="'"){i+="'",a+=2;continue}s=!0,a+=1;break}i+=e[a],a+=1}if(!s)throw new Error(`temporal-fmt: unterminated quote in format string "${e}"`);N(t,i),n=a;continue}let o=ie.find(a=>e.startsWith(a,n));if(o){t.push({kind:"token",value:o}),n+=o.length;continue}N(t,r),n+=1}return t}function N(e,t){let n=e[e.length-1];n&&n.kind==="literal"?n.value+=t:e.push({kind:"literal",value:t})}var se=new Map($.map(([e,t,n])=>[e,{fn:t,field:n}]));function V(e,t,n={}){if(t.length>1e3)throw new Error(`temporal-fmt: format string exceeds maximum length of ${1e3} characters (got ${t.length}).`);let r=n.locale??C,o=S(t),a="";for(let i of o){if(i.kind==="literal"){a+=i.value;continue}let s=se.get(i.value);if(!s)throw new Error(`temporal-fmt: unknown token "${i.value}"`);if(e[s.field]===void 0)throw new Error(`temporal-fmt: token "${i.value}" requires "${s.field}", which this Temporal object doesn't have. (e.g. PlainDate has no time fields, PlainTime has no date fields)`);a+=s.fn(e,r)}return a}var j=new Map;function E(e,t,n){let r=e.formatToParts(t).find(o=>o.type===n);if(!r)throw new Error(`temporal-fmt: locale produced no "${n}" part while building match vocabulary.`);return r.value}function p(e){let t=j.get(e);if(t)return t;let n=new Intl.DateTimeFormat(e,{month:"long",timeZone:"UTC"}),r=new Intl.DateTimeFormat(e,{month:"short",timeZone:"UTC"}),o=[],a=[];for(let d=0;d<12;d++){let c=new Date(Date.UTC(2020,d,1));o.push(E(n,c,"month")),a.push(E(r,c,"month"))}let i=new Intl.DateTimeFormat(e,{weekday:"long",timeZone:"UTC"}),s=new Intl.DateTimeFormat(e,{weekday:"short",timeZone:"UTC"}),m=[],g=[];for(let d=0;d<7;d++){let c=new Date(Date.UTC(2024,0,1+d));m.push(E(i,c,"weekday")),g.push(E(s,c,"weekday"))}let u=new Intl.DateTimeFormat(e,{hour:"numeric",hour12:!0,timeZone:"UTC"}),f=E(u,new Date(Date.UTC(2020,0,1,1)),"dayPeriod"),F=E(u,new Date(Date.UTC(2020,0,1,13)),"dayPeriod"),h=[...new Set([f,F])],y={monthLong:o,monthShort:a,weekdayLong:m,weekdayShort:g,dayPeriod:h};return j.set(e,y),y}function me(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function b(e){return`(?:${e.map(me).join("|")})`}var P;function de(){if(P)return P;let e=Intl.supportedValuesOf;return typeof e=="function"?P=b([...e("timeZone"),"UTC"]):P="[A-Za-z_]+(?:\\/[A-Za-z_+\\-0-9]+)+|UTC",P}var ue={yyyy:"\\d{4}",yy:"\\d{2}",MM:"(?:0[1-9]|1[0-2])",M:"(?:[1-9]|1[0-2])",dd:"(?:0[1-9]|[12]\\d|3[01])",d:"(?:[1-9]|[12]\\d|3[01])",HH:"(?:[01]\\d|2[0-3])",H:"(?:[0-9]|1\\d|2[0-3])",hh:"(?:0[1-9]|1[0-2])",h:"(?:[1-9]|1[0-2])",mm:"(?:[0-5]\\d)",m:"(?:[0-9]|[1-5]\\d)",ss:"(?:[0-5]\\d)",s:"(?:[0-9]|[1-5]\\d)",SSS:"\\d{3}"};function K(e,t){let n=ue[e];if(n)return n;let r=p(t);switch(e){case"MMMM":return b(r.monthLong);case"MMM":return b(r.monthShort);case"EEEE":return b(r.weekdayLong);case"EEE":return b(r.weekdayShort);case"a":return b(r.dayPeriod);case"zzz":return de();default:throw new Error(`temporal-fmt: unknown token "${e}"`)}}function ce(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Y(e,t){let n=[],r="",o=0;for(let a of e){if(a.kind==="literal"){r+=ce(a.value);continue}let i=`g${o++}`;n.push({name:i,token:a.value}),r+=`(?<${i}>${K(a.value,t)})`}return{regex:new RegExp(`^(?:${r})$`,"u"),groups:n}}function W(){let e=globalThis.Temporal;if(!e)throw new Error("temporal-fmt: parse() needs a global `Temporal` to construct its result. Native on Node 26+, or assign a polyfill (e.g. temporal-polyfill) to globalThis.Temporal first.");return e}var I=new Map,le=500;function pe(e,t){let n=t+" "+e,r=I.get(n);if(r)return r;if(I.size>=le){let o=I.keys().next().value;o!==void 0&&I.delete(o)}return r=Y(S(e),t),I.set(n,r),r}var D=new Map,fe=500;function ge(e){if(D.has(e))return D.get(e);if(D.size>=fe){let r=D.keys().next().value;r!==void 0&&D.delete(r)}let t=new Intl.DateTimeFormat(e).resolvedOptions().calendar,n=t==="gregory"?void 0:t;return D.set(e,n),n}function he(e,t,n,r){switch(t){case"yyyy":e.year=parseInt(n,10);break;case"yy":e.twoDigitYear=parseInt(n,10);break;case"MM":case"M":e.month=parseInt(n,10);break;case"MMMM":e.month=p(r).monthLong.indexOf(n)+1;break;case"MMM":e.month=p(r).monthShort.indexOf(n)+1;break;case"dd":case"d":e.day=parseInt(n,10);break;case"EEEE":e.weekdayRaw=n,e.weekdayExpected=p(r).weekdayLong.indexOf(n)+1;break;case"EEE":e.weekdayRaw=n,e.weekdayExpected=p(r).weekdayShort.indexOf(n)+1;break;case"HH":case"H":e.hour=parseInt(n,10);break;case"hh":case"h":e.hour12=parseInt(n,10);break;case"mm":case"m":e.minute=parseInt(n,10);break;case"ss":case"s":e.second=parseInt(n,10);break;case"SSS":e.millisecond=parseInt(n,10);break;case"a":e.isPM=n===p(r).dayPeriod[1];break;case"zzz":e.timeZoneId=n;break}}function ye(e){if(e.year!==void 0)return e.year;if(e.twoDigitYear!==void 0)return e.twoDigitYear<=68?2e3+e.twoDigitYear:1900+e.twoDigitYear}function ke(e,t){if(e.hour!==void 0)return e.hour;if(e.hour12!==void 0){if(e.isPM===void 0)throw new Error(`temporal-fmt: format string "${t}" uses a 12-hour token ("hh"/"h") without an "a" token, so parse() can't tell AM from PM.`);return e.hour12%12+(e.isPM?12:0)}}function G(e,t,n={}){if(e.length>1e3)throw new Error(`temporal-fmt: format string exceeds maximum length of ${1e3} characters (got ${e.length}).`);let r=n.locale??C,o=ge(r),a=pe(e,r),i=a.regex.exec(t);if(!i)throw new Error("temporal-fmt: no valid pattern matches the format string and input shape");if(a.groups.length===0)throw new Error(`temporal-fmt: format string "${e}" has no tokens \u2014 nothing to parse into a value.`);let s={};for(let{name:T,token:_}of a.groups)he(s,_,i.groups[T],r);let m=ye(s),g=ke(s,e),{month:u,day:f,minute:F,second:h,millisecond:y,timeZoneId:d,weekdayExpected:c,weekdayRaw:X}=s,q=m!==void 0||u!==void 0||f!==void 0,k=m!==void 0&&u!==void 0&&f!==void 0;if(q&&!k)throw new Error(`temporal-fmt: format string "${e}" has an incomplete date \u2014 year, month, and day tokens must all be present together.`);let A=g!==void 0||F!==void 0||h!==void 0||y!==void 0;if(d!==void 0&&!(k&&A))throw new Error(`temporal-fmt: format string "${e}" has a "zzz" token but needs a full date and time to build a ZonedDateTime.`);if(c!==void 0&&!k)throw new Error(`temporal-fmt: format string "${e}" has a weekday token ("EEEE"/"EEE") but needs a full date to validate it against.`);if(!k&&!A)throw new Error(`temporal-fmt: format string "${e}" has no date or time tokens to parse.`);let x=W(),Z={hour:g??0,minute:F??0,second:h??0,millisecond:y??0},z=o?{calendar:o}:{},v={overflow:"reject"},w;try{d!==void 0?w=x.ZonedDateTime.from({year:m,month:u,day:f,...Z,...z,timeZone:d},v):k&&A?w=x.PlainDateTime.from({year:m,month:u,day:f,...Z,...z},v):k?w=x.PlainDate.from({year:m,month:u,day:f,...z},v):w=x.PlainTime.from(Z,v)}catch(T){throw new Error(`temporal-fmt: "${t}" doesn't describe a valid date/time for format "${e}": ${T.message}`)}if(c!==void 0){let T=w.dayOfWeek;if(T!==c){let _=p(r);throw new Error(`temporal-fmt: "${X}" doesn't match the actual weekday (${_.weekdayLong[T-1]}) for the parsed date.`)}}return w}0&&(module.exports={format,parse});
1
+ "use strict";var _=Object.defineProperty;var B=Object.getOwnPropertyDescriptor;var J=Object.getOwnPropertyNames;var Q=Object.prototype.hasOwnProperty;var ee=(e,t)=>{for(var n in t)_(e,n,{get:t[n],enumerable:!0})},te=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of J(t))!Q.call(e,o)&&o!==n&&_(e,o,{get:()=>t[o],enumerable:!(r=B(t,o))||r.enumerable});return e};var ne=e=>te(_({},"__esModule",{value:!0}),e);var we={};ee(we,{format:()=>V,parse:()=>G});module.exports=ne(we);function l(e,t){return String(e).padStart(t,"0")}var C="en-US",M=new Map,re=500;function R(e,t){let n=e+JSON.stringify(t),r=M.get(n);if(r)return r;if(M.size>=re){let o=M.keys().next().value;o!==void 0&&M.delete(o)}return r=new Intl.DateTimeFormat(e,t),M.set(n,r),r}var L;function oe(){if(L===void 0){L=!1;let e=globalThis.Temporal;if(e?.PlainDate)try{new Intl.DateTimeFormat("en-US",{day:"numeric"}).formatToParts(e.PlainDate.from("1970-01-01")),L=!0}catch{}}return L}function O(e,t,n,r){let o=e?.calendarId,a={...n,...o&&o!=="iso8601"?{calendar:o}:{}};if(!oe())return e.toLocaleString(t,a);let{toInstant:i,timeZoneId:s}=e,m=typeof i=="function"&&typeof s=="string",h=m?e.toInstant():e,u={...a,...m?{timeZone:s}:{}},g=R(t,u).formatToParts(h).find(y=>y.type===r);if(!g)throw new Error(`temporal-fmt: locale "${t}" produced no "${r}" part for this token. This usually means the Temporal object is missing the field the token needs.`);return g.value}function ae(e,t){let n=new Date(Date.UTC(1970,0,1,e)),o=R(t,{hour:"numeric",hour12:!0,timeZone:"UTC"}).formatToParts(n).find(a=>a.type==="dayPeriod");if(!o)throw new Error(`temporal-fmt: locale "${t}" produced no "dayPeriod" part for token "a".`);return o.value}var $=[["yyyy",e=>l(e.year,4),"year"],["yy",e=>{if(e.year<0)throw new Error(`temporal-fmt: token "yy" doesn't support negative years (got ${e.year}), since truncating to 2 digits would make it indistinguishable from a positive year. Use "yyyy" instead.`);return l(e.year%100,2)},"year"],["MMMM",(e,t)=>O(e,t,{month:"long"},"month"),"month"],["MMM",(e,t)=>O(e,t,{month:"short"},"month"),"month"],["MM",e=>l(e.month,2),"month"],["M",e=>String(e.month),"month"],["dd",e=>l(e.day,2),"day"],["d",e=>String(e.day),"day"],["EEEE",(e,t)=>O(e,t,{weekday:"long"},"weekday"),"dayOfWeek"],["EEE",(e,t)=>O(e,t,{weekday:"short"},"weekday"),"dayOfWeek"],["HH",e=>l(e.hour,2),"hour"],["H",e=>String(e.hour),"hour"],["hh",e=>l(e.hour%12||12,2),"hour"],["h",e=>String(e.hour%12||12),"hour"],["mm",e=>l(e.minute,2),"minute"],["m",e=>String(e.minute),"minute"],["ss",e=>l(e.second,2),"second"],["s",e=>String(e.second),"second"],["SSS",e=>l(e.millisecond,3),"millisecond"],["a",(e,t)=>ae(e.hour,t),"hour"],["zzz",e=>e.timeZoneId,"timeZoneId"]];var ie=$.map(([e])=>e).sort((e,t)=>t.length-e.length);function S(e){let t=[],n=0;for(;n<e.length;){let r=e[n];if(r==="'"){if(e[n+1]==="'"){U(t,"'"),n+=2;continue}let a=n+1,i="",s=!1;for(;a<e.length;){if(e[a]==="'"){if(e[a+1]==="'"){i+="'",a+=2;continue}s=!0,a+=1;break}i+=e[a],a+=1}if(!s)throw new Error(`temporal-fmt: unterminated quote in format string "${e}"`);U(t,i),n=a;continue}let o=ie.find(a=>e.startsWith(a,n));if(o){t.push({kind:"token",value:o}),n+=o.length;continue}U(t,r),n+=1}return t}function U(e,t){let n=e[e.length-1];n&&n.kind==="literal"?n.value+=t:e.push({kind:"literal",value:t})}var se=new Map($.map(([e,t,n])=>[e,{fn:t,field:n}]));function V(e,t,n={}){if(t.length>1e3)throw new Error(`temporal-fmt: format string exceeds maximum length of ${1e3} characters (got ${t.length}).`);let r=n.locale??C,o=S(t),a="";for(let i of o){if(i.kind==="literal"){a+=i.value;continue}let s=se.get(i.value);if(!s)throw new Error(`temporal-fmt: unknown token "${i.value}"`);if(e[s.field]===void 0)throw new Error(`temporal-fmt: token "${i.value}" requires "${s.field}", which this Temporal object doesn't have. (e.g. PlainDate has no time fields, PlainTime has no date fields)`);a+=s.fn(e,r)}return a}var j=new Map;function E(e,t,n){let r=e.formatToParts(t).find(o=>o.type===n);if(!r)throw new Error(`temporal-fmt: locale produced no "${n}" part while building match vocabulary.`);return r.value}function p(e){let t=j.get(e);if(t)return t;let n=new Intl.DateTimeFormat(e,{month:"long",timeZone:"UTC"}),r=new Intl.DateTimeFormat(e,{month:"short",timeZone:"UTC"}),o=[],a=[];for(let d=0;d<12;d++){let c=new Date(Date.UTC(2020,d,1));o.push(E(n,c,"month")),a.push(E(r,c,"month"))}let i=new Intl.DateTimeFormat(e,{weekday:"long",timeZone:"UTC"}),s=new Intl.DateTimeFormat(e,{weekday:"short",timeZone:"UTC"}),m=[],h=[];for(let d=0;d<7;d++){let c=new Date(Date.UTC(2024,0,1+d));m.push(E(i,c,"weekday")),h.push(E(s,c,"weekday"))}let u=new Intl.DateTimeFormat(e,{hour:"numeric",hour12:!0,timeZone:"UTC"}),f=E(u,new Date(Date.UTC(2020,0,1,1)),"dayPeriod"),F=E(u,new Date(Date.UTC(2020,0,1,13)),"dayPeriod"),g=[...new Set([f,F])],y={monthLong:o,monthShort:a,weekdayLong:m,weekdayShort:h,dayPeriod:g};return j.set(e,y),y}function me(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function b(e){return`(?:${e.map(me).join("|")})`}var P;function de(){if(P)return P;let e=Intl.supportedValuesOf;return typeof e=="function"?P=b([...e("timeZone"),"UTC"]):P="[A-Za-z_]+(?:\\/[A-Za-z_+\\-0-9]+)+|UTC",P}var ue={yyyy:"\\d{4}",yy:"\\d{2}",MM:"(?:0[1-9]|1[0-2])",M:"(?:[1-9]|1[0-2])",dd:"(?:0[1-9]|[12]\\d|3[01])",d:"(?:[1-9]|[12]\\d|3[01])",HH:"(?:[01]\\d|2[0-3])",H:"(?:[0-9]|1\\d|2[0-3])",hh:"(?:0[1-9]|1[0-2])",h:"(?:[1-9]|1[0-2])",mm:"(?:[0-5]\\d)",m:"(?:[0-9]|[1-5]\\d)",ss:"(?:[0-5]\\d)",s:"(?:[0-9]|[1-5]\\d)",SSS:"\\d{3}"};function K(e,t){let n=ue[e];if(n)return n;let r=p(t);switch(e){case"MMMM":return b(r.monthLong);case"MMM":return b(r.monthShort);case"EEEE":return b(r.weekdayLong);case"EEE":return b(r.weekdayShort);case"a":return b(r.dayPeriod);case"zzz":return de();default:throw new Error(`temporal-fmt: unknown token "${e}"`)}}function ce(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Y(e,t){let n=[],r="",o=0;for(let a of e){if(a.kind==="literal"){r+=ce(a.value);continue}let i=`g${o++}`;n.push({name:i,token:a.value}),r+=`(?<${i}>${K(a.value,t)})`}return{regex:new RegExp(`^(?:${r})$`,"u"),groups:n}}function W(){let e=globalThis.Temporal;if(!e)throw new Error("temporal-fmt: parse() needs a global `Temporal` to construct its result. Native on Node 26+, or assign a polyfill (e.g. temporal-polyfill) to globalThis.Temporal first.");return e}var I=new Map,le=500;function pe(e,t){let n=t+" "+e,r=I.get(n);if(r)return r;if(I.size>=le){let o=I.keys().next().value;o!==void 0&&I.delete(o)}return r=Y(S(e),t),I.set(n,r),r}var D=new Map,fe=500;function he(e){if(D.has(e))return D.get(e);if(D.size>=fe){let r=D.keys().next().value;r!==void 0&&D.delete(r)}let t=new Intl.DateTimeFormat(e).resolvedOptions().calendar,n=t==="gregory"?void 0:t;return D.set(e,n),n}function ge(e,t,n,r){switch(t){case"yyyy":e.year=parseInt(n,10);break;case"yy":e.twoDigitYear=parseInt(n,10);break;case"MM":case"M":e.month=parseInt(n,10);break;case"MMMM":e.month=p(r).monthLong.indexOf(n)+1;break;case"MMM":e.month=p(r).monthShort.indexOf(n)+1;break;case"dd":case"d":e.day=parseInt(n,10);break;case"EEEE":e.weekdayRaw=n,e.weekdayExpected=p(r).weekdayLong.indexOf(n)+1;break;case"EEE":e.weekdayRaw=n,e.weekdayExpected=p(r).weekdayShort.indexOf(n)+1;break;case"HH":case"H":e.hour=parseInt(n,10);break;case"hh":case"h":e.hour12=parseInt(n,10);break;case"mm":case"m":e.minute=parseInt(n,10);break;case"ss":case"s":e.second=parseInt(n,10);break;case"SSS":e.millisecond=parseInt(n,10);break;case"a":e.isPM=n===p(r).dayPeriod[1];break;case"zzz":e.timeZoneId=n;break}}function ye(e){if(e.year!==void 0)return e.year;if(e.twoDigitYear!==void 0)return e.twoDigitYear<=68?2e3+e.twoDigitYear:1900+e.twoDigitYear}function ke(e,t){if(e.hour!==void 0&&e.hour12!==void 0)throw new Error(`temporal-fmt: format string "${t}" mixes a 24-hour token ("HH"/"H") with a 12-hour token ("hh"/"h"). Pick one or the other \u2014 parse() won't guess which is authoritative.`);if(e.hour!==void 0)return e.hour;if(e.hour12!==void 0){if(e.isPM===void 0)throw new Error(`temporal-fmt: format string "${t}" uses a 12-hour token ("hh"/"h") without an "a" token, so parse() can't tell AM from PM.`);return e.hour12%12+(e.isPM?12:0)}}function G(e,t,n={}){if(e.length>1e3)throw new Error(`temporal-fmt: format string exceeds maximum length of ${1e3} characters (got ${e.length}).`);let r=n.locale??C,o=he(r),a=pe(e,r),i=a.regex.exec(t);if(!i)throw new Error("temporal-fmt: no valid pattern matches the format string and input shape");if(a.groups.length===0)throw new Error(`temporal-fmt: format string "${e}" has no tokens \u2014 nothing to parse into a value.`);let s={};for(let{name:T,token:H}of a.groups)ge(s,H,i.groups[T],r);let m=ye(s),h=ke(s,e),{month:u,day:f,minute:F,second:g,millisecond:y,timeZoneId:d,weekdayExpected:c,weekdayRaw:X}=s,q=m!==void 0||u!==void 0||f!==void 0,k=m!==void 0&&u!==void 0&&f!==void 0;if(q&&!k)throw new Error(`temporal-fmt: format string "${e}" has an incomplete date \u2014 year, month, and day tokens must all be present together.`);let A=h!==void 0||F!==void 0||g!==void 0||y!==void 0;if(d!==void 0&&!(k&&A))throw new Error(`temporal-fmt: format string "${e}" has a "zzz" token but needs a full date and time to build a ZonedDateTime.`);if(c!==void 0&&!k)throw new Error(`temporal-fmt: format string "${e}" has a weekday token ("EEEE"/"EEE") but needs a full date to validate it against.`);if(!k&&!A)throw new Error(`temporal-fmt: format string "${e}" has no date or time tokens to parse.`);let x=W(),Z={hour:h??0,minute:F??0,second:g??0,millisecond:y??0},z=o?{calendar:o}:{},v={overflow:"reject"},w;try{d!==void 0?w=x.ZonedDateTime.from({year:m,month:u,day:f,...Z,...z,timeZone:d},v):k&&A?w=x.PlainDateTime.from({year:m,month:u,day:f,...Z,...z},v):k?w=x.PlainDate.from({year:m,month:u,day:f,...z},v):w=x.PlainTime.from(Z,v)}catch(T){throw new Error(`temporal-fmt: "${t}" doesn't describe a valid date/time for format "${e}": ${T.message}`)}if(c!==void 0){let T=w.dayOfWeek;if(T!==c){let H=p(r);throw new Error(`temporal-fmt: "${X}" doesn't match the actual weekday (${H.weekdayLong[T-1]}) for the parsed date.`)}}return w}0&&(module.exports={format,parse});
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/tokens.ts","../src/tokenize.ts","../src/format.ts","../src/localeVocab.ts","../src/pattern.ts","../src/parsePattern.ts","../src/temporalGlobal.ts","../src/parse.ts"],"sourcesContent":["export { format } from './format.js';\nexport { parse } from './parse.js';\nexport type { TemporalLike, FormatOptions } from './tokens.js';","export function pad(n: number, len: number): string {\n return String(n).padStart(len, '0');\n}\n\n// Not every field exists on every Temporal type (PlainDate has no .hour,\n// etc). Callers check for undefined before formatting a token.\nexport interface TemporalLike {\n year?: number;\n month?: number;\n day?: number;\n hour?: number;\n minute?: number;\n second?: number;\n millisecond?: number;\n timeZoneId?: string;\n dayOfWeek?: number; // 1 (Mon) - 7 (Sun), per Temporal spec\n calendarId?: string;\n toInstant?: () => unknown;\n toLocaleString?: (locale: string, options: Intl.DateTimeFormatOptions) => string;\n}\n\nexport interface FormatOptions {\n /** BCP 47 locale tag, e.g. 'en-US', 'fr-FR', 'ar-EG'. Defaults to 'en-US'. */\n locale?: string;\n}\n\nexport const DEFAULT_LOCALE = 'en-US';\n\n// Intl.DateTimeFormat is expensive to construct and format() can run in a\n// loop (rendering a table of dates), so cache by (locale, options).\nconst formatterCache = new Map<string, Intl.DateTimeFormat>();\nconst MAX_CACHE_SIZE = 500;\n\nfunction getFormatter(locale: string, options: Intl.DateTimeFormatOptions): Intl.DateTimeFormat {\n const key = locale + JSON.stringify(options);\n let formatter = formatterCache.get(key);\n if (formatter) {\n return formatter;\n }\n if (formatterCache.size >= MAX_CACHE_SIZE) {\n // not real LRU, just evicts oldest insertion — fine for this key space\n const oldestKey = formatterCache.keys().next().value;\n if (oldestKey !== undefined) formatterCache.delete(oldestKey);\n }\n formatter = new Intl.DateTimeFormat(locale, options);\n formatterCache.set(key, formatter);\n return formatter;\n}\n\n// Passing a Temporal object straight into `new Intl.DateTimeFormat().formatToParts()`\n// only works when the engine's Intl implementation has special-cased support for\n// *native* Temporal instances (checked via internal slots and/or gated behind a V8 flag,\n// not tied to a specific Node version).\n// \n// A Temporal polyfill's instances don't have those slots, so the engine falls back to ToNumber() -> .valueOf(),\n// which the polyfill deliberately throws on (\"Cannot use valueOf\"). \n// Probed once and memoized and only from intlPart(), so it never\n// runs unless a format string actually uses a locale-aware token.\nlet nativeSupport: boolean | undefined;\nfunction intlSupportsNativeTemporal(): boolean {\n if (nativeSupport === undefined) {\n nativeSupport = false;\n const Temporal = (globalThis as { Temporal?: { PlainDate?: { from: (s: string) => unknown } } }).Temporal;\n if (Temporal?.PlainDate) {\n try {\n new Intl.DateTimeFormat('en-US', { day: 'numeric' }).formatToParts(Temporal.PlainDate.from('1970-01-01') as Date);\n nativeSupport = true;\n } catch {\n // native Temporal absent, or present but not recognized by Intl — fall back\n }\n }\n }\n return nativeSupport;\n}\n\nfunction intlPart(\n temporal: TemporalLike,\n locale: string,\n options: Intl.DateTimeFormatOptions,\n partType: Intl.DateTimeFormatPartTypes\n): string {\n // Intl throws \"Mismatching Calendars\" if the formatter's calendar doesn't\n // match the object's own (e.g. en-US formatter defaults to gregory, but\n // a hebrew/islamic PlainDate needs its own calendar passed through).\n //\n // skip this for iso8601 specifically — passing `calendar: 'iso8601'`\n // explicitly alongside a single-field options object makes formatToParts()\n // come back empty for some reason.\n const calendar = temporal?.calendarId;\n const formatterOptions: Intl.DateTimeFormatOptions = {\n ...options,\n ...(calendar && calendar !== 'iso8601' ? { calendar } : {}),\n };\n\n // Temporal.prototype.toLocaleString() is part of the Temporal spec itself:\n // polyfills implement the ICU formatting internally without needing the\n // engine to recognize the object, so it works without native Intl support.\n if (!intlSupportsNativeTemporal()) {\n return temporal.toLocaleString!(locale, formatterOptions);\n }\n\n // formatToParts() throws on ZonedDateTime directly (per spec), so convert\n // to Instant and pass the zone via `timeZone` instead. Don't convert to\n // PlainDateTime — that drops the zone, which breaks 'MMMM' + 'zzz' combos.\n const { toInstant, timeZoneId } = temporal;\n const isZoned = typeof toInstant === 'function' && typeof timeZoneId === 'string';\n // has to be called as temporal.toInstant() because destructuring it off breaks\n // the receiver and throws\n const intlSafeTemporal = isZoned ? temporal.toInstant!() : temporal;\n const nativeOptions: Intl.DateTimeFormatOptions = {\n ...formatterOptions,\n ...(isZoned ? { timeZone: timeZoneId } : {}),\n };\n\n const formatter = getFormatter(locale, nativeOptions);\n const parts = formatter.formatToParts(intlSafeTemporal as Date | number);\n const part = parts.find((p) => p.type === partType);\n if (!part) {\n throw new Error(\n `temporal-fmt: locale \"${locale}\" produced no \"${partType}\" part for this token. ` +\n `This usually means the Temporal object is missing the field the token needs.`\n );\n }\n return part.value;\n}\n\n\n// Temporal.prototype.toLocaleString() can't isolate a single field the way formatToParts() can\n// — asking for `hour` + `dayPeriod` together returns one joined string (e.g.\n// \"3 in the afternoon\"), and asking for `dayPeriod` alone silently resolves\n// against a different, non-hour-anchored set of periods (produces \"in the\n// afternoon\"/\"昼\" instead of the \"PM\"/\"午後\" that pairing it with hour12\n// actually renders).\n// \n// On using this instead of temporal:\n// Day period only depends on the hour, not on the calendar or the date, \n// so always route it through a plain UTC Date instead\n// Intl.DateTimeFormat has always accepted Date objects, on every engine,\n// independent of whether Temporal itself is native or polyfilled.\nfunction dayPeriodPart(hour: number, locale: string): string {\n const date = new Date(Date.UTC(1970, 0, 1, hour));\n const formatter = getFormatter(locale, { hour: 'numeric', hour12: true, timeZone: 'UTC' });\n const part = formatter.formatToParts(date).find((p) => p.type === 'dayPeriod');\n if (!part) {\n throw new Error(`temporal-fmt: locale \"${locale}\" produced no \"dayPeriod\" part for token \"a\".`);\n }\n return part.value;\n}\n\ntype TokenHandler = (t: TemporalLike, locale: string) => string;\n\n// Longest-first — tokenizer is greedy, \"yyyy\" has to be tried before \"yy\".\n//\n// Numeric tokens always render in ASCII digits, never locale-native\n// (Arabic-Indic, Devanagari, etc). Padding non-ASCII digit strings to a\n// fixed width isn't the same operation as padding \"3\", and most consumers\n// parsing these back out want plain digits anyway.\nexport const TOKENS: Array<[string, TokenHandler, keyof TemporalLike]> = [\n ['yyyy', (t) => pad(t.year!, 4), 'year'],\n ['yy', (t) => {\n // -45 % 100 === -45, so truncating negative years to 2 digits doesn't\n // work and Math.abs() would make 45 CE and 45 BCE render the same.\n if (t.year! < 0) {\n throw new Error(\n `temporal-fmt: token \"yy\" doesn't support negative years (got ${t.year}), ` +\n `since truncating to 2 digits would make it indistinguishable from a ` +\n `positive year. Use \"yyyy\" instead.`\n );\n }\n return pad(t.year! % 100, 2);\n }, 'year'],\n ['MMMM', (t, locale) => intlPart(t, locale, { month: 'long' }, 'month'), 'month'],\n ['MMM', (t, locale) => intlPart(t, locale, { month: 'short' }, 'month'), 'month'],\n ['MM', (t) => pad(t.month!, 2), 'month'],\n ['M', (t) => String(t.month!), 'month'],\n ['dd', (t) => pad(t.day!, 2), 'day'],\n ['d', (t) => String(t.day!), 'day'],\n ['EEEE', (t, locale) => intlPart(t, locale, { weekday: 'long' }, 'weekday'), 'dayOfWeek'],\n ['EEE', (t, locale) => intlPart(t, locale, { weekday: 'short' }, 'weekday'), 'dayOfWeek'],\n ['HH', (t) => pad(t.hour!, 2), 'hour'],\n ['H', (t) => String(t.hour!), 'hour'],\n ['hh', (t) => pad(t.hour! % 12 || 12, 2), 'hour'],\n ['h', (t) => String(t.hour! % 12 || 12), 'hour'],\n ['mm', (t) => pad(t.minute!, 2), 'minute'],\n ['m', (t) => String(t.minute!), 'minute'],\n ['ss', (t) => pad(t.second!, 2), 'second'],\n ['s', (t) => String(t.second!), 'second'],\n ['SSS', (t) => pad(t.millisecond!, 3), 'millisecond'],\n // dayPeriod text is locale-specific (AM/PM in en-US, م/ص in ar-EG) but\n // still needs .hour on the input to compute which period it is\n ['a', (t, locale) => dayPeriodPart(t.hour!, locale), 'hour'],\n ['zzz', (t) => t.timeZoneId!, 'timeZoneId'],\n];\n","import { TOKENS } from './tokens.js';\n\nexport type Piece =\n | { kind: 'token'; value: string }\n | { kind: 'literal'; value: string };\n\n// longest-first so the greedy scan never matches \"M\" when \"MMMM\" was there\nconst SORTED_TOKEN_STRINGS = TOKENS.map(([tok]) => tok).sort((a, b) => b.length - a.length);\n\n/**\n * Splits a format string like `\"yyyy-MM-dd 'at' HH:mm\"` into token/literal\n * pieces. Text in single quotes is always literal (e.g. write 'rd' in\n * \"3rd\" so it's not read as the day token). A doubled quote ('') means a\n * literal quote character, both inside a quoted span and standalone.\n */\nexport function tokenize(format: string): Piece[] {\n const pieces: Piece[] = [];\n let i = 0;\n\n while (i < format.length) {\n const ch = format[i];\n\n if (ch === \"'\") {\n // check doubled-quote first or \"''best''\" parses wrong\n if (format[i + 1] === \"'\") {\n appendLiteral(pieces, \"'\");\n i += 2;\n continue;\n }\n\n let j = i + 1;\n let literal = '';\n let closed = false;\n while (j < format.length) {\n if (format[j] === \"'\") {\n if (format[j + 1] === \"'\") {\n literal += \"'\";\n j += 2;\n continue;\n }\n closed = true;\n j += 1;\n break;\n }\n literal += format[j];\n j += 1;\n }\n\n if (!closed) {\n throw new Error(`temporal-fmt: unterminated quote in format string \"${format}\"`);\n }\n\n appendLiteral(pieces, literal);\n i = j;\n continue;\n }\n\n const match = SORTED_TOKEN_STRINGS.find((tok) => format.startsWith(tok, i));\n if (match) {\n pieces.push({ kind: 'token', value: match });\n i += match.length;\n continue;\n }\n\n // not a token or quote — pass through as-is \n appendLiteral(pieces, ch);\n i += 1;\n }\n\n return pieces;\n}\n\n// merges into the previous piece if it's also a literal, so \"---\" is one\n// piece instead of three\nfunction appendLiteral(pieces: Piece[], value: string): void {\n const last = pieces[pieces.length - 1];\n if (last && last.kind === 'literal') {\n last.value += value;\n } else {\n pieces.push({ kind: 'literal', value });\n }\n}\n","import { TOKENS, DEFAULT_LOCALE, type TemporalLike, type FormatOptions } from './tokens.js';\nimport { tokenize } from './tokenize.js';\nimport { MAX_FORMAT_LENGTH } from './constants.js';\n\nconst HANDLER_BY_TOKEN = new Map(TOKENS.map(([tok, fn, field]) => [tok, { fn, field }]));\n\n/**\n * Format a Temporal.PlainDate, PlainTime, PlainDateTime, or ZonedDateTime\n * using a date-fns-style token string.\n *\n * @example\n * format(Temporal.Now.plainDateISO(), 'yyyy-MM-dd') // \"2026-08-04\"\n * format(zdt, \"MMM d, yyyy 'at' h:mm a\") // \"Aug 4, 2026 at 3:45 PM\"\n * format(zdt, 'MMMM d, yyyy', { locale: 'fr-FR' }) // \"août 4, 2026\"\n * format(zdt, 'EEEE d MMMM', { locale: 'ar-EG' }) // Arabic weekday/month names\n *\n * Numeric fields always render in ASCII digits regardless of locale.\n * Named fields (MMMM, EEEE, a) are fully localized via Intl, including\n * non-Gregorian calendars if the Temporal object carries one.\n *\n * Throws if the format string uses a token the input type doesn't support\n * (e.g. 'HH' on a PlainDate) rather than silently printing \"undefined\".\n */\nexport function format(temporal: TemporalLike, formatStr: string, options: FormatOptions = {}): string {\n if (formatStr.length > MAX_FORMAT_LENGTH) {\n throw new Error(\n `temporal-fmt: format string exceeds maximum length of ${MAX_FORMAT_LENGTH} characters ` +\n `(got ${formatStr.length}).`\n );\n }\n\n const locale = options.locale ?? DEFAULT_LOCALE;\n const pieces = tokenize(formatStr);\n let result = '';\n\n for (const piece of pieces) {\n if (piece.kind === 'literal') {\n result += piece.value;\n continue;\n }\n\n const handler = HANDLER_BY_TOKEN.get(piece.value);\n if (!handler) {\n // shouldn't happen — tokenize() only emits tokens from TOKENS\n throw new Error(`temporal-fmt: unknown token \"${piece.value}\"`);\n }\n\n if (temporal[handler.field] === undefined) {\n throw new Error(\n `temporal-fmt: token \"${piece.value}\" requires \"${handler.field}\", ` +\n `which this Temporal object doesn't have. ` +\n `(e.g. PlainDate has no time fields, PlainTime has no date fields)`\n );\n }\n\n result += handler.fn(temporal, locale);\n }\n\n return result;\n}\n","// Closed-vocabulary lookups for locale-aware tokens (MMMM, MMM, EEEE, EEE, a).\n// Each set 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\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\nconst vocabCache = new Map<string, LocaleVocab>();\n\nfunction partValue(formatter: Intl.DateTimeFormat, date: Date, type: Intl.DateTimeFormatPartTypes): string {\n const part = formatter.formatToParts(date).find((p) => p.type === type);\n if (!part) {\n throw new Error(`temporal-fmt: locale produced no \"${type}\" part while building match vocabulary.`);\n }\n return part.value;\n}\n\nexport function getLocaleVocab(locale: string): LocaleVocab {\n const cached = vocabCache.get(locale);\n if (cached) {\n return cached;\n }\n\n const monthLongFmt = new Intl.DateTimeFormat(locale, { month: 'long', timeZone: 'UTC' });\n const monthShortFmt = new Intl.DateTimeFormat(locale, { 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\n const weekdayLongFmt = new Intl.DateTimeFormat(locale, { weekday: 'long', timeZone: 'UTC' });\n const weekdayShortFmt = new Intl.DateTimeFormat(locale, { 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\n const dayPeriodFmt = new Intl.DateTimeFormat(locale, { 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 vocabCache.set(locale, vocab);\n return vocab;\n}\n","import { getLocaleVocab } from './localeVocab.js';\n\nfunction escapeRegExp(literal: string): string {\n return literal.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nfunction alternation(values: string[]): string {\n return `(?:${values.map(escapeRegExp).join('|')})`;\n}\n\nlet timeZoneFragment: string | undefined;\n\nfunction getTimeZoneFragment(): string {\n if (timeZoneFragment) {\n return timeZoneFragment;\n }\n const supportedValuesOf = (Intl as unknown as { supportedValuesOf?: (key: string) => string[] }).supportedValuesOf;\n if (typeof supportedValuesOf === 'function') {\n // supportedValuesOf('timeZone') leaves out 'UTC', but format() can\n // produce it from a real ZonedDateTime — without this, parse() couldn't\n // parse our own library's own output back.\n timeZoneFragment = alternation([...supportedValuesOf('timeZone'), 'UTC']);\n } else {\n // no Intl.supportedValuesOf — match on shape only\n timeZoneFragment = '[A-Za-z_]+(?:\\\\/[A-Za-z_+\\\\-0-9]+)+|UTC';\n }\n return timeZoneFragment;\n}\n\n// mirrors the ranges pad() in tokens.ts actually produces — keep in sync\n// if those ever change\nconst NUMERIC_FRAGMENTS: Record<string, string> = {\n yyyy: '\\\\d{4}',\n yy: '\\\\d{2}',\n MM: '(?:0[1-9]|1[0-2])',\n M: '(?:[1-9]|1[0-2])',\n dd: '(?:0[1-9]|[12]\\\\d|3[01])',\n d: '(?:[1-9]|[12]\\\\d|3[01])',\n HH: '(?:[01]\\\\d|2[0-3])',\n H: '(?:[0-9]|1\\\\d|2[0-3])',\n hh: '(?:0[1-9]|1[0-2])',\n h: '(?:[1-9]|1[0-2])',\n mm: '(?:[0-5]\\\\d)',\n m: '(?:[0-9]|[1-5]\\\\d)',\n ss: '(?:[0-5]\\\\d)',\n s: '(?:[0-9]|[1-5]\\\\d)',\n SSS: '\\\\d{3}',\n};\n\nexport function tokenFragment(token: string, locale: string): string {\n const numeric = NUMERIC_FRAGMENTS[token];\n if (numeric) {\n return numeric;\n }\n\n const vocab = getLocaleVocab(locale);\n switch (token) {\n case 'MMMM': return alternation(vocab.monthLong);\n case 'MMM': return alternation(vocab.monthShort);\n case 'EEEE': return alternation(vocab.weekdayLong);\n case 'EEE': return alternation(vocab.weekdayShort);\n case 'a': return alternation(vocab.dayPeriod);\n case 'zzz': return getTimeZoneFragment();\n default:\n throw new Error(`temporal-fmt: unknown token \"${token}\"`);\n }\n}\n","import type { Piece } from './tokenize.js';\nimport { tokenFragment } from './pattern.js';\n\nfunction escapeRegExp(literal: string): string {\n return literal.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nexport interface CapturingPattern {\n regex: RegExp;\n groups: Array<{ name: string; token: string }>; // token pieces, in order\n}\n\n/**\n * Same walk as buildPatternSource() in pattern.ts, but each token piece\n * gets its own named capture group (positionally named so the same token,\n * e.g. \"yyyy\", could in theory appear twice) so a caller can pull the\n * matched substring for each token back out after a successful match.\n */\nexport function buildCapturingPattern(pieces: Piece[], locale: string): CapturingPattern {\n const groups: Array<{ name: string; token: string }> = [];\n let source = '';\n let i = 0;\n\n for (const piece of pieces) {\n if (piece.kind === 'literal') {\n source += escapeRegExp(piece.value);\n continue;\n }\n const name = `g${i++}`;\n groups.push({ name, token: piece.value });\n source += `(?<${name}>${tokenFragment(piece.value, locale)})`;\n }\n\n return { regex: new RegExp(`^(?:${source})$`, 'u'), groups };\n}\n","// This package's tsconfig assumes lib: [\"ESNext\"] only — no ambient\n// `Temporal` namespace type. Everywhere else in this codebase only ever\n// *reads* fields off a Temporal-like object the caller already built\n// (TemporalLike in tokens.ts). parse() is the first place that needs to\n// *construct* one, via the global `Temporal` the README already requires\n// consumers to provide (native on Node 26+, or a polyfill). Kept loosely\n// typed on purpose, consistent with the rest of the codebase.\ninterface TemporalFactory {\n from(fields: Record<string, number | string | undefined>, options?: { overflow?: 'constrain' | 'reject' }): unknown;\n}\n\nexport interface TemporalNamespace {\n PlainDate: TemporalFactory;\n PlainTime: TemporalFactory;\n PlainDateTime: TemporalFactory;\n ZonedDateTime: TemporalFactory;\n}\n\nexport function getTemporal(): TemporalNamespace {\n const temporal = (globalThis as { Temporal?: TemporalNamespace }).Temporal;\n if (!temporal) {\n throw new Error(\n 'temporal-fmt: parse() needs a global `Temporal` to construct its result. ' +\n 'Native on Node 26+, or assign a polyfill (e.g. temporal-polyfill) to globalThis.Temporal first.'\n );\n }\n return temporal;\n}\n","import { DEFAULT_LOCALE, type FormatOptions } from './tokens.js';\nimport { tokenize } from './tokenize.js';\nimport { buildCapturingPattern, type CapturingPattern } from './parsePattern.js';\nimport { getLocaleVocab } from './localeVocab.js';\nimport { getTemporal } from './temporalGlobal.js';\nimport { MAX_FORMAT_LENGTH } from './constants.js';\n\n// format strings are short hand-written literals reused across many calls —\n// cache the compiled capturing pattern per (formatStr, locale) pair instead\n// of rebuilding it every call.\nconst patternCache = new Map<string, CapturingPattern>();\nconst MAX_CACHE_SIZE = 500;\n\nfunction getPattern(formatStr: string, locale: string): CapturingPattern {\n const key = locale + ' ' + formatStr;\n let pattern = patternCache.get(key);\n if (pattern) {\n return pattern;\n }\n if (patternCache.size >= MAX_CACHE_SIZE) {\n const oldestKey = patternCache.keys().next().value;\n if (oldestKey !== undefined) patternCache.delete(oldestKey);\n }\n pattern = buildCapturingPattern(tokenize(formatStr), locale);\n patternCache.set(key, pattern);\n return pattern;\n}\n\n// Intl.DateTimeFormat(locale).resolvedOptions().calendar reports the\n// locale's default calendar so passing locale with a `-u-ca-` extension in the tag\n// allows setting non-gregorian calendars. 'gregory' is treated as \"no calendar\" so\n// the default locale ('en-US') keeps constructing plain ISO 8601\nconst calendarCache = new Map<string, string | undefined>();\nconst MAX_CALENDAR_CACHE_SIZE = 500;\n\nfunction resolveCalendar(locale: string): string | undefined {\n if (calendarCache.has(locale)) {\n return calendarCache.get(locale);\n }\n if (calendarCache.size >= MAX_CALENDAR_CACHE_SIZE) {\n const oldestKey = calendarCache.keys().next().value;\n if (oldestKey !== undefined) calendarCache.delete(oldestKey);\n }\n const resolved = new Intl.DateTimeFormat(locale).resolvedOptions().calendar;\n const calendar = resolved === 'gregory' ? undefined : resolved;\n calendarCache.set(locale, calendar);\n return calendar;\n}\n\ninterface Fields {\n year?: number;\n twoDigitYear?: number;\n month?: number;\n day?: number;\n hour?: number;\n hour12?: number;\n isPM?: boolean;\n minute?: number;\n second?: number;\n millisecond?: number;\n timeZoneId?: string;\n weekdayExpected?: number; // ISO dayOfWeek, 1 (Mon) - 7 (Sun)\n weekdayRaw?: string;\n}\n\nfunction applyGroup(fields: Fields, token: string, raw: string, locale: string): void {\n switch (token) {\n case 'yyyy': fields.year = parseInt(raw, 10); break;\n case 'yy': fields.twoDigitYear = parseInt(raw, 10); break;\n case 'MM': case 'M': fields.month = parseInt(raw, 10); break;\n case 'MMMM': fields.month = getLocaleVocab(locale).monthLong.indexOf(raw) + 1; break;\n case 'MMM': fields.month = getLocaleVocab(locale).monthShort.indexOf(raw) + 1; break;\n case 'dd': case 'd': fields.day = parseInt(raw, 10); break;\n case 'EEEE':\n fields.weekdayRaw = raw;\n fields.weekdayExpected = getLocaleVocab(locale).weekdayLong.indexOf(raw) + 1;\n break;\n case 'EEE':\n fields.weekdayRaw = raw;\n fields.weekdayExpected = getLocaleVocab(locale).weekdayShort.indexOf(raw) + 1;\n break;\n case 'HH': case 'H': fields.hour = parseInt(raw, 10); break;\n case 'hh': case 'h': fields.hour12 = parseInt(raw, 10); break;\n case 'mm': case 'm': fields.minute = parseInt(raw, 10); break;\n case 'ss': case 's': fields.second = parseInt(raw, 10); break;\n case 'SSS': fields.millisecond = parseInt(raw, 10); break;\n case 'a': fields.isPM = raw === getLocaleVocab(locale).dayPeriod[1]; break;\n case 'zzz': fields.timeZoneId = raw; break;\n }\n}\n\n/**\n * Resolves year value into 4-digit year\n * \n * For 2-digit values it emulates strptime (POSIX)\n * so that resolving value is not clock-dependent\n * \n * * 00-68 -> 2000-2068\n * * 69-99 -> 1900-1999\n * \n * @see https://www.man7.org/linux//man-pages/man3/strptime.3p.html\n */\nfunction resolveYear(fields: Fields): number | undefined {\n if (fields.year !== undefined) return fields.year;\n if (fields.twoDigitYear !== undefined) {\n return fields.twoDigitYear <= 68 ? 2000 + fields.twoDigitYear : 1900 + fields.twoDigitYear;\n }\n return undefined;\n}\n\nfunction resolveHour(fields: Fields, formatStr: string): number | undefined {\n if (fields.hour !== undefined) return fields.hour;\n if (fields.hour12 !== undefined) {\n if (fields.isPM === undefined) {\n throw new Error(\n `temporal-fmt: format string \"${formatStr}\" uses a 12-hour token (\"hh\"/\"h\") without an \"a\" token, ` +\n `so parse() can't tell AM from PM.`\n );\n }\n return (fields.hour12 % 12) + (fields.isPM ? 12 : 0);\n }\n return undefined;\n}\n\n/**\n * Parses `input` against `formatStr` and builds the real Temporal value it\n * describes: a `Temporal.PlainDate`, `PlainTime`, `PlainDateTime`, or\n * `ZonedDateTime` depending on which tokens are present.\n * \n * Value is returned as `unknown` since this package assumes no ambient `Temporal` types.\n *\n * Optionally, `options.locale` picks the calendar the result is built in. Pass a\n * locale tag with a `-u-ca-` extension (e.g. `'en-u-ca-hebrew'`) to parse\n * into a non-Gregorian calendar.\n * \n * @throws if `input` doesn't match `formatStr`'s shape at all\n * @throws if it matches the shape but escribes an impossible date (e.g. Feb 30)\n * or self-contradictory data (e.g. a weekday name that doesn't match the actual date)\n *\n * @example\n * parse('yyyy-MM-dd HH:mm', '2026-08-04 15:45') // Temporal.PlainDateTime\n * parse('yyyy-MM', '2026-08-04T15:45:30') // throws — not a valid pattern and input shape\n * parse('yyyy-MM-dd', '2026-02-30') // throws — not a real date\n */\nexport function parse(formatStr: string, input: string, options: FormatOptions = {}): unknown | undefined {\n if (formatStr.length > MAX_FORMAT_LENGTH) {\n throw new Error(\n `temporal-fmt: format string exceeds maximum length of ${MAX_FORMAT_LENGTH} characters ` +\n `(got ${formatStr.length}).`\n );\n }\n\n const locale = options.locale ?? DEFAULT_LOCALE;\n const calendar = resolveCalendar(locale);\n const pattern = getPattern(formatStr, locale);\n const match = pattern.regex.exec(input);\n if (!match) {\n throw new Error(`temporal-fmt: no valid pattern matches the format string and input shape`);\n }\n\n if (pattern.groups.length === 0) {\n throw new Error(`temporal-fmt: format string \"${formatStr}\" has no tokens — nothing to parse into a value.`);\n }\n\n const fields: Fields = {};\n for (const { name, token } of pattern.groups) {\n applyGroup(fields, token, match.groups![name]!, locale);\n }\n\n const year = resolveYear(fields);\n const hour = resolveHour(fields, formatStr);\n const { month, day, minute, second, millisecond, timeZoneId, weekdayExpected, weekdayRaw } = fields;\n\n const hasAnyDatePart = year !== undefined || month !== undefined || day !== undefined;\n const hasFullDate = year !== undefined && month !== undefined && day !== undefined;\n if (hasAnyDatePart && !hasFullDate) {\n throw new Error(\n `temporal-fmt: format string \"${formatStr}\" has an incomplete date — ` +\n `year, month, and day tokens must all be present together.`\n );\n }\n\n const hasTime = hour !== undefined || minute !== undefined || second !== undefined || millisecond !== undefined;\n\n if (timeZoneId !== undefined && !(hasFullDate && hasTime)) {\n throw new Error(\n `temporal-fmt: format string \"${formatStr}\" has a \"zzz\" token but needs a full date and time ` +\n `to build a ZonedDateTime.`\n );\n }\n\n if (weekdayExpected !== undefined && !hasFullDate) {\n throw new Error(\n `temporal-fmt: format string \"${formatStr}\" has a weekday token (\"EEEE\"/\"EEE\") but needs ` +\n `a full date to validate it against.`\n );\n }\n\n if (!hasFullDate && !hasTime) {\n // shouldn't happen — every token maps to a date, time, zone, or\n // weekday field, and weekday-without-date already threw above\n throw new Error(`temporal-fmt: format string \"${formatStr}\" has no date or time tokens to parse.`);\n }\n\n const temporal = getTemporal();\n const timeFields = { hour: hour ?? 0, minute: minute ?? 0, second: second ?? 0, millisecond: millisecond ?? 0 };\n // omitted entirely for the default calendar (see resolveCalendar) so\n // construction stays plain ISO 8601 unless a caller's locale asks for\n // something else — Temporal calendars don't apply to time-only values.\n const calendarField = calendar ? { calendar } : {};\n\n // overflow: 'reject' — without it Temporal *clamps* out-of-range fields\n // (Feb 30 silently becomes Feb 28) instead of throwing, which would\n // contradict the \"throws on genuinely invalid data\" behavior parse() promises.\n const reject = { overflow: 'reject' as const };\n\n let result: unknown;\n try {\n if (timeZoneId !== undefined) {\n result = temporal.ZonedDateTime.from({ year: year!, month: month!, day: day!, ...timeFields, ...calendarField, timeZone: timeZoneId }, reject);\n } else if (hasFullDate && hasTime) {\n result = temporal.PlainDateTime.from({ year: year!, month: month!, day: day!, ...timeFields, ...calendarField }, reject);\n } else if (hasFullDate) {\n result = temporal.PlainDate.from({ year: year!, month: month!, day: day!, ...calendarField }, reject);\n } else {\n result = temporal.PlainTime.from(timeFields, reject);\n }\n } catch (err) {\n throw new Error(\n `temporal-fmt: \"${input}\" doesn't describe a valid date/time for format \"${formatStr}\": ` +\n `${(err as Error).message}`\n );\n }\n\n if (weekdayExpected !== undefined) {\n const actual = (result as { dayOfWeek: number }).dayOfWeek;\n if (actual !== weekdayExpected) {\n const vocab = getLocaleVocab(locale);\n throw new Error(\n `temporal-fmt: \"${weekdayRaw}\" doesn't match the actual weekday (${vocab.weekdayLong[actual - 1]}) ` +\n `for the parsed date.`\n );\n }\n }\n\n return result;\n}\n"],"mappings":"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","names":["index_exports","__export","format","parse","__toCommonJS","pad","n","len","DEFAULT_LOCALE","formatterCache","MAX_CACHE_SIZE","getFormatter","locale","options","key","formatter","oldestKey","nativeSupport","intlSupportsNativeTemporal","Temporal","intlPart","temporal","partType","calendar","formatterOptions","toInstant","timeZoneId","isZoned","intlSafeTemporal","nativeOptions","part","p","dayPeriodPart","hour","date","TOKENS","t","SORTED_TOKEN_STRINGS","TOKENS","tok","a","b","tokenize","format","pieces","i","ch","appendLiteral","j","literal","closed","match","value","last","HANDLER_BY_TOKEN","TOKENS","tok","fn","field","format","temporal","formatStr","options","locale","DEFAULT_LOCALE","pieces","tokenize","result","piece","handler","vocabCache","partValue","formatter","date","type","part","p","getLocaleVocab","locale","cached","monthLongFmt","monthShortFmt","monthLong","monthShort","m","weekdayLongFmt","weekdayShortFmt","weekdayLong","weekdayShort","dayPeriodFmt","am","pm","dayPeriod","vocab","escapeRegExp","literal","alternation","values","timeZoneFragment","getTimeZoneFragment","supportedValuesOf","NUMERIC_FRAGMENTS","tokenFragment","token","locale","numeric","vocab","getLocaleVocab","escapeRegExp","literal","buildCapturingPattern","pieces","locale","groups","source","i","piece","name","tokenFragment","getTemporal","temporal","patternCache","MAX_CACHE_SIZE","getPattern","formatStr","locale","key","pattern","oldestKey","buildCapturingPattern","tokenize","calendarCache","MAX_CALENDAR_CACHE_SIZE","resolveCalendar","resolved","calendar","applyGroup","fields","token","raw","getLocaleVocab","resolveYear","resolveHour","parse","input","options","DEFAULT_LOCALE","match","name","year","hour","month","day","minute","second","millisecond","timeZoneId","weekdayExpected","weekdayRaw","hasAnyDatePart","hasFullDate","hasTime","temporal","getTemporal","timeFields","calendarField","reject","result","err","actual","vocab"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/tokens.ts","../src/tokenize.ts","../src/format.ts","../src/localeVocab.ts","../src/pattern.ts","../src/parsePattern.ts","../src/temporalGlobal.ts","../src/parse.ts"],"sourcesContent":["export { format } from './format.js';\nexport { parse } from './parse.js';\nexport type { TemporalLike, FormatOptions } from './tokens.js';","export function pad(n: number, len: number): string {\n return String(n).padStart(len, '0');\n}\n\n// Not every field exists on every Temporal type (PlainDate has no .hour,\n// etc). Callers check for undefined before formatting a token.\nexport interface TemporalLike {\n year?: number;\n month?: number;\n day?: number;\n hour?: number;\n minute?: number;\n second?: number;\n millisecond?: number;\n timeZoneId?: string;\n dayOfWeek?: number; // 1 (Mon) - 7 (Sun), per Temporal spec\n calendarId?: string;\n toInstant?: () => unknown;\n toLocaleString?: (locale: string, options: Intl.DateTimeFormatOptions) => string;\n}\n\nexport interface FormatOptions {\n /** BCP 47 locale tag, e.g. 'en-US', 'fr-FR', 'ar-EG'. Defaults to 'en-US'. */\n locale?: string;\n}\n\nexport const DEFAULT_LOCALE = 'en-US';\n\n// Intl.DateTimeFormat is expensive to construct and format() can run in a\n// loop (rendering a table of dates), so cache by (locale, options).\nconst formatterCache = new Map<string, Intl.DateTimeFormat>();\nconst MAX_CACHE_SIZE = 500;\n\nfunction getFormatter(locale: string, options: Intl.DateTimeFormatOptions): Intl.DateTimeFormat {\n const key = locale + JSON.stringify(options);\n let formatter = formatterCache.get(key);\n if (formatter) {\n return formatter;\n }\n if (formatterCache.size >= MAX_CACHE_SIZE) {\n // not real LRU, just evicts oldest insertion — fine for this key space\n const oldestKey = formatterCache.keys().next().value;\n if (oldestKey !== undefined) formatterCache.delete(oldestKey);\n }\n formatter = new Intl.DateTimeFormat(locale, options);\n formatterCache.set(key, formatter);\n return formatter;\n}\n\n// Passing a Temporal object straight into `new Intl.DateTimeFormat().formatToParts()`\n// only works when the engine's Intl implementation has special-cased support for\n// *native* Temporal instances (checked via internal slots and/or gated behind a V8 flag,\n// not tied to a specific Node version).\n// \n// A Temporal polyfill's instances don't have those slots, so the engine falls back to ToNumber() -> .valueOf(),\n// which the polyfill deliberately throws on (\"Cannot use valueOf\"). \n// Probed once and memoized and only from intlPart(), so it never\n// runs unless a format string actually uses a locale-aware token.\nlet nativeSupport: boolean | undefined;\nfunction intlSupportsNativeTemporal(): boolean {\n if (nativeSupport === undefined) {\n nativeSupport = false;\n const Temporal = (globalThis as { Temporal?: { PlainDate?: { from: (s: string) => unknown } } }).Temporal;\n if (Temporal?.PlainDate) {\n try {\n new Intl.DateTimeFormat('en-US', { day: 'numeric' }).formatToParts(Temporal.PlainDate.from('1970-01-01') as Date);\n nativeSupport = true;\n } catch {\n // native Temporal absent, or present but not recognized by Intl — fall back\n }\n }\n }\n return nativeSupport;\n}\n\nfunction intlPart(\n temporal: TemporalLike,\n locale: string,\n options: Intl.DateTimeFormatOptions,\n partType: Intl.DateTimeFormatPartTypes\n): string {\n // Intl throws \"Mismatching Calendars\" if the formatter's calendar doesn't\n // match the object's own (e.g. en-US formatter defaults to gregory, but\n // a hebrew/islamic PlainDate needs its own calendar passed through).\n //\n // skip this for iso8601 specifically — passing `calendar: 'iso8601'`\n // explicitly alongside a single-field options object makes formatToParts()\n // come back empty for some reason.\n const calendar = temporal?.calendarId;\n const formatterOptions: Intl.DateTimeFormatOptions = {\n ...options,\n ...(calendar && calendar !== 'iso8601' ? { calendar } : {}),\n };\n\n // Temporal.prototype.toLocaleString() is part of the Temporal spec itself:\n // polyfills implement the ICU formatting internally without needing the\n // engine to recognize the object, so it works without native Intl support.\n if (!intlSupportsNativeTemporal()) {\n return temporal.toLocaleString!(locale, formatterOptions);\n }\n\n // formatToParts() throws on ZonedDateTime directly (per spec), so convert\n // to Instant and pass the zone via `timeZone` instead. Don't convert to\n // PlainDateTime — that drops the zone, which breaks 'MMMM' + 'zzz' combos.\n const { toInstant, timeZoneId } = temporal;\n const isZoned = typeof toInstant === 'function' && typeof timeZoneId === 'string';\n // has to be called as temporal.toInstant() because destructuring it off breaks\n // the receiver and throws\n const intlSafeTemporal = isZoned ? temporal.toInstant!() : temporal;\n const nativeOptions: Intl.DateTimeFormatOptions = {\n ...formatterOptions,\n ...(isZoned ? { timeZone: timeZoneId } : {}),\n };\n\n const formatter = getFormatter(locale, nativeOptions);\n const parts = formatter.formatToParts(intlSafeTemporal as Date | number);\n const part = parts.find((p) => p.type === partType);\n if (!part) {\n throw new Error(\n `temporal-fmt: locale \"${locale}\" produced no \"${partType}\" part for this token. ` +\n `This usually means the Temporal object is missing the field the token needs.`\n );\n }\n return part.value;\n}\n\n\n// Temporal.prototype.toLocaleString() can't isolate a single field the way formatToParts() can\n// — asking for `hour` + `dayPeriod` together returns one joined string (e.g.\n// \"3 in the afternoon\"), and asking for `dayPeriod` alone silently resolves\n// against a different, non-hour-anchored set of periods (produces \"in the\n// afternoon\"/\"昼\" instead of the \"PM\"/\"午後\" that pairing it with hour12\n// actually renders).\n// \n// On using this instead of temporal:\n// Day period only depends on the hour, not on the calendar or the date, \n// so always route it through a plain UTC Date instead\n// Intl.DateTimeFormat has always accepted Date objects, on every engine,\n// independent of whether Temporal itself is native or polyfilled.\nfunction dayPeriodPart(hour: number, locale: string): string {\n const date = new Date(Date.UTC(1970, 0, 1, hour));\n const formatter = getFormatter(locale, { hour: 'numeric', hour12: true, timeZone: 'UTC' });\n const part = formatter.formatToParts(date).find((p) => p.type === 'dayPeriod');\n if (!part) {\n throw new Error(`temporal-fmt: locale \"${locale}\" produced no \"dayPeriod\" part for token \"a\".`);\n }\n return part.value;\n}\n\ntype TokenHandler = (t: TemporalLike, locale: string) => string;\n\n// Longest-first — tokenizer is greedy, \"yyyy\" has to be tried before \"yy\".\n//\n// Numeric tokens always render in ASCII digits, never locale-native\n// (Arabic-Indic, Devanagari, etc). Padding non-ASCII digit strings to a\n// fixed width isn't the same operation as padding \"3\", and most consumers\n// parsing these back out want plain digits anyway.\nexport const TOKENS: Array<[string, TokenHandler, keyof TemporalLike]> = [\n ['yyyy', (t) => pad(t.year!, 4), 'year'],\n ['yy', (t) => {\n // -45 % 100 === -45, so truncating negative years to 2 digits doesn't\n // work and Math.abs() would make 45 CE and 45 BCE render the same.\n if (t.year! < 0) {\n throw new Error(\n `temporal-fmt: token \"yy\" doesn't support negative years (got ${t.year}), ` +\n `since truncating to 2 digits would make it indistinguishable from a ` +\n `positive year. Use \"yyyy\" instead.`\n );\n }\n return pad(t.year! % 100, 2);\n }, 'year'],\n ['MMMM', (t, locale) => intlPart(t, locale, { month: 'long' }, 'month'), 'month'],\n ['MMM', (t, locale) => intlPart(t, locale, { month: 'short' }, 'month'), 'month'],\n ['MM', (t) => pad(t.month!, 2), 'month'],\n ['M', (t) => String(t.month!), 'month'],\n ['dd', (t) => pad(t.day!, 2), 'day'],\n ['d', (t) => String(t.day!), 'day'],\n ['EEEE', (t, locale) => intlPart(t, locale, { weekday: 'long' }, 'weekday'), 'dayOfWeek'],\n ['EEE', (t, locale) => intlPart(t, locale, { weekday: 'short' }, 'weekday'), 'dayOfWeek'],\n ['HH', (t) => pad(t.hour!, 2), 'hour'],\n ['H', (t) => String(t.hour!), 'hour'],\n ['hh', (t) => pad(t.hour! % 12 || 12, 2), 'hour'],\n ['h', (t) => String(t.hour! % 12 || 12), 'hour'],\n ['mm', (t) => pad(t.minute!, 2), 'minute'],\n ['m', (t) => String(t.minute!), 'minute'],\n ['ss', (t) => pad(t.second!, 2), 'second'],\n ['s', (t) => String(t.second!), 'second'],\n ['SSS', (t) => pad(t.millisecond!, 3), 'millisecond'],\n // dayPeriod text is locale-specific (AM/PM in en-US, م/ص in ar-EG) but\n // still needs .hour on the input to compute which period it is\n ['a', (t, locale) => dayPeriodPart(t.hour!, locale), 'hour'],\n ['zzz', (t) => t.timeZoneId!, 'timeZoneId'],\n];\n","import { TOKENS } from './tokens.js';\n\nexport type Piece =\n | { kind: 'token'; value: string }\n | { kind: 'literal'; value: string };\n\n// longest-first so the greedy scan never matches \"M\" when \"MMMM\" was there\nconst SORTED_TOKEN_STRINGS = TOKENS.map(([tok]) => tok).sort((a, b) => b.length - a.length);\n\n/**\n * Splits a format string like `\"yyyy-MM-dd 'at' HH:mm\"` into token/literal\n * pieces. Text in single quotes is always literal (e.g. write 'rd' in\n * \"3rd\" so it's not read as the day token). A doubled quote ('') means a\n * literal quote character, both inside a quoted span and standalone.\n */\nexport function tokenize(format: string): Piece[] {\n const pieces: Piece[] = [];\n let i = 0;\n\n while (i < format.length) {\n const ch = format[i];\n\n if (ch === \"'\") {\n // check doubled-quote first or \"''best''\" parses wrong\n if (format[i + 1] === \"'\") {\n appendLiteral(pieces, \"'\");\n i += 2;\n continue;\n }\n\n let j = i + 1;\n let literal = '';\n let closed = false;\n while (j < format.length) {\n if (format[j] === \"'\") {\n if (format[j + 1] === \"'\") {\n literal += \"'\";\n j += 2;\n continue;\n }\n closed = true;\n j += 1;\n break;\n }\n literal += format[j];\n j += 1;\n }\n\n if (!closed) {\n throw new Error(`temporal-fmt: unterminated quote in format string \"${format}\"`);\n }\n\n appendLiteral(pieces, literal);\n i = j;\n continue;\n }\n\n const match = SORTED_TOKEN_STRINGS.find((tok) => format.startsWith(tok, i));\n if (match) {\n pieces.push({ kind: 'token', value: match });\n i += match.length;\n continue;\n }\n\n // not a token or quote — pass through as-is \n appendLiteral(pieces, ch);\n i += 1;\n }\n\n return pieces;\n}\n\n// merges into the previous piece if it's also a literal, so \"---\" is one\n// piece instead of three\nfunction appendLiteral(pieces: Piece[], value: string): void {\n const last = pieces[pieces.length - 1];\n if (last && last.kind === 'literal') {\n last.value += value;\n } else {\n pieces.push({ kind: 'literal', value });\n }\n}\n","import { TOKENS, DEFAULT_LOCALE, type TemporalLike, type FormatOptions } from './tokens.js';\nimport { tokenize } from './tokenize.js';\nimport { MAX_FORMAT_LENGTH } from './constants.js';\n\nconst HANDLER_BY_TOKEN = new Map(TOKENS.map(([tok, fn, field]) => [tok, { fn, field }]));\n\n/**\n * Format a Temporal.PlainDate, PlainTime, PlainDateTime, or ZonedDateTime\n * using a date-fns-style token string.\n *\n * @example\n * format(Temporal.Now.plainDateISO(), 'yyyy-MM-dd') // \"2026-08-04\"\n * format(zdt, \"MMM d, yyyy 'at' h:mm a\") // \"Aug 4, 2026 at 3:45 PM\"\n * format(zdt, 'MMMM d, yyyy', { locale: 'fr-FR' }) // \"août 4, 2026\"\n * format(zdt, 'EEEE d MMMM', { locale: 'ar-EG' }) // Arabic weekday/month names\n *\n * Numeric fields always render in ASCII digits regardless of locale.\n * Named fields (MMMM, EEEE, a) are fully localized via Intl, including\n * non-Gregorian calendars if the Temporal object carries one.\n *\n * Throws if the format string uses a token the input type doesn't support\n * (e.g. 'HH' on a PlainDate) rather than silently printing \"undefined\".\n */\nexport function format(temporal: TemporalLike, formatStr: string, options: FormatOptions = {}): string {\n if (formatStr.length > MAX_FORMAT_LENGTH) {\n throw new Error(\n `temporal-fmt: format string exceeds maximum length of ${MAX_FORMAT_LENGTH} characters ` +\n `(got ${formatStr.length}).`\n );\n }\n\n const locale = options.locale ?? DEFAULT_LOCALE;\n const pieces = tokenize(formatStr);\n let result = '';\n\n for (const piece of pieces) {\n if (piece.kind === 'literal') {\n result += piece.value;\n continue;\n }\n\n const handler = HANDLER_BY_TOKEN.get(piece.value);\n if (!handler) {\n // shouldn't happen — tokenize() only emits tokens from TOKENS\n throw new Error(`temporal-fmt: unknown token \"${piece.value}\"`);\n }\n\n if (temporal[handler.field] === undefined) {\n throw new Error(\n `temporal-fmt: token \"${piece.value}\" requires \"${handler.field}\", ` +\n `which this Temporal object doesn't have. ` +\n `(e.g. PlainDate has no time fields, PlainTime has no date fields)`\n );\n }\n\n result += handler.fn(temporal, locale);\n }\n\n return result;\n}\n","// Closed-vocabulary lookups for locale-aware tokens (MMMM, MMM, EEEE, EEE, a).\n// Each set 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\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\nconst vocabCache = new Map<string, LocaleVocab>();\n\nfunction partValue(formatter: Intl.DateTimeFormat, date: Date, type: Intl.DateTimeFormatPartTypes): string {\n const part = formatter.formatToParts(date).find((p) => p.type === type);\n if (!part) {\n throw new Error(`temporal-fmt: locale produced no \"${type}\" part while building match vocabulary.`);\n }\n return part.value;\n}\n\nexport function getLocaleVocab(locale: string): LocaleVocab {\n const cached = vocabCache.get(locale);\n if (cached) {\n return cached;\n }\n\n const monthLongFmt = new Intl.DateTimeFormat(locale, { month: 'long', timeZone: 'UTC' });\n const monthShortFmt = new Intl.DateTimeFormat(locale, { 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\n const weekdayLongFmt = new Intl.DateTimeFormat(locale, { weekday: 'long', timeZone: 'UTC' });\n const weekdayShortFmt = new Intl.DateTimeFormat(locale, { 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\n const dayPeriodFmt = new Intl.DateTimeFormat(locale, { 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 vocabCache.set(locale, vocab);\n return vocab;\n}\n","import { getLocaleVocab } from './localeVocab.js';\n\nfunction escapeRegExp(literal: string): string {\n return literal.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nfunction alternation(values: string[]): string {\n return `(?:${values.map(escapeRegExp).join('|')})`;\n}\n\nlet timeZoneFragment: string | undefined;\n\nfunction getTimeZoneFragment(): string {\n if (timeZoneFragment) {\n return timeZoneFragment;\n }\n const supportedValuesOf = (Intl as unknown as { supportedValuesOf?: (key: string) => string[] }).supportedValuesOf;\n if (typeof supportedValuesOf === 'function') {\n // supportedValuesOf('timeZone') leaves out 'UTC', but format() can\n // produce it from a real ZonedDateTime — without this, parse() couldn't\n // parse our own library's own output back.\n timeZoneFragment = alternation([...supportedValuesOf('timeZone'), 'UTC']);\n } else {\n // no Intl.supportedValuesOf — match on shape only\n timeZoneFragment = '[A-Za-z_]+(?:\\\\/[A-Za-z_+\\\\-0-9]+)+|UTC';\n }\n return timeZoneFragment;\n}\n\n// mirrors the ranges pad() in tokens.ts actually produces — keep in sync\n// if those ever change\nconst NUMERIC_FRAGMENTS: Record<string, string> = {\n yyyy: '\\\\d{4}',\n yy: '\\\\d{2}',\n MM: '(?:0[1-9]|1[0-2])',\n M: '(?:[1-9]|1[0-2])',\n dd: '(?:0[1-9]|[12]\\\\d|3[01])',\n d: '(?:[1-9]|[12]\\\\d|3[01])',\n HH: '(?:[01]\\\\d|2[0-3])',\n H: '(?:[0-9]|1\\\\d|2[0-3])',\n hh: '(?:0[1-9]|1[0-2])',\n h: '(?:[1-9]|1[0-2])',\n mm: '(?:[0-5]\\\\d)',\n m: '(?:[0-9]|[1-5]\\\\d)',\n ss: '(?:[0-5]\\\\d)',\n s: '(?:[0-9]|[1-5]\\\\d)',\n SSS: '\\\\d{3}',\n};\n\nexport function tokenFragment(token: string, locale: string): string {\n const numeric = NUMERIC_FRAGMENTS[token];\n if (numeric) {\n return numeric;\n }\n\n const vocab = getLocaleVocab(locale);\n switch (token) {\n case 'MMMM': return alternation(vocab.monthLong);\n case 'MMM': return alternation(vocab.monthShort);\n case 'EEEE': return alternation(vocab.weekdayLong);\n case 'EEE': return alternation(vocab.weekdayShort);\n case 'a': return alternation(vocab.dayPeriod);\n case 'zzz': return getTimeZoneFragment();\n default:\n throw new Error(`temporal-fmt: unknown token \"${token}\"`);\n }\n}\n","import type { Piece } from './tokenize.js';\nimport { tokenFragment } from './pattern.js';\n\nfunction escapeRegExp(literal: string): string {\n return literal.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nexport interface CapturingPattern {\n regex: RegExp;\n groups: Array<{ name: string; token: string }>; // token pieces, in order\n}\n\n/**\n * Same walk as buildPatternSource() in pattern.ts, but each token piece\n * gets its own named capture group (positionally named so the same token,\n * e.g. \"yyyy\", could in theory appear twice) so a caller can pull the\n * matched substring for each token back out after a successful match.\n */\nexport function buildCapturingPattern(pieces: Piece[], locale: string): CapturingPattern {\n const groups: Array<{ name: string; token: string }> = [];\n let source = '';\n let i = 0;\n\n for (const piece of pieces) {\n if (piece.kind === 'literal') {\n source += escapeRegExp(piece.value);\n continue;\n }\n const name = `g${i++}`;\n groups.push({ name, token: piece.value });\n source += `(?<${name}>${tokenFragment(piece.value, locale)})`;\n }\n\n return { regex: new RegExp(`^(?:${source})$`, 'u'), groups };\n}\n","// This package's tsconfig assumes lib: [\"ESNext\"] only — no ambient\n// `Temporal` namespace type. Everywhere else in this codebase only ever\n// *reads* fields off a Temporal-like object the caller already built\n// (TemporalLike in tokens.ts). parse() is the first place that needs to\n// *construct* one, via the global `Temporal` the README already requires\n// consumers to provide (native on Node 26+, or a polyfill). Kept loosely\n// typed on purpose, consistent with the rest of the codebase.\ninterface TemporalFactory {\n from(fields: Record<string, number | string | undefined>, options?: { overflow?: 'constrain' | 'reject' }): unknown;\n}\n\nexport interface TemporalNamespace {\n PlainDate: TemporalFactory;\n PlainTime: TemporalFactory;\n PlainDateTime: TemporalFactory;\n ZonedDateTime: TemporalFactory;\n}\n\nexport function getTemporal(): TemporalNamespace {\n const temporal = (globalThis as unknown as { Temporal?: TemporalNamespace }).Temporal;\n if (!temporal) {\n throw new Error(\n 'temporal-fmt: parse() needs a global `Temporal` to construct its result. ' +\n 'Native on Node 26+, or assign a polyfill (e.g. temporal-polyfill) to globalThis.Temporal first.'\n );\n }\n return temporal;\n}\n","import { DEFAULT_LOCALE, type FormatOptions } from './tokens.js';\nimport { tokenize } from './tokenize.js';\nimport { buildCapturingPattern, type CapturingPattern } from './parsePattern.js';\nimport { getLocaleVocab } from './localeVocab.js';\nimport { getTemporal } from './temporalGlobal.js';\nimport { MAX_FORMAT_LENGTH } from './constants.js';\n\n// format strings are short hand-written literals reused across many calls —\n// cache the compiled capturing pattern per (formatStr, locale) pair instead\n// of rebuilding it every call.\nconst patternCache = new Map<string, CapturingPattern>();\nconst MAX_CACHE_SIZE = 500;\n\nfunction getPattern(formatStr: string, locale: string): CapturingPattern {\n const key = locale + ' ' + formatStr;\n let pattern = patternCache.get(key);\n if (pattern) {\n return pattern;\n }\n if (patternCache.size >= MAX_CACHE_SIZE) {\n const oldestKey = patternCache.keys().next().value;\n if (oldestKey !== undefined) patternCache.delete(oldestKey);\n }\n pattern = buildCapturingPattern(tokenize(formatStr), locale);\n patternCache.set(key, pattern);\n return pattern;\n}\n\n// Intl.DateTimeFormat(locale).resolvedOptions().calendar reports the\n// locale's default calendar so passing locale with a `-u-ca-` extension in the tag\n// allows setting non-gregorian calendars. 'gregory' is treated as \"no calendar\" so\n// the default locale ('en-US') keeps constructing plain ISO 8601\nconst calendarCache = new Map<string, string | undefined>();\nconst MAX_CALENDAR_CACHE_SIZE = 500;\n\nfunction resolveCalendar(locale: string): string | undefined {\n if (calendarCache.has(locale)) {\n return calendarCache.get(locale);\n }\n if (calendarCache.size >= MAX_CALENDAR_CACHE_SIZE) {\n const oldestKey = calendarCache.keys().next().value;\n if (oldestKey !== undefined) calendarCache.delete(oldestKey);\n }\n const resolved = new Intl.DateTimeFormat(locale).resolvedOptions().calendar;\n const calendar = resolved === 'gregory' ? undefined : resolved;\n calendarCache.set(locale, calendar);\n return calendar;\n}\n\ninterface Fields {\n year?: number;\n twoDigitYear?: number;\n month?: number;\n day?: number;\n hour?: number;\n hour12?: number;\n isPM?: boolean;\n minute?: number;\n second?: number;\n millisecond?: number;\n timeZoneId?: string;\n weekdayExpected?: number; // ISO dayOfWeek, 1 (Mon) - 7 (Sun)\n weekdayRaw?: string;\n}\n\nfunction applyGroup(fields: Fields, token: string, raw: string, locale: string): void {\n switch (token) {\n case 'yyyy': fields.year = parseInt(raw, 10); break;\n case 'yy': fields.twoDigitYear = parseInt(raw, 10); break;\n case 'MM': case 'M': fields.month = parseInt(raw, 10); break;\n case 'MMMM': fields.month = getLocaleVocab(locale).monthLong.indexOf(raw) + 1; break;\n case 'MMM': fields.month = getLocaleVocab(locale).monthShort.indexOf(raw) + 1; break;\n case 'dd': case 'd': fields.day = parseInt(raw, 10); break;\n case 'EEEE':\n fields.weekdayRaw = raw;\n fields.weekdayExpected = getLocaleVocab(locale).weekdayLong.indexOf(raw) + 1;\n break;\n case 'EEE':\n fields.weekdayRaw = raw;\n fields.weekdayExpected = getLocaleVocab(locale).weekdayShort.indexOf(raw) + 1;\n break;\n case 'HH': case 'H': fields.hour = parseInt(raw, 10); break;\n case 'hh': case 'h': fields.hour12 = parseInt(raw, 10); break;\n case 'mm': case 'm': fields.minute = parseInt(raw, 10); break;\n case 'ss': case 's': fields.second = parseInt(raw, 10); break;\n case 'SSS': fields.millisecond = parseInt(raw, 10); break;\n case 'a': fields.isPM = raw === getLocaleVocab(locale).dayPeriod[1]; break;\n case 'zzz': fields.timeZoneId = raw; break;\n }\n}\n\n/**\n * Resolves year value into 4-digit year\n * \n * For 2-digit values it emulates strptime (POSIX)\n * so that resolving value is not clock-dependent\n * \n * * 00-68 -> 2000-2068\n * * 69-99 -> 1900-1999\n * \n * @see https://www.man7.org/linux//man-pages/man3/strptime.3p.html\n */\nfunction resolveYear(fields: Fields): number | undefined {\n if (fields.year !== undefined) return fields.year;\n if (fields.twoDigitYear !== undefined) {\n return fields.twoDigitYear <= 68 ? 2000 + fields.twoDigitYear : 1900 + fields.twoDigitYear;\n }\n return undefined;\n}\n\nfunction resolveHour(fields: Fields, formatStr: string): number | undefined {\n if (fields.hour !== undefined && fields.hour12 !== undefined) {\n throw new Error(\n `temporal-fmt: format string \"${formatStr}\" mixes a 24-hour token (\"HH\"/\"H\") with a ` +\n `12-hour token (\"hh\"/\"h\"). Pick one or the other — parse() won't guess which is authoritative.`\n );\n }\n if (fields.hour !== undefined) return fields.hour;\n if (fields.hour12 !== undefined) {\n if (fields.isPM === undefined) {\n throw new Error(\n `temporal-fmt: format string \"${formatStr}\" uses a 12-hour token (\"hh\"/\"h\") without an \"a\" token, ` +\n `so parse() can't tell AM from PM.`\n );\n }\n return (fields.hour12 % 12) + (fields.isPM ? 12 : 0);\n }\n return undefined;\n}\n\n/**\n * Parses `input` against `formatStr` and builds the real Temporal value it\n * describes: a `Temporal.PlainDate`, `PlainTime`, `PlainDateTime`, or\n * `ZonedDateTime` depending on which tokens are present.\n * \n * Value is returned as `unknown` since this package assumes no ambient `Temporal` types.\n *\n * Optionally, `options.locale` picks the calendar the result is built in. Pass a\n * locale tag with a `-u-ca-` extension (e.g. `'en-u-ca-hebrew'`) to parse\n * into a non-Gregorian calendar.\n * \n * @throws if `input` doesn't match `formatStr`'s shape at all\n * @throws if it matches the shape but escribes an impossible date (e.g. Feb 30)\n * or self-contradictory data (e.g. a weekday name that doesn't match the actual date)\n *\n * @example\n * parse('yyyy-MM-dd HH:mm', '2026-08-04 15:45') // Temporal.PlainDateTime\n * parse('yyyy-MM', '2026-08-04T15:45:30') // throws — not a valid pattern and input shape\n * parse('yyyy-MM-dd', '2026-02-30') // throws — not a real date\n */\nexport function parse(formatStr: string, input: string, options: FormatOptions = {}): unknown | undefined {\n if (formatStr.length > MAX_FORMAT_LENGTH) {\n throw new Error(\n `temporal-fmt: format string exceeds maximum length of ${MAX_FORMAT_LENGTH} characters ` +\n `(got ${formatStr.length}).`\n );\n }\n\n const locale = options.locale ?? DEFAULT_LOCALE;\n const calendar = resolveCalendar(locale);\n const pattern = getPattern(formatStr, locale);\n const match = pattern.regex.exec(input);\n if (!match) {\n throw new Error(`temporal-fmt: no valid pattern matches the format string and input shape`);\n }\n\n if (pattern.groups.length === 0) {\n throw new Error(`temporal-fmt: format string \"${formatStr}\" has no tokens — nothing to parse into a value.`);\n }\n\n const fields: Fields = {};\n for (const { name, token } of pattern.groups) {\n applyGroup(fields, token, match.groups![name]!, locale);\n }\n\n const year = resolveYear(fields);\n const hour = resolveHour(fields, formatStr);\n const { month, day, minute, second, millisecond, timeZoneId, weekdayExpected, weekdayRaw } = fields;\n\n const hasAnyDatePart = year !== undefined || month !== undefined || day !== undefined;\n const hasFullDate = year !== undefined && month !== undefined && day !== undefined;\n if (hasAnyDatePart && !hasFullDate) {\n throw new Error(\n `temporal-fmt: format string \"${formatStr}\" has an incomplete date — ` +\n `year, month, and day tokens must all be present together.`\n );\n }\n\n const hasTime = hour !== undefined || minute !== undefined || second !== undefined || millisecond !== undefined;\n\n if (timeZoneId !== undefined && !(hasFullDate && hasTime)) {\n throw new Error(\n `temporal-fmt: format string \"${formatStr}\" has a \"zzz\" token but needs a full date and time ` +\n `to build a ZonedDateTime.`\n );\n }\n\n if (weekdayExpected !== undefined && !hasFullDate) {\n throw new Error(\n `temporal-fmt: format string \"${formatStr}\" has a weekday token (\"EEEE\"/\"EEE\") but needs ` +\n `a full date to validate it against.`\n );\n }\n\n if (!hasFullDate && !hasTime) {\n // shouldn't happen — every token maps to a date, time, zone, or\n // weekday field, and weekday-without-date already threw above\n throw new Error(`temporal-fmt: format string \"${formatStr}\" has no date or time tokens to parse.`);\n }\n\n const temporal = getTemporal();\n const timeFields = { hour: hour ?? 0, minute: minute ?? 0, second: second ?? 0, millisecond: millisecond ?? 0 };\n // omitted entirely for the default calendar (see resolveCalendar) so\n // construction stays plain ISO 8601 unless a caller's locale asks for\n // something else — Temporal calendars don't apply to time-only values.\n const calendarField = calendar ? { calendar } : {};\n\n // overflow: 'reject' — without it Temporal *clamps* out-of-range fields\n // (Feb 30 silently becomes Feb 28) instead of throwing, which would\n // contradict the \"throws on genuinely invalid data\" behavior parse() promises.\n const reject = { overflow: 'reject' as const };\n\n let result: unknown;\n try {\n if (timeZoneId !== undefined) {\n result = temporal.ZonedDateTime.from({ year: year!, month: month!, day: day!, ...timeFields, ...calendarField, timeZone: timeZoneId }, reject);\n } else if (hasFullDate && hasTime) {\n result = temporal.PlainDateTime.from({ year: year!, month: month!, day: day!, ...timeFields, ...calendarField }, reject);\n } else if (hasFullDate) {\n result = temporal.PlainDate.from({ year: year!, month: month!, day: day!, ...calendarField }, reject);\n } else {\n result = temporal.PlainTime.from(timeFields, reject);\n }\n } catch (err) {\n throw new Error(\n `temporal-fmt: \"${input}\" doesn't describe a valid date/time for format \"${formatStr}\": ` +\n `${(err as Error).message}`\n );\n }\n\n if (weekdayExpected !== undefined) {\n const actual = (result as { dayOfWeek: number }).dayOfWeek;\n if (actual !== weekdayExpected) {\n const vocab = getLocaleVocab(locale);\n throw new Error(\n `temporal-fmt: \"${weekdayRaw}\" doesn't match the actual weekday (${vocab.weekdayLong[actual - 1]}) ` +\n `for the parsed date.`\n );\n }\n }\n\n return result;\n}\n"],"mappings":"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","names":["index_exports","__export","format","parse","__toCommonJS","pad","n","len","DEFAULT_LOCALE","formatterCache","MAX_CACHE_SIZE","getFormatter","locale","options","key","formatter","oldestKey","nativeSupport","intlSupportsNativeTemporal","Temporal","intlPart","temporal","partType","calendar","formatterOptions","toInstant","timeZoneId","isZoned","intlSafeTemporal","nativeOptions","part","p","dayPeriodPart","hour","date","TOKENS","t","SORTED_TOKEN_STRINGS","TOKENS","tok","a","b","tokenize","format","pieces","i","ch","appendLiteral","j","literal","closed","match","value","last","HANDLER_BY_TOKEN","TOKENS","tok","fn","field","format","temporal","formatStr","options","locale","DEFAULT_LOCALE","pieces","tokenize","result","piece","handler","vocabCache","partValue","formatter","date","type","part","p","getLocaleVocab","locale","cached","monthLongFmt","monthShortFmt","monthLong","monthShort","m","weekdayLongFmt","weekdayShortFmt","weekdayLong","weekdayShort","dayPeriodFmt","am","pm","dayPeriod","vocab","escapeRegExp","literal","alternation","values","timeZoneFragment","getTimeZoneFragment","supportedValuesOf","NUMERIC_FRAGMENTS","tokenFragment","token","locale","numeric","vocab","getLocaleVocab","escapeRegExp","literal","buildCapturingPattern","pieces","locale","groups","source","i","piece","name","tokenFragment","getTemporal","temporal","patternCache","MAX_CACHE_SIZE","getPattern","formatStr","locale","key","pattern","oldestKey","buildCapturingPattern","tokenize","calendarCache","MAX_CALENDAR_CACHE_SIZE","resolveCalendar","resolved","calendar","applyGroup","fields","token","raw","getLocaleVocab","resolveYear","resolveHour","parse","input","options","DEFAULT_LOCALE","match","name","year","hour","month","day","minute","second","millisecond","timeZoneId","weekdayExpected","weekdayRaw","hasAnyDatePart","hasFullDate","hasTime","temporal","getTemporal","timeFields","calendarField","reject","result","err","actual","vocab"]}
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- function l(e,n){return String(e).padStart(n,"0")}var C="en-US",M=new Map,G=500;function H(e,n){let t=e+JSON.stringify(n),r=M.get(t);if(r)return r;if(M.size>=G){let a=M.keys().next().value;a!==void 0&&M.delete(a)}return r=new Intl.DateTimeFormat(e,n),M.set(t,r),r}var L;function X(){if(L===void 0){L=!1;let e=globalThis.Temporal;if(e?.PlainDate)try{new Intl.DateTimeFormat("en-US",{day:"numeric"}).formatToParts(e.PlainDate.from("1970-01-01")),L=!0}catch{}}return L}function O(e,n,t,r){let a=e?.calendarId,o={...t,...a&&a!=="iso8601"?{calendar:a}:{}};if(!X())return e.toLocaleString(n,o);let{toInstant:i,timeZoneId:s}=e,m=typeof i=="function"&&typeof s=="string",g=m?e.toInstant():e,u={...o,...m?{timeZone:s}:{}},h=H(n,u).formatToParts(g).find(y=>y.type===r);if(!h)throw new Error(`temporal-fmt: locale "${n}" produced no "${r}" part for this token. This usually means the Temporal object is missing the field the token needs.`);return h.value}function q(e,n){let t=new Date(Date.UTC(1970,0,1,e)),a=H(n,{hour:"numeric",hour12:!0,timeZone:"UTC"}).formatToParts(t).find(o=>o.type==="dayPeriod");if(!a)throw new Error(`temporal-fmt: locale "${n}" produced no "dayPeriod" part for token "a".`);return a.value}var $=[["yyyy",e=>l(e.year,4),"year"],["yy",e=>{if(e.year<0)throw new Error(`temporal-fmt: token "yy" doesn't support negative years (got ${e.year}), since truncating to 2 digits would make it indistinguishable from a positive year. Use "yyyy" instead.`);return l(e.year%100,2)},"year"],["MMMM",(e,n)=>O(e,n,{month:"long"},"month"),"month"],["MMM",(e,n)=>O(e,n,{month:"short"},"month"),"month"],["MM",e=>l(e.month,2),"month"],["M",e=>String(e.month),"month"],["dd",e=>l(e.day,2),"day"],["d",e=>String(e.day),"day"],["EEEE",(e,n)=>O(e,n,{weekday:"long"},"weekday"),"dayOfWeek"],["EEE",(e,n)=>O(e,n,{weekday:"short"},"weekday"),"dayOfWeek"],["HH",e=>l(e.hour,2),"hour"],["H",e=>String(e.hour),"hour"],["hh",e=>l(e.hour%12||12,2),"hour"],["h",e=>String(e.hour%12||12),"hour"],["mm",e=>l(e.minute,2),"minute"],["m",e=>String(e.minute),"minute"],["ss",e=>l(e.second,2),"second"],["s",e=>String(e.second),"second"],["SSS",e=>l(e.millisecond,3),"millisecond"],["a",(e,n)=>q(e.hour,n),"hour"],["zzz",e=>e.timeZoneId,"timeZoneId"]];var B=$.map(([e])=>e).sort((e,n)=>n.length-e.length);function S(e){let n=[],t=0;for(;t<e.length;){let r=e[t];if(r==="'"){if(e[t+1]==="'"){U(n,"'"),t+=2;continue}let o=t+1,i="",s=!1;for(;o<e.length;){if(e[o]==="'"){if(e[o+1]==="'"){i+="'",o+=2;continue}s=!0,o+=1;break}i+=e[o],o+=1}if(!s)throw new Error(`temporal-fmt: unterminated quote in format string "${e}"`);U(n,i),t=o;continue}let a=B.find(o=>e.startsWith(o,t));if(a){n.push({kind:"token",value:a}),t+=a.length;continue}U(n,r),t+=1}return n}function U(e,n){let t=e[e.length-1];t&&t.kind==="literal"?t.value+=n:e.push({kind:"literal",value:n})}var J=new Map($.map(([e,n,t])=>[e,{fn:n,field:t}]));function Q(e,n,t={}){if(n.length>1e3)throw new Error(`temporal-fmt: format string exceeds maximum length of ${1e3} characters (got ${n.length}).`);let r=t.locale??C,a=S(n),o="";for(let i of a){if(i.kind==="literal"){o+=i.value;continue}let s=J.get(i.value);if(!s)throw new Error(`temporal-fmt: unknown token "${i.value}"`);if(e[s.field]===void 0)throw new Error(`temporal-fmt: token "${i.value}" requires "${s.field}", which this Temporal object doesn't have. (e.g. PlainDate has no time fields, PlainTime has no date fields)`);o+=s.fn(e,r)}return o}var R=new Map;function E(e,n,t){let r=e.formatToParts(n).find(a=>a.type===t);if(!r)throw new Error(`temporal-fmt: locale produced no "${t}" part while building match vocabulary.`);return r.value}function p(e){let n=R.get(e);if(n)return n;let t=new Intl.DateTimeFormat(e,{month:"long",timeZone:"UTC"}),r=new Intl.DateTimeFormat(e,{month:"short",timeZone:"UTC"}),a=[],o=[];for(let d=0;d<12;d++){let c=new Date(Date.UTC(2020,d,1));a.push(E(t,c,"month")),o.push(E(r,c,"month"))}let i=new Intl.DateTimeFormat(e,{weekday:"long",timeZone:"UTC"}),s=new Intl.DateTimeFormat(e,{weekday:"short",timeZone:"UTC"}),m=[],g=[];for(let d=0;d<7;d++){let c=new Date(Date.UTC(2024,0,1+d));m.push(E(i,c,"weekday")),g.push(E(s,c,"weekday"))}let u=new Intl.DateTimeFormat(e,{hour:"numeric",hour12:!0,timeZone:"UTC"}),f=E(u,new Date(Date.UTC(2020,0,1,1)),"dayPeriod"),F=E(u,new Date(Date.UTC(2020,0,1,13)),"dayPeriod"),h=[...new Set([f,F])],y={monthLong:a,monthShort:o,weekdayLong:m,weekdayShort:g,dayPeriod:h};return R.set(e,y),y}function ee(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function b(e){return`(?:${e.map(ee).join("|")})`}var P;function te(){if(P)return P;let e=Intl.supportedValuesOf;return typeof e=="function"?P=b([...e("timeZone"),"UTC"]):P="[A-Za-z_]+(?:\\/[A-Za-z_+\\-0-9]+)+|UTC",P}var ne={yyyy:"\\d{4}",yy:"\\d{2}",MM:"(?:0[1-9]|1[0-2])",M:"(?:[1-9]|1[0-2])",dd:"(?:0[1-9]|[12]\\d|3[01])",d:"(?:[1-9]|[12]\\d|3[01])",HH:"(?:[01]\\d|2[0-3])",H:"(?:[0-9]|1\\d|2[0-3])",hh:"(?:0[1-9]|1[0-2])",h:"(?:[1-9]|1[0-2])",mm:"(?:[0-5]\\d)",m:"(?:[0-9]|[1-5]\\d)",ss:"(?:[0-5]\\d)",s:"(?:[0-9]|[1-5]\\d)",SSS:"\\d{3}"};function V(e,n){let t=ne[e];if(t)return t;let r=p(n);switch(e){case"MMMM":return b(r.monthLong);case"MMM":return b(r.monthShort);case"EEEE":return b(r.weekdayLong);case"EEE":return b(r.weekdayShort);case"a":return b(r.dayPeriod);case"zzz":return te();default:throw new Error(`temporal-fmt: unknown token "${e}"`)}}function re(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function j(e,n){let t=[],r="",a=0;for(let o of e){if(o.kind==="literal"){r+=re(o.value);continue}let i=`g${a++}`;t.push({name:i,token:o.value}),r+=`(?<${i}>${V(o.value,n)})`}return{regex:new RegExp(`^(?:${r})$`,"u"),groups:t}}function K(){let e=globalThis.Temporal;if(!e)throw new Error("temporal-fmt: parse() needs a global `Temporal` to construct its result. Native on Node 26+, or assign a polyfill (e.g. temporal-polyfill) to globalThis.Temporal first.");return e}var I=new Map,oe=500;function ae(e,n){let t=n+" "+e,r=I.get(t);if(r)return r;if(I.size>=oe){let a=I.keys().next().value;a!==void 0&&I.delete(a)}return r=j(S(e),n),I.set(t,r),r}var D=new Map,ie=500;function se(e){if(D.has(e))return D.get(e);if(D.size>=ie){let r=D.keys().next().value;r!==void 0&&D.delete(r)}let n=new Intl.DateTimeFormat(e).resolvedOptions().calendar,t=n==="gregory"?void 0:n;return D.set(e,t),t}function me(e,n,t,r){switch(n){case"yyyy":e.year=parseInt(t,10);break;case"yy":e.twoDigitYear=parseInt(t,10);break;case"MM":case"M":e.month=parseInt(t,10);break;case"MMMM":e.month=p(r).monthLong.indexOf(t)+1;break;case"MMM":e.month=p(r).monthShort.indexOf(t)+1;break;case"dd":case"d":e.day=parseInt(t,10);break;case"EEEE":e.weekdayRaw=t,e.weekdayExpected=p(r).weekdayLong.indexOf(t)+1;break;case"EEE":e.weekdayRaw=t,e.weekdayExpected=p(r).weekdayShort.indexOf(t)+1;break;case"HH":case"H":e.hour=parseInt(t,10);break;case"hh":case"h":e.hour12=parseInt(t,10);break;case"mm":case"m":e.minute=parseInt(t,10);break;case"ss":case"s":e.second=parseInt(t,10);break;case"SSS":e.millisecond=parseInt(t,10);break;case"a":e.isPM=t===p(r).dayPeriod[1];break;case"zzz":e.timeZoneId=t;break}}function de(e){if(e.year!==void 0)return e.year;if(e.twoDigitYear!==void 0)return e.twoDigitYear<=68?2e3+e.twoDigitYear:1900+e.twoDigitYear}function ue(e,n){if(e.hour!==void 0)return e.hour;if(e.hour12!==void 0){if(e.isPM===void 0)throw new Error(`temporal-fmt: format string "${n}" uses a 12-hour token ("hh"/"h") without an "a" token, so parse() can't tell AM from PM.`);return e.hour12%12+(e.isPM?12:0)}}function ce(e,n,t={}){if(e.length>1e3)throw new Error(`temporal-fmt: format string exceeds maximum length of ${1e3} characters (got ${e.length}).`);let r=t.locale??C,a=se(r),o=ae(e,r),i=o.regex.exec(n);if(!i)throw new Error("temporal-fmt: no valid pattern matches the format string and input shape");if(o.groups.length===0)throw new Error(`temporal-fmt: format string "${e}" has no tokens \u2014 nothing to parse into a value.`);let s={};for(let{name:T,token:_}of o.groups)me(s,_,i.groups[T],r);let m=de(s),g=ue(s,e),{month:u,day:f,minute:F,second:h,millisecond:y,timeZoneId:d,weekdayExpected:c,weekdayRaw:Y}=s,W=m!==void 0||u!==void 0||f!==void 0,k=m!==void 0&&u!==void 0&&f!==void 0;if(W&&!k)throw new Error(`temporal-fmt: format string "${e}" has an incomplete date \u2014 year, month, and day tokens must all be present together.`);let A=g!==void 0||F!==void 0||h!==void 0||y!==void 0;if(d!==void 0&&!(k&&A))throw new Error(`temporal-fmt: format string "${e}" has a "zzz" token but needs a full date and time to build a ZonedDateTime.`);if(c!==void 0&&!k)throw new Error(`temporal-fmt: format string "${e}" has a weekday token ("EEEE"/"EEE") but needs a full date to validate it against.`);if(!k&&!A)throw new Error(`temporal-fmt: format string "${e}" has no date or time tokens to parse.`);let x=K(),Z={hour:g??0,minute:F??0,second:h??0,millisecond:y??0},z=a?{calendar:a}:{},v={overflow:"reject"},w;try{d!==void 0?w=x.ZonedDateTime.from({year:m,month:u,day:f,...Z,...z,timeZone:d},v):k&&A?w=x.PlainDateTime.from({year:m,month:u,day:f,...Z,...z},v):k?w=x.PlainDate.from({year:m,month:u,day:f,...z},v):w=x.PlainTime.from(Z,v)}catch(T){throw new Error(`temporal-fmt: "${n}" doesn't describe a valid date/time for format "${e}": ${T.message}`)}if(c!==void 0){let T=w.dayOfWeek;if(T!==c){let _=p(r);throw new Error(`temporal-fmt: "${Y}" doesn't match the actual weekday (${_.weekdayLong[T-1]}) for the parsed date.`)}}return w}export{Q as format,ce as parse};
1
+ function l(e,t){return String(e).padStart(t,"0")}var C="en-US",M=new Map,G=500;function N(e,t){let n=e+JSON.stringify(t),r=M.get(n);if(r)return r;if(M.size>=G){let a=M.keys().next().value;a!==void 0&&M.delete(a)}return r=new Intl.DateTimeFormat(e,t),M.set(n,r),r}var L;function X(){if(L===void 0){L=!1;let e=globalThis.Temporal;if(e?.PlainDate)try{new Intl.DateTimeFormat("en-US",{day:"numeric"}).formatToParts(e.PlainDate.from("1970-01-01")),L=!0}catch{}}return L}function O(e,t,n,r){let a=e?.calendarId,o={...n,...a&&a!=="iso8601"?{calendar:a}:{}};if(!X())return e.toLocaleString(t,o);let{toInstant:i,timeZoneId:s}=e,m=typeof i=="function"&&typeof s=="string",h=m?e.toInstant():e,u={...o,...m?{timeZone:s}:{}},g=N(t,u).formatToParts(h).find(y=>y.type===r);if(!g)throw new Error(`temporal-fmt: locale "${t}" produced no "${r}" part for this token. This usually means the Temporal object is missing the field the token needs.`);return g.value}function q(e,t){let n=new Date(Date.UTC(1970,0,1,e)),a=N(t,{hour:"numeric",hour12:!0,timeZone:"UTC"}).formatToParts(n).find(o=>o.type==="dayPeriod");if(!a)throw new Error(`temporal-fmt: locale "${t}" produced no "dayPeriod" part for token "a".`);return a.value}var $=[["yyyy",e=>l(e.year,4),"year"],["yy",e=>{if(e.year<0)throw new Error(`temporal-fmt: token "yy" doesn't support negative years (got ${e.year}), since truncating to 2 digits would make it indistinguishable from a positive year. Use "yyyy" instead.`);return l(e.year%100,2)},"year"],["MMMM",(e,t)=>O(e,t,{month:"long"},"month"),"month"],["MMM",(e,t)=>O(e,t,{month:"short"},"month"),"month"],["MM",e=>l(e.month,2),"month"],["M",e=>String(e.month),"month"],["dd",e=>l(e.day,2),"day"],["d",e=>String(e.day),"day"],["EEEE",(e,t)=>O(e,t,{weekday:"long"},"weekday"),"dayOfWeek"],["EEE",(e,t)=>O(e,t,{weekday:"short"},"weekday"),"dayOfWeek"],["HH",e=>l(e.hour,2),"hour"],["H",e=>String(e.hour),"hour"],["hh",e=>l(e.hour%12||12,2),"hour"],["h",e=>String(e.hour%12||12),"hour"],["mm",e=>l(e.minute,2),"minute"],["m",e=>String(e.minute),"minute"],["ss",e=>l(e.second,2),"second"],["s",e=>String(e.second),"second"],["SSS",e=>l(e.millisecond,3),"millisecond"],["a",(e,t)=>q(e.hour,t),"hour"],["zzz",e=>e.timeZoneId,"timeZoneId"]];var B=$.map(([e])=>e).sort((e,t)=>t.length-e.length);function S(e){let t=[],n=0;for(;n<e.length;){let r=e[n];if(r==="'"){if(e[n+1]==="'"){_(t,"'"),n+=2;continue}let o=n+1,i="",s=!1;for(;o<e.length;){if(e[o]==="'"){if(e[o+1]==="'"){i+="'",o+=2;continue}s=!0,o+=1;break}i+=e[o],o+=1}if(!s)throw new Error(`temporal-fmt: unterminated quote in format string "${e}"`);_(t,i),n=o;continue}let a=B.find(o=>e.startsWith(o,n));if(a){t.push({kind:"token",value:a}),n+=a.length;continue}_(t,r),n+=1}return t}function _(e,t){let n=e[e.length-1];n&&n.kind==="literal"?n.value+=t:e.push({kind:"literal",value:t})}var J=new Map($.map(([e,t,n])=>[e,{fn:t,field:n}]));function Q(e,t,n={}){if(t.length>1e3)throw new Error(`temporal-fmt: format string exceeds maximum length of ${1e3} characters (got ${t.length}).`);let r=n.locale??C,a=S(t),o="";for(let i of a){if(i.kind==="literal"){o+=i.value;continue}let s=J.get(i.value);if(!s)throw new Error(`temporal-fmt: unknown token "${i.value}"`);if(e[s.field]===void 0)throw new Error(`temporal-fmt: token "${i.value}" requires "${s.field}", which this Temporal object doesn't have. (e.g. PlainDate has no time fields, PlainTime has no date fields)`);o+=s.fn(e,r)}return o}var R=new Map;function E(e,t,n){let r=e.formatToParts(t).find(a=>a.type===n);if(!r)throw new Error(`temporal-fmt: locale produced no "${n}" part while building match vocabulary.`);return r.value}function p(e){let t=R.get(e);if(t)return t;let n=new Intl.DateTimeFormat(e,{month:"long",timeZone:"UTC"}),r=new Intl.DateTimeFormat(e,{month:"short",timeZone:"UTC"}),a=[],o=[];for(let d=0;d<12;d++){let c=new Date(Date.UTC(2020,d,1));a.push(E(n,c,"month")),o.push(E(r,c,"month"))}let i=new Intl.DateTimeFormat(e,{weekday:"long",timeZone:"UTC"}),s=new Intl.DateTimeFormat(e,{weekday:"short",timeZone:"UTC"}),m=[],h=[];for(let d=0;d<7;d++){let c=new Date(Date.UTC(2024,0,1+d));m.push(E(i,c,"weekday")),h.push(E(s,c,"weekday"))}let u=new Intl.DateTimeFormat(e,{hour:"numeric",hour12:!0,timeZone:"UTC"}),f=E(u,new Date(Date.UTC(2020,0,1,1)),"dayPeriod"),F=E(u,new Date(Date.UTC(2020,0,1,13)),"dayPeriod"),g=[...new Set([f,F])],y={monthLong:a,monthShort:o,weekdayLong:m,weekdayShort:h,dayPeriod:g};return R.set(e,y),y}function ee(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function b(e){return`(?:${e.map(ee).join("|")})`}var P;function te(){if(P)return P;let e=Intl.supportedValuesOf;return typeof e=="function"?P=b([...e("timeZone"),"UTC"]):P="[A-Za-z_]+(?:\\/[A-Za-z_+\\-0-9]+)+|UTC",P}var ne={yyyy:"\\d{4}",yy:"\\d{2}",MM:"(?:0[1-9]|1[0-2])",M:"(?:[1-9]|1[0-2])",dd:"(?:0[1-9]|[12]\\d|3[01])",d:"(?:[1-9]|[12]\\d|3[01])",HH:"(?:[01]\\d|2[0-3])",H:"(?:[0-9]|1\\d|2[0-3])",hh:"(?:0[1-9]|1[0-2])",h:"(?:[1-9]|1[0-2])",mm:"(?:[0-5]\\d)",m:"(?:[0-9]|[1-5]\\d)",ss:"(?:[0-5]\\d)",s:"(?:[0-9]|[1-5]\\d)",SSS:"\\d{3}"};function V(e,t){let n=ne[e];if(n)return n;let r=p(t);switch(e){case"MMMM":return b(r.monthLong);case"MMM":return b(r.monthShort);case"EEEE":return b(r.weekdayLong);case"EEE":return b(r.weekdayShort);case"a":return b(r.dayPeriod);case"zzz":return te();default:throw new Error(`temporal-fmt: unknown token "${e}"`)}}function re(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function j(e,t){let n=[],r="",a=0;for(let o of e){if(o.kind==="literal"){r+=re(o.value);continue}let i=`g${a++}`;n.push({name:i,token:o.value}),r+=`(?<${i}>${V(o.value,t)})`}return{regex:new RegExp(`^(?:${r})$`,"u"),groups:n}}function K(){let e=globalThis.Temporal;if(!e)throw new Error("temporal-fmt: parse() needs a global `Temporal` to construct its result. Native on Node 26+, or assign a polyfill (e.g. temporal-polyfill) to globalThis.Temporal first.");return e}var I=new Map,oe=500;function ae(e,t){let n=t+" "+e,r=I.get(n);if(r)return r;if(I.size>=oe){let a=I.keys().next().value;a!==void 0&&I.delete(a)}return r=j(S(e),t),I.set(n,r),r}var D=new Map,ie=500;function se(e){if(D.has(e))return D.get(e);if(D.size>=ie){let r=D.keys().next().value;r!==void 0&&D.delete(r)}let t=new Intl.DateTimeFormat(e).resolvedOptions().calendar,n=t==="gregory"?void 0:t;return D.set(e,n),n}function me(e,t,n,r){switch(t){case"yyyy":e.year=parseInt(n,10);break;case"yy":e.twoDigitYear=parseInt(n,10);break;case"MM":case"M":e.month=parseInt(n,10);break;case"MMMM":e.month=p(r).monthLong.indexOf(n)+1;break;case"MMM":e.month=p(r).monthShort.indexOf(n)+1;break;case"dd":case"d":e.day=parseInt(n,10);break;case"EEEE":e.weekdayRaw=n,e.weekdayExpected=p(r).weekdayLong.indexOf(n)+1;break;case"EEE":e.weekdayRaw=n,e.weekdayExpected=p(r).weekdayShort.indexOf(n)+1;break;case"HH":case"H":e.hour=parseInt(n,10);break;case"hh":case"h":e.hour12=parseInt(n,10);break;case"mm":case"m":e.minute=parseInt(n,10);break;case"ss":case"s":e.second=parseInt(n,10);break;case"SSS":e.millisecond=parseInt(n,10);break;case"a":e.isPM=n===p(r).dayPeriod[1];break;case"zzz":e.timeZoneId=n;break}}function de(e){if(e.year!==void 0)return e.year;if(e.twoDigitYear!==void 0)return e.twoDigitYear<=68?2e3+e.twoDigitYear:1900+e.twoDigitYear}function ue(e,t){if(e.hour!==void 0&&e.hour12!==void 0)throw new Error(`temporal-fmt: format string "${t}" mixes a 24-hour token ("HH"/"H") with a 12-hour token ("hh"/"h"). Pick one or the other \u2014 parse() won't guess which is authoritative.`);if(e.hour!==void 0)return e.hour;if(e.hour12!==void 0){if(e.isPM===void 0)throw new Error(`temporal-fmt: format string "${t}" uses a 12-hour token ("hh"/"h") without an "a" token, so parse() can't tell AM from PM.`);return e.hour12%12+(e.isPM?12:0)}}function ce(e,t,n={}){if(e.length>1e3)throw new Error(`temporal-fmt: format string exceeds maximum length of ${1e3} characters (got ${e.length}).`);let r=n.locale??C,a=se(r),o=ae(e,r),i=o.regex.exec(t);if(!i)throw new Error("temporal-fmt: no valid pattern matches the format string and input shape");if(o.groups.length===0)throw new Error(`temporal-fmt: format string "${e}" has no tokens \u2014 nothing to parse into a value.`);let s={};for(let{name:T,token:H}of o.groups)me(s,H,i.groups[T],r);let m=de(s),h=ue(s,e),{month:u,day:f,minute:F,second:g,millisecond:y,timeZoneId:d,weekdayExpected:c,weekdayRaw:Y}=s,W=m!==void 0||u!==void 0||f!==void 0,k=m!==void 0&&u!==void 0&&f!==void 0;if(W&&!k)throw new Error(`temporal-fmt: format string "${e}" has an incomplete date \u2014 year, month, and day tokens must all be present together.`);let A=h!==void 0||F!==void 0||g!==void 0||y!==void 0;if(d!==void 0&&!(k&&A))throw new Error(`temporal-fmt: format string "${e}" has a "zzz" token but needs a full date and time to build a ZonedDateTime.`);if(c!==void 0&&!k)throw new Error(`temporal-fmt: format string "${e}" has a weekday token ("EEEE"/"EEE") but needs a full date to validate it against.`);if(!k&&!A)throw new Error(`temporal-fmt: format string "${e}" has no date or time tokens to parse.`);let x=K(),Z={hour:h??0,minute:F??0,second:g??0,millisecond:y??0},z=a?{calendar:a}:{},v={overflow:"reject"},w;try{d!==void 0?w=x.ZonedDateTime.from({year:m,month:u,day:f,...Z,...z,timeZone:d},v):k&&A?w=x.PlainDateTime.from({year:m,month:u,day:f,...Z,...z},v):k?w=x.PlainDate.from({year:m,month:u,day:f,...z},v):w=x.PlainTime.from(Z,v)}catch(T){throw new Error(`temporal-fmt: "${t}" doesn't describe a valid date/time for format "${e}": ${T.message}`)}if(c!==void 0){let T=w.dayOfWeek;if(T!==c){let H=p(r);throw new Error(`temporal-fmt: "${Y}" doesn't match the actual weekday (${H.weekdayLong[T-1]}) for the parsed date.`)}}return w}export{Q as format,ce as parse};
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/tokens.ts","../src/tokenize.ts","../src/format.ts","../src/localeVocab.ts","../src/pattern.ts","../src/parsePattern.ts","../src/temporalGlobal.ts","../src/parse.ts"],"sourcesContent":["export function pad(n: number, len: number): string {\n return String(n).padStart(len, '0');\n}\n\n// Not every field exists on every Temporal type (PlainDate has no .hour,\n// etc). Callers check for undefined before formatting a token.\nexport interface TemporalLike {\n year?: number;\n month?: number;\n day?: number;\n hour?: number;\n minute?: number;\n second?: number;\n millisecond?: number;\n timeZoneId?: string;\n dayOfWeek?: number; // 1 (Mon) - 7 (Sun), per Temporal spec\n calendarId?: string;\n toInstant?: () => unknown;\n toLocaleString?: (locale: string, options: Intl.DateTimeFormatOptions) => string;\n}\n\nexport interface FormatOptions {\n /** BCP 47 locale tag, e.g. 'en-US', 'fr-FR', 'ar-EG'. Defaults to 'en-US'. */\n locale?: string;\n}\n\nexport const DEFAULT_LOCALE = 'en-US';\n\n// Intl.DateTimeFormat is expensive to construct and format() can run in a\n// loop (rendering a table of dates), so cache by (locale, options).\nconst formatterCache = new Map<string, Intl.DateTimeFormat>();\nconst MAX_CACHE_SIZE = 500;\n\nfunction getFormatter(locale: string, options: Intl.DateTimeFormatOptions): Intl.DateTimeFormat {\n const key = locale + JSON.stringify(options);\n let formatter = formatterCache.get(key);\n if (formatter) {\n return formatter;\n }\n if (formatterCache.size >= MAX_CACHE_SIZE) {\n // not real LRU, just evicts oldest insertion — fine for this key space\n const oldestKey = formatterCache.keys().next().value;\n if (oldestKey !== undefined) formatterCache.delete(oldestKey);\n }\n formatter = new Intl.DateTimeFormat(locale, options);\n formatterCache.set(key, formatter);\n return formatter;\n}\n\n// Passing a Temporal object straight into `new Intl.DateTimeFormat().formatToParts()`\n// only works when the engine's Intl implementation has special-cased support for\n// *native* Temporal instances (checked via internal slots and/or gated behind a V8 flag,\n// not tied to a specific Node version).\n// \n// A Temporal polyfill's instances don't have those slots, so the engine falls back to ToNumber() -> .valueOf(),\n// which the polyfill deliberately throws on (\"Cannot use valueOf\"). \n// Probed once and memoized and only from intlPart(), so it never\n// runs unless a format string actually uses a locale-aware token.\nlet nativeSupport: boolean | undefined;\nfunction intlSupportsNativeTemporal(): boolean {\n if (nativeSupport === undefined) {\n nativeSupport = false;\n const Temporal = (globalThis as { Temporal?: { PlainDate?: { from: (s: string) => unknown } } }).Temporal;\n if (Temporal?.PlainDate) {\n try {\n new Intl.DateTimeFormat('en-US', { day: 'numeric' }).formatToParts(Temporal.PlainDate.from('1970-01-01') as Date);\n nativeSupport = true;\n } catch {\n // native Temporal absent, or present but not recognized by Intl — fall back\n }\n }\n }\n return nativeSupport;\n}\n\nfunction intlPart(\n temporal: TemporalLike,\n locale: string,\n options: Intl.DateTimeFormatOptions,\n partType: Intl.DateTimeFormatPartTypes\n): string {\n // Intl throws \"Mismatching Calendars\" if the formatter's calendar doesn't\n // match the object's own (e.g. en-US formatter defaults to gregory, but\n // a hebrew/islamic PlainDate needs its own calendar passed through).\n //\n // skip this for iso8601 specifically — passing `calendar: 'iso8601'`\n // explicitly alongside a single-field options object makes formatToParts()\n // come back empty for some reason.\n const calendar = temporal?.calendarId;\n const formatterOptions: Intl.DateTimeFormatOptions = {\n ...options,\n ...(calendar && calendar !== 'iso8601' ? { calendar } : {}),\n };\n\n // Temporal.prototype.toLocaleString() is part of the Temporal spec itself:\n // polyfills implement the ICU formatting internally without needing the\n // engine to recognize the object, so it works without native Intl support.\n if (!intlSupportsNativeTemporal()) {\n return temporal.toLocaleString!(locale, formatterOptions);\n }\n\n // formatToParts() throws on ZonedDateTime directly (per spec), so convert\n // to Instant and pass the zone via `timeZone` instead. Don't convert to\n // PlainDateTime — that drops the zone, which breaks 'MMMM' + 'zzz' combos.\n const { toInstant, timeZoneId } = temporal;\n const isZoned = typeof toInstant === 'function' && typeof timeZoneId === 'string';\n // has to be called as temporal.toInstant() because destructuring it off breaks\n // the receiver and throws\n const intlSafeTemporal = isZoned ? temporal.toInstant!() : temporal;\n const nativeOptions: Intl.DateTimeFormatOptions = {\n ...formatterOptions,\n ...(isZoned ? { timeZone: timeZoneId } : {}),\n };\n\n const formatter = getFormatter(locale, nativeOptions);\n const parts = formatter.formatToParts(intlSafeTemporal as Date | number);\n const part = parts.find((p) => p.type === partType);\n if (!part) {\n throw new Error(\n `temporal-fmt: locale \"${locale}\" produced no \"${partType}\" part for this token. ` +\n `This usually means the Temporal object is missing the field the token needs.`\n );\n }\n return part.value;\n}\n\n\n// Temporal.prototype.toLocaleString() can't isolate a single field the way formatToParts() can\n// — asking for `hour` + `dayPeriod` together returns one joined string (e.g.\n// \"3 in the afternoon\"), and asking for `dayPeriod` alone silently resolves\n// against a different, non-hour-anchored set of periods (produces \"in the\n// afternoon\"/\"昼\" instead of the \"PM\"/\"午後\" that pairing it with hour12\n// actually renders).\n// \n// On using this instead of temporal:\n// Day period only depends on the hour, not on the calendar or the date, \n// so always route it through a plain UTC Date instead\n// Intl.DateTimeFormat has always accepted Date objects, on every engine,\n// independent of whether Temporal itself is native or polyfilled.\nfunction dayPeriodPart(hour: number, locale: string): string {\n const date = new Date(Date.UTC(1970, 0, 1, hour));\n const formatter = getFormatter(locale, { hour: 'numeric', hour12: true, timeZone: 'UTC' });\n const part = formatter.formatToParts(date).find((p) => p.type === 'dayPeriod');\n if (!part) {\n throw new Error(`temporal-fmt: locale \"${locale}\" produced no \"dayPeriod\" part for token \"a\".`);\n }\n return part.value;\n}\n\ntype TokenHandler = (t: TemporalLike, locale: string) => string;\n\n// Longest-first — tokenizer is greedy, \"yyyy\" has to be tried before \"yy\".\n//\n// Numeric tokens always render in ASCII digits, never locale-native\n// (Arabic-Indic, Devanagari, etc). Padding non-ASCII digit strings to a\n// fixed width isn't the same operation as padding \"3\", and most consumers\n// parsing these back out want plain digits anyway.\nexport const TOKENS: Array<[string, TokenHandler, keyof TemporalLike]> = [\n ['yyyy', (t) => pad(t.year!, 4), 'year'],\n ['yy', (t) => {\n // -45 % 100 === -45, so truncating negative years to 2 digits doesn't\n // work and Math.abs() would make 45 CE and 45 BCE render the same.\n if (t.year! < 0) {\n throw new Error(\n `temporal-fmt: token \"yy\" doesn't support negative years (got ${t.year}), ` +\n `since truncating to 2 digits would make it indistinguishable from a ` +\n `positive year. Use \"yyyy\" instead.`\n );\n }\n return pad(t.year! % 100, 2);\n }, 'year'],\n ['MMMM', (t, locale) => intlPart(t, locale, { month: 'long' }, 'month'), 'month'],\n ['MMM', (t, locale) => intlPart(t, locale, { month: 'short' }, 'month'), 'month'],\n ['MM', (t) => pad(t.month!, 2), 'month'],\n ['M', (t) => String(t.month!), 'month'],\n ['dd', (t) => pad(t.day!, 2), 'day'],\n ['d', (t) => String(t.day!), 'day'],\n ['EEEE', (t, locale) => intlPart(t, locale, { weekday: 'long' }, 'weekday'), 'dayOfWeek'],\n ['EEE', (t, locale) => intlPart(t, locale, { weekday: 'short' }, 'weekday'), 'dayOfWeek'],\n ['HH', (t) => pad(t.hour!, 2), 'hour'],\n ['H', (t) => String(t.hour!), 'hour'],\n ['hh', (t) => pad(t.hour! % 12 || 12, 2), 'hour'],\n ['h', (t) => String(t.hour! % 12 || 12), 'hour'],\n ['mm', (t) => pad(t.minute!, 2), 'minute'],\n ['m', (t) => String(t.minute!), 'minute'],\n ['ss', (t) => pad(t.second!, 2), 'second'],\n ['s', (t) => String(t.second!), 'second'],\n ['SSS', (t) => pad(t.millisecond!, 3), 'millisecond'],\n // dayPeriod text is locale-specific (AM/PM in en-US, م/ص in ar-EG) but\n // still needs .hour on the input to compute which period it is\n ['a', (t, locale) => dayPeriodPart(t.hour!, locale), 'hour'],\n ['zzz', (t) => t.timeZoneId!, 'timeZoneId'],\n];\n","import { TOKENS } from './tokens.js';\n\nexport type Piece =\n | { kind: 'token'; value: string }\n | { kind: 'literal'; value: string };\n\n// longest-first so the greedy scan never matches \"M\" when \"MMMM\" was there\nconst SORTED_TOKEN_STRINGS = TOKENS.map(([tok]) => tok).sort((a, b) => b.length - a.length);\n\n/**\n * Splits a format string like `\"yyyy-MM-dd 'at' HH:mm\"` into token/literal\n * pieces. Text in single quotes is always literal (e.g. write 'rd' in\n * \"3rd\" so it's not read as the day token). A doubled quote ('') means a\n * literal quote character, both inside a quoted span and standalone.\n */\nexport function tokenize(format: string): Piece[] {\n const pieces: Piece[] = [];\n let i = 0;\n\n while (i < format.length) {\n const ch = format[i];\n\n if (ch === \"'\") {\n // check doubled-quote first or \"''best''\" parses wrong\n if (format[i + 1] === \"'\") {\n appendLiteral(pieces, \"'\");\n i += 2;\n continue;\n }\n\n let j = i + 1;\n let literal = '';\n let closed = false;\n while (j < format.length) {\n if (format[j] === \"'\") {\n if (format[j + 1] === \"'\") {\n literal += \"'\";\n j += 2;\n continue;\n }\n closed = true;\n j += 1;\n break;\n }\n literal += format[j];\n j += 1;\n }\n\n if (!closed) {\n throw new Error(`temporal-fmt: unterminated quote in format string \"${format}\"`);\n }\n\n appendLiteral(pieces, literal);\n i = j;\n continue;\n }\n\n const match = SORTED_TOKEN_STRINGS.find((tok) => format.startsWith(tok, i));\n if (match) {\n pieces.push({ kind: 'token', value: match });\n i += match.length;\n continue;\n }\n\n // not a token or quote — pass through as-is \n appendLiteral(pieces, ch);\n i += 1;\n }\n\n return pieces;\n}\n\n// merges into the previous piece if it's also a literal, so \"---\" is one\n// piece instead of three\nfunction appendLiteral(pieces: Piece[], value: string): void {\n const last = pieces[pieces.length - 1];\n if (last && last.kind === 'literal') {\n last.value += value;\n } else {\n pieces.push({ kind: 'literal', value });\n }\n}\n","import { TOKENS, DEFAULT_LOCALE, type TemporalLike, type FormatOptions } from './tokens.js';\nimport { tokenize } from './tokenize.js';\nimport { MAX_FORMAT_LENGTH } from './constants.js';\n\nconst HANDLER_BY_TOKEN = new Map(TOKENS.map(([tok, fn, field]) => [tok, { fn, field }]));\n\n/**\n * Format a Temporal.PlainDate, PlainTime, PlainDateTime, or ZonedDateTime\n * using a date-fns-style token string.\n *\n * @example\n * format(Temporal.Now.plainDateISO(), 'yyyy-MM-dd') // \"2026-08-04\"\n * format(zdt, \"MMM d, yyyy 'at' h:mm a\") // \"Aug 4, 2026 at 3:45 PM\"\n * format(zdt, 'MMMM d, yyyy', { locale: 'fr-FR' }) // \"août 4, 2026\"\n * format(zdt, 'EEEE d MMMM', { locale: 'ar-EG' }) // Arabic weekday/month names\n *\n * Numeric fields always render in ASCII digits regardless of locale.\n * Named fields (MMMM, EEEE, a) are fully localized via Intl, including\n * non-Gregorian calendars if the Temporal object carries one.\n *\n * Throws if the format string uses a token the input type doesn't support\n * (e.g. 'HH' on a PlainDate) rather than silently printing \"undefined\".\n */\nexport function format(temporal: TemporalLike, formatStr: string, options: FormatOptions = {}): string {\n if (formatStr.length > MAX_FORMAT_LENGTH) {\n throw new Error(\n `temporal-fmt: format string exceeds maximum length of ${MAX_FORMAT_LENGTH} characters ` +\n `(got ${formatStr.length}).`\n );\n }\n\n const locale = options.locale ?? DEFAULT_LOCALE;\n const pieces = tokenize(formatStr);\n let result = '';\n\n for (const piece of pieces) {\n if (piece.kind === 'literal') {\n result += piece.value;\n continue;\n }\n\n const handler = HANDLER_BY_TOKEN.get(piece.value);\n if (!handler) {\n // shouldn't happen — tokenize() only emits tokens from TOKENS\n throw new Error(`temporal-fmt: unknown token \"${piece.value}\"`);\n }\n\n if (temporal[handler.field] === undefined) {\n throw new Error(\n `temporal-fmt: token \"${piece.value}\" requires \"${handler.field}\", ` +\n `which this Temporal object doesn't have. ` +\n `(e.g. PlainDate has no time fields, PlainTime has no date fields)`\n );\n }\n\n result += handler.fn(temporal, locale);\n }\n\n return result;\n}\n","// Closed-vocabulary lookups for locale-aware tokens (MMMM, MMM, EEEE, EEE, a).\n// Each set 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\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\nconst vocabCache = new Map<string, LocaleVocab>();\n\nfunction partValue(formatter: Intl.DateTimeFormat, date: Date, type: Intl.DateTimeFormatPartTypes): string {\n const part = formatter.formatToParts(date).find((p) => p.type === type);\n if (!part) {\n throw new Error(`temporal-fmt: locale produced no \"${type}\" part while building match vocabulary.`);\n }\n return part.value;\n}\n\nexport function getLocaleVocab(locale: string): LocaleVocab {\n const cached = vocabCache.get(locale);\n if (cached) {\n return cached;\n }\n\n const monthLongFmt = new Intl.DateTimeFormat(locale, { month: 'long', timeZone: 'UTC' });\n const monthShortFmt = new Intl.DateTimeFormat(locale, { 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\n const weekdayLongFmt = new Intl.DateTimeFormat(locale, { weekday: 'long', timeZone: 'UTC' });\n const weekdayShortFmt = new Intl.DateTimeFormat(locale, { 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\n const dayPeriodFmt = new Intl.DateTimeFormat(locale, { 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 vocabCache.set(locale, vocab);\n return vocab;\n}\n","import { getLocaleVocab } from './localeVocab.js';\n\nfunction escapeRegExp(literal: string): string {\n return literal.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nfunction alternation(values: string[]): string {\n return `(?:${values.map(escapeRegExp).join('|')})`;\n}\n\nlet timeZoneFragment: string | undefined;\n\nfunction getTimeZoneFragment(): string {\n if (timeZoneFragment) {\n return timeZoneFragment;\n }\n const supportedValuesOf = (Intl as unknown as { supportedValuesOf?: (key: string) => string[] }).supportedValuesOf;\n if (typeof supportedValuesOf === 'function') {\n // supportedValuesOf('timeZone') leaves out 'UTC', but format() can\n // produce it from a real ZonedDateTime — without this, parse() couldn't\n // parse our own library's own output back.\n timeZoneFragment = alternation([...supportedValuesOf('timeZone'), 'UTC']);\n } else {\n // no Intl.supportedValuesOf — match on shape only\n timeZoneFragment = '[A-Za-z_]+(?:\\\\/[A-Za-z_+\\\\-0-9]+)+|UTC';\n }\n return timeZoneFragment;\n}\n\n// mirrors the ranges pad() in tokens.ts actually produces — keep in sync\n// if those ever change\nconst NUMERIC_FRAGMENTS: Record<string, string> = {\n yyyy: '\\\\d{4}',\n yy: '\\\\d{2}',\n MM: '(?:0[1-9]|1[0-2])',\n M: '(?:[1-9]|1[0-2])',\n dd: '(?:0[1-9]|[12]\\\\d|3[01])',\n d: '(?:[1-9]|[12]\\\\d|3[01])',\n HH: '(?:[01]\\\\d|2[0-3])',\n H: '(?:[0-9]|1\\\\d|2[0-3])',\n hh: '(?:0[1-9]|1[0-2])',\n h: '(?:[1-9]|1[0-2])',\n mm: '(?:[0-5]\\\\d)',\n m: '(?:[0-9]|[1-5]\\\\d)',\n ss: '(?:[0-5]\\\\d)',\n s: '(?:[0-9]|[1-5]\\\\d)',\n SSS: '\\\\d{3}',\n};\n\nexport function tokenFragment(token: string, locale: string): string {\n const numeric = NUMERIC_FRAGMENTS[token];\n if (numeric) {\n return numeric;\n }\n\n const vocab = getLocaleVocab(locale);\n switch (token) {\n case 'MMMM': return alternation(vocab.monthLong);\n case 'MMM': return alternation(vocab.monthShort);\n case 'EEEE': return alternation(vocab.weekdayLong);\n case 'EEE': return alternation(vocab.weekdayShort);\n case 'a': return alternation(vocab.dayPeriod);\n case 'zzz': return getTimeZoneFragment();\n default:\n throw new Error(`temporal-fmt: unknown token \"${token}\"`);\n }\n}\n","import type { Piece } from './tokenize.js';\nimport { tokenFragment } from './pattern.js';\n\nfunction escapeRegExp(literal: string): string {\n return literal.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nexport interface CapturingPattern {\n regex: RegExp;\n groups: Array<{ name: string; token: string }>; // token pieces, in order\n}\n\n/**\n * Same walk as buildPatternSource() in pattern.ts, but each token piece\n * gets its own named capture group (positionally named so the same token,\n * e.g. \"yyyy\", could in theory appear twice) so a caller can pull the\n * matched substring for each token back out after a successful match.\n */\nexport function buildCapturingPattern(pieces: Piece[], locale: string): CapturingPattern {\n const groups: Array<{ name: string; token: string }> = [];\n let source = '';\n let i = 0;\n\n for (const piece of pieces) {\n if (piece.kind === 'literal') {\n source += escapeRegExp(piece.value);\n continue;\n }\n const name = `g${i++}`;\n groups.push({ name, token: piece.value });\n source += `(?<${name}>${tokenFragment(piece.value, locale)})`;\n }\n\n return { regex: new RegExp(`^(?:${source})$`, 'u'), groups };\n}\n","// This package's tsconfig assumes lib: [\"ESNext\"] only — no ambient\n// `Temporal` namespace type. Everywhere else in this codebase only ever\n// *reads* fields off a Temporal-like object the caller already built\n// (TemporalLike in tokens.ts). parse() is the first place that needs to\n// *construct* one, via the global `Temporal` the README already requires\n// consumers to provide (native on Node 26+, or a polyfill). Kept loosely\n// typed on purpose, consistent with the rest of the codebase.\ninterface TemporalFactory {\n from(fields: Record<string, number | string | undefined>, options?: { overflow?: 'constrain' | 'reject' }): unknown;\n}\n\nexport interface TemporalNamespace {\n PlainDate: TemporalFactory;\n PlainTime: TemporalFactory;\n PlainDateTime: TemporalFactory;\n ZonedDateTime: TemporalFactory;\n}\n\nexport function getTemporal(): TemporalNamespace {\n const temporal = (globalThis as { Temporal?: TemporalNamespace }).Temporal;\n if (!temporal) {\n throw new Error(\n 'temporal-fmt: parse() needs a global `Temporal` to construct its result. ' +\n 'Native on Node 26+, or assign a polyfill (e.g. temporal-polyfill) to globalThis.Temporal first.'\n );\n }\n return temporal;\n}\n","import { DEFAULT_LOCALE, type FormatOptions } from './tokens.js';\nimport { tokenize } from './tokenize.js';\nimport { buildCapturingPattern, type CapturingPattern } from './parsePattern.js';\nimport { getLocaleVocab } from './localeVocab.js';\nimport { getTemporal } from './temporalGlobal.js';\nimport { MAX_FORMAT_LENGTH } from './constants.js';\n\n// format strings are short hand-written literals reused across many calls —\n// cache the compiled capturing pattern per (formatStr, locale) pair instead\n// of rebuilding it every call.\nconst patternCache = new Map<string, CapturingPattern>();\nconst MAX_CACHE_SIZE = 500;\n\nfunction getPattern(formatStr: string, locale: string): CapturingPattern {\n const key = locale + ' ' + formatStr;\n let pattern = patternCache.get(key);\n if (pattern) {\n return pattern;\n }\n if (patternCache.size >= MAX_CACHE_SIZE) {\n const oldestKey = patternCache.keys().next().value;\n if (oldestKey !== undefined) patternCache.delete(oldestKey);\n }\n pattern = buildCapturingPattern(tokenize(formatStr), locale);\n patternCache.set(key, pattern);\n return pattern;\n}\n\n// Intl.DateTimeFormat(locale).resolvedOptions().calendar reports the\n// locale's default calendar so passing locale with a `-u-ca-` extension in the tag\n// allows setting non-gregorian calendars. 'gregory' is treated as \"no calendar\" so\n// the default locale ('en-US') keeps constructing plain ISO 8601\nconst calendarCache = new Map<string, string | undefined>();\nconst MAX_CALENDAR_CACHE_SIZE = 500;\n\nfunction resolveCalendar(locale: string): string | undefined {\n if (calendarCache.has(locale)) {\n return calendarCache.get(locale);\n }\n if (calendarCache.size >= MAX_CALENDAR_CACHE_SIZE) {\n const oldestKey = calendarCache.keys().next().value;\n if (oldestKey !== undefined) calendarCache.delete(oldestKey);\n }\n const resolved = new Intl.DateTimeFormat(locale).resolvedOptions().calendar;\n const calendar = resolved === 'gregory' ? undefined : resolved;\n calendarCache.set(locale, calendar);\n return calendar;\n}\n\ninterface Fields {\n year?: number;\n twoDigitYear?: number;\n month?: number;\n day?: number;\n hour?: number;\n hour12?: number;\n isPM?: boolean;\n minute?: number;\n second?: number;\n millisecond?: number;\n timeZoneId?: string;\n weekdayExpected?: number; // ISO dayOfWeek, 1 (Mon) - 7 (Sun)\n weekdayRaw?: string;\n}\n\nfunction applyGroup(fields: Fields, token: string, raw: string, locale: string): void {\n switch (token) {\n case 'yyyy': fields.year = parseInt(raw, 10); break;\n case 'yy': fields.twoDigitYear = parseInt(raw, 10); break;\n case 'MM': case 'M': fields.month = parseInt(raw, 10); break;\n case 'MMMM': fields.month = getLocaleVocab(locale).monthLong.indexOf(raw) + 1; break;\n case 'MMM': fields.month = getLocaleVocab(locale).monthShort.indexOf(raw) + 1; break;\n case 'dd': case 'd': fields.day = parseInt(raw, 10); break;\n case 'EEEE':\n fields.weekdayRaw = raw;\n fields.weekdayExpected = getLocaleVocab(locale).weekdayLong.indexOf(raw) + 1;\n break;\n case 'EEE':\n fields.weekdayRaw = raw;\n fields.weekdayExpected = getLocaleVocab(locale).weekdayShort.indexOf(raw) + 1;\n break;\n case 'HH': case 'H': fields.hour = parseInt(raw, 10); break;\n case 'hh': case 'h': fields.hour12 = parseInt(raw, 10); break;\n case 'mm': case 'm': fields.minute = parseInt(raw, 10); break;\n case 'ss': case 's': fields.second = parseInt(raw, 10); break;\n case 'SSS': fields.millisecond = parseInt(raw, 10); break;\n case 'a': fields.isPM = raw === getLocaleVocab(locale).dayPeriod[1]; break;\n case 'zzz': fields.timeZoneId = raw; break;\n }\n}\n\n/**\n * Resolves year value into 4-digit year\n * \n * For 2-digit values it emulates strptime (POSIX)\n * so that resolving value is not clock-dependent\n * \n * * 00-68 -> 2000-2068\n * * 69-99 -> 1900-1999\n * \n * @see https://www.man7.org/linux//man-pages/man3/strptime.3p.html\n */\nfunction resolveYear(fields: Fields): number | undefined {\n if (fields.year !== undefined) return fields.year;\n if (fields.twoDigitYear !== undefined) {\n return fields.twoDigitYear <= 68 ? 2000 + fields.twoDigitYear : 1900 + fields.twoDigitYear;\n }\n return undefined;\n}\n\nfunction resolveHour(fields: Fields, formatStr: string): number | undefined {\n if (fields.hour !== undefined) return fields.hour;\n if (fields.hour12 !== undefined) {\n if (fields.isPM === undefined) {\n throw new Error(\n `temporal-fmt: format string \"${formatStr}\" uses a 12-hour token (\"hh\"/\"h\") without an \"a\" token, ` +\n `so parse() can't tell AM from PM.`\n );\n }\n return (fields.hour12 % 12) + (fields.isPM ? 12 : 0);\n }\n return undefined;\n}\n\n/**\n * Parses `input` against `formatStr` and builds the real Temporal value it\n * describes: a `Temporal.PlainDate`, `PlainTime`, `PlainDateTime`, or\n * `ZonedDateTime` depending on which tokens are present.\n * \n * Value is returned as `unknown` since this package assumes no ambient `Temporal` types.\n *\n * Optionally, `options.locale` picks the calendar the result is built in. Pass a\n * locale tag with a `-u-ca-` extension (e.g. `'en-u-ca-hebrew'`) to parse\n * into a non-Gregorian calendar.\n * \n * @throws if `input` doesn't match `formatStr`'s shape at all\n * @throws if it matches the shape but escribes an impossible date (e.g. Feb 30)\n * or self-contradictory data (e.g. a weekday name that doesn't match the actual date)\n *\n * @example\n * parse('yyyy-MM-dd HH:mm', '2026-08-04 15:45') // Temporal.PlainDateTime\n * parse('yyyy-MM', '2026-08-04T15:45:30') // throws — not a valid pattern and input shape\n * parse('yyyy-MM-dd', '2026-02-30') // throws — not a real date\n */\nexport function parse(formatStr: string, input: string, options: FormatOptions = {}): unknown | undefined {\n if (formatStr.length > MAX_FORMAT_LENGTH) {\n throw new Error(\n `temporal-fmt: format string exceeds maximum length of ${MAX_FORMAT_LENGTH} characters ` +\n `(got ${formatStr.length}).`\n );\n }\n\n const locale = options.locale ?? DEFAULT_LOCALE;\n const calendar = resolveCalendar(locale);\n const pattern = getPattern(formatStr, locale);\n const match = pattern.regex.exec(input);\n if (!match) {\n throw new Error(`temporal-fmt: no valid pattern matches the format string and input shape`);\n }\n\n if (pattern.groups.length === 0) {\n throw new Error(`temporal-fmt: format string \"${formatStr}\" has no tokens — nothing to parse into a value.`);\n }\n\n const fields: Fields = {};\n for (const { name, token } of pattern.groups) {\n applyGroup(fields, token, match.groups![name]!, locale);\n }\n\n const year = resolveYear(fields);\n const hour = resolveHour(fields, formatStr);\n const { month, day, minute, second, millisecond, timeZoneId, weekdayExpected, weekdayRaw } = fields;\n\n const hasAnyDatePart = year !== undefined || month !== undefined || day !== undefined;\n const hasFullDate = year !== undefined && month !== undefined && day !== undefined;\n if (hasAnyDatePart && !hasFullDate) {\n throw new Error(\n `temporal-fmt: format string \"${formatStr}\" has an incomplete date — ` +\n `year, month, and day tokens must all be present together.`\n );\n }\n\n const hasTime = hour !== undefined || minute !== undefined || second !== undefined || millisecond !== undefined;\n\n if (timeZoneId !== undefined && !(hasFullDate && hasTime)) {\n throw new Error(\n `temporal-fmt: format string \"${formatStr}\" has a \"zzz\" token but needs a full date and time ` +\n `to build a ZonedDateTime.`\n );\n }\n\n if (weekdayExpected !== undefined && !hasFullDate) {\n throw new Error(\n `temporal-fmt: format string \"${formatStr}\" has a weekday token (\"EEEE\"/\"EEE\") but needs ` +\n `a full date to validate it against.`\n );\n }\n\n if (!hasFullDate && !hasTime) {\n // shouldn't happen — every token maps to a date, time, zone, or\n // weekday field, and weekday-without-date already threw above\n throw new Error(`temporal-fmt: format string \"${formatStr}\" has no date or time tokens to parse.`);\n }\n\n const temporal = getTemporal();\n const timeFields = { hour: hour ?? 0, minute: minute ?? 0, second: second ?? 0, millisecond: millisecond ?? 0 };\n // omitted entirely for the default calendar (see resolveCalendar) so\n // construction stays plain ISO 8601 unless a caller's locale asks for\n // something else — Temporal calendars don't apply to time-only values.\n const calendarField = calendar ? { calendar } : {};\n\n // overflow: 'reject' — without it Temporal *clamps* out-of-range fields\n // (Feb 30 silently becomes Feb 28) instead of throwing, which would\n // contradict the \"throws on genuinely invalid data\" behavior parse() promises.\n const reject = { overflow: 'reject' as const };\n\n let result: unknown;\n try {\n if (timeZoneId !== undefined) {\n result = temporal.ZonedDateTime.from({ year: year!, month: month!, day: day!, ...timeFields, ...calendarField, timeZone: timeZoneId }, reject);\n } else if (hasFullDate && hasTime) {\n result = temporal.PlainDateTime.from({ year: year!, month: month!, day: day!, ...timeFields, ...calendarField }, reject);\n } else if (hasFullDate) {\n result = temporal.PlainDate.from({ year: year!, month: month!, day: day!, ...calendarField }, reject);\n } else {\n result = temporal.PlainTime.from(timeFields, reject);\n }\n } catch (err) {\n throw new Error(\n `temporal-fmt: \"${input}\" doesn't describe a valid date/time for format \"${formatStr}\": ` +\n `${(err as Error).message}`\n );\n }\n\n if (weekdayExpected !== undefined) {\n const actual = (result as { dayOfWeek: number }).dayOfWeek;\n if (actual !== weekdayExpected) {\n const vocab = getLocaleVocab(locale);\n throw new Error(\n `temporal-fmt: \"${weekdayRaw}\" doesn't match the actual weekday (${vocab.weekdayLong[actual - 1]}) ` +\n `for the parsed date.`\n );\n }\n }\n\n return result;\n}\n"],"mappings":"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","names":["pad","n","len","DEFAULT_LOCALE","formatterCache","MAX_CACHE_SIZE","getFormatter","locale","options","key","formatter","oldestKey","nativeSupport","intlSupportsNativeTemporal","Temporal","intlPart","temporal","partType","calendar","formatterOptions","toInstant","timeZoneId","isZoned","intlSafeTemporal","nativeOptions","part","p","dayPeriodPart","hour","date","TOKENS","t","SORTED_TOKEN_STRINGS","TOKENS","tok","a","b","tokenize","format","pieces","i","ch","appendLiteral","j","literal","closed","match","value","last","HANDLER_BY_TOKEN","TOKENS","tok","fn","field","format","temporal","formatStr","options","locale","DEFAULT_LOCALE","pieces","tokenize","result","piece","handler","vocabCache","partValue","formatter","date","type","part","p","getLocaleVocab","locale","cached","monthLongFmt","monthShortFmt","monthLong","monthShort","m","weekdayLongFmt","weekdayShortFmt","weekdayLong","weekdayShort","dayPeriodFmt","am","pm","dayPeriod","vocab","escapeRegExp","literal","alternation","values","timeZoneFragment","getTimeZoneFragment","supportedValuesOf","NUMERIC_FRAGMENTS","tokenFragment","token","locale","numeric","vocab","getLocaleVocab","escapeRegExp","literal","buildCapturingPattern","pieces","locale","groups","source","i","piece","name","tokenFragment","getTemporal","temporal","patternCache","MAX_CACHE_SIZE","getPattern","formatStr","locale","key","pattern","oldestKey","buildCapturingPattern","tokenize","calendarCache","MAX_CALENDAR_CACHE_SIZE","resolveCalendar","resolved","calendar","applyGroup","fields","token","raw","getLocaleVocab","resolveYear","resolveHour","parse","input","options","DEFAULT_LOCALE","match","name","year","hour","month","day","minute","second","millisecond","timeZoneId","weekdayExpected","weekdayRaw","hasAnyDatePart","hasFullDate","hasTime","temporal","getTemporal","timeFields","calendarField","reject","result","err","actual","vocab"]}
1
+ {"version":3,"sources":["../src/tokens.ts","../src/tokenize.ts","../src/format.ts","../src/localeVocab.ts","../src/pattern.ts","../src/parsePattern.ts","../src/temporalGlobal.ts","../src/parse.ts"],"sourcesContent":["export function pad(n: number, len: number): string {\n return String(n).padStart(len, '0');\n}\n\n// Not every field exists on every Temporal type (PlainDate has no .hour,\n// etc). Callers check for undefined before formatting a token.\nexport interface TemporalLike {\n year?: number;\n month?: number;\n day?: number;\n hour?: number;\n minute?: number;\n second?: number;\n millisecond?: number;\n timeZoneId?: string;\n dayOfWeek?: number; // 1 (Mon) - 7 (Sun), per Temporal spec\n calendarId?: string;\n toInstant?: () => unknown;\n toLocaleString?: (locale: string, options: Intl.DateTimeFormatOptions) => string;\n}\n\nexport interface FormatOptions {\n /** BCP 47 locale tag, e.g. 'en-US', 'fr-FR', 'ar-EG'. Defaults to 'en-US'. */\n locale?: string;\n}\n\nexport const DEFAULT_LOCALE = 'en-US';\n\n// Intl.DateTimeFormat is expensive to construct and format() can run in a\n// loop (rendering a table of dates), so cache by (locale, options).\nconst formatterCache = new Map<string, Intl.DateTimeFormat>();\nconst MAX_CACHE_SIZE = 500;\n\nfunction getFormatter(locale: string, options: Intl.DateTimeFormatOptions): Intl.DateTimeFormat {\n const key = locale + JSON.stringify(options);\n let formatter = formatterCache.get(key);\n if (formatter) {\n return formatter;\n }\n if (formatterCache.size >= MAX_CACHE_SIZE) {\n // not real LRU, just evicts oldest insertion — fine for this key space\n const oldestKey = formatterCache.keys().next().value;\n if (oldestKey !== undefined) formatterCache.delete(oldestKey);\n }\n formatter = new Intl.DateTimeFormat(locale, options);\n formatterCache.set(key, formatter);\n return formatter;\n}\n\n// Passing a Temporal object straight into `new Intl.DateTimeFormat().formatToParts()`\n// only works when the engine's Intl implementation has special-cased support for\n// *native* Temporal instances (checked via internal slots and/or gated behind a V8 flag,\n// not tied to a specific Node version).\n// \n// A Temporal polyfill's instances don't have those slots, so the engine falls back to ToNumber() -> .valueOf(),\n// which the polyfill deliberately throws on (\"Cannot use valueOf\"). \n// Probed once and memoized and only from intlPart(), so it never\n// runs unless a format string actually uses a locale-aware token.\nlet nativeSupport: boolean | undefined;\nfunction intlSupportsNativeTemporal(): boolean {\n if (nativeSupport === undefined) {\n nativeSupport = false;\n const Temporal = (globalThis as { Temporal?: { PlainDate?: { from: (s: string) => unknown } } }).Temporal;\n if (Temporal?.PlainDate) {\n try {\n new Intl.DateTimeFormat('en-US', { day: 'numeric' }).formatToParts(Temporal.PlainDate.from('1970-01-01') as Date);\n nativeSupport = true;\n } catch {\n // native Temporal absent, or present but not recognized by Intl — fall back\n }\n }\n }\n return nativeSupport;\n}\n\nfunction intlPart(\n temporal: TemporalLike,\n locale: string,\n options: Intl.DateTimeFormatOptions,\n partType: Intl.DateTimeFormatPartTypes\n): string {\n // Intl throws \"Mismatching Calendars\" if the formatter's calendar doesn't\n // match the object's own (e.g. en-US formatter defaults to gregory, but\n // a hebrew/islamic PlainDate needs its own calendar passed through).\n //\n // skip this for iso8601 specifically — passing `calendar: 'iso8601'`\n // explicitly alongside a single-field options object makes formatToParts()\n // come back empty for some reason.\n const calendar = temporal?.calendarId;\n const formatterOptions: Intl.DateTimeFormatOptions = {\n ...options,\n ...(calendar && calendar !== 'iso8601' ? { calendar } : {}),\n };\n\n // Temporal.prototype.toLocaleString() is part of the Temporal spec itself:\n // polyfills implement the ICU formatting internally without needing the\n // engine to recognize the object, so it works without native Intl support.\n if (!intlSupportsNativeTemporal()) {\n return temporal.toLocaleString!(locale, formatterOptions);\n }\n\n // formatToParts() throws on ZonedDateTime directly (per spec), so convert\n // to Instant and pass the zone via `timeZone` instead. Don't convert to\n // PlainDateTime — that drops the zone, which breaks 'MMMM' + 'zzz' combos.\n const { toInstant, timeZoneId } = temporal;\n const isZoned = typeof toInstant === 'function' && typeof timeZoneId === 'string';\n // has to be called as temporal.toInstant() because destructuring it off breaks\n // the receiver and throws\n const intlSafeTemporal = isZoned ? temporal.toInstant!() : temporal;\n const nativeOptions: Intl.DateTimeFormatOptions = {\n ...formatterOptions,\n ...(isZoned ? { timeZone: timeZoneId } : {}),\n };\n\n const formatter = getFormatter(locale, nativeOptions);\n const parts = formatter.formatToParts(intlSafeTemporal as Date | number);\n const part = parts.find((p) => p.type === partType);\n if (!part) {\n throw new Error(\n `temporal-fmt: locale \"${locale}\" produced no \"${partType}\" part for this token. ` +\n `This usually means the Temporal object is missing the field the token needs.`\n );\n }\n return part.value;\n}\n\n\n// Temporal.prototype.toLocaleString() can't isolate a single field the way formatToParts() can\n// — asking for `hour` + `dayPeriod` together returns one joined string (e.g.\n// \"3 in the afternoon\"), and asking for `dayPeriod` alone silently resolves\n// against a different, non-hour-anchored set of periods (produces \"in the\n// afternoon\"/\"昼\" instead of the \"PM\"/\"午後\" that pairing it with hour12\n// actually renders).\n// \n// On using this instead of temporal:\n// Day period only depends on the hour, not on the calendar or the date, \n// so always route it through a plain UTC Date instead\n// Intl.DateTimeFormat has always accepted Date objects, on every engine,\n// independent of whether Temporal itself is native or polyfilled.\nfunction dayPeriodPart(hour: number, locale: string): string {\n const date = new Date(Date.UTC(1970, 0, 1, hour));\n const formatter = getFormatter(locale, { hour: 'numeric', hour12: true, timeZone: 'UTC' });\n const part = formatter.formatToParts(date).find((p) => p.type === 'dayPeriod');\n if (!part) {\n throw new Error(`temporal-fmt: locale \"${locale}\" produced no \"dayPeriod\" part for token \"a\".`);\n }\n return part.value;\n}\n\ntype TokenHandler = (t: TemporalLike, locale: string) => string;\n\n// Longest-first — tokenizer is greedy, \"yyyy\" has to be tried before \"yy\".\n//\n// Numeric tokens always render in ASCII digits, never locale-native\n// (Arabic-Indic, Devanagari, etc). Padding non-ASCII digit strings to a\n// fixed width isn't the same operation as padding \"3\", and most consumers\n// parsing these back out want plain digits anyway.\nexport const TOKENS: Array<[string, TokenHandler, keyof TemporalLike]> = [\n ['yyyy', (t) => pad(t.year!, 4), 'year'],\n ['yy', (t) => {\n // -45 % 100 === -45, so truncating negative years to 2 digits doesn't\n // work and Math.abs() would make 45 CE and 45 BCE render the same.\n if (t.year! < 0) {\n throw new Error(\n `temporal-fmt: token \"yy\" doesn't support negative years (got ${t.year}), ` +\n `since truncating to 2 digits would make it indistinguishable from a ` +\n `positive year. Use \"yyyy\" instead.`\n );\n }\n return pad(t.year! % 100, 2);\n }, 'year'],\n ['MMMM', (t, locale) => intlPart(t, locale, { month: 'long' }, 'month'), 'month'],\n ['MMM', (t, locale) => intlPart(t, locale, { month: 'short' }, 'month'), 'month'],\n ['MM', (t) => pad(t.month!, 2), 'month'],\n ['M', (t) => String(t.month!), 'month'],\n ['dd', (t) => pad(t.day!, 2), 'day'],\n ['d', (t) => String(t.day!), 'day'],\n ['EEEE', (t, locale) => intlPart(t, locale, { weekday: 'long' }, 'weekday'), 'dayOfWeek'],\n ['EEE', (t, locale) => intlPart(t, locale, { weekday: 'short' }, 'weekday'), 'dayOfWeek'],\n ['HH', (t) => pad(t.hour!, 2), 'hour'],\n ['H', (t) => String(t.hour!), 'hour'],\n ['hh', (t) => pad(t.hour! % 12 || 12, 2), 'hour'],\n ['h', (t) => String(t.hour! % 12 || 12), 'hour'],\n ['mm', (t) => pad(t.minute!, 2), 'minute'],\n ['m', (t) => String(t.minute!), 'minute'],\n ['ss', (t) => pad(t.second!, 2), 'second'],\n ['s', (t) => String(t.second!), 'second'],\n ['SSS', (t) => pad(t.millisecond!, 3), 'millisecond'],\n // dayPeriod text is locale-specific (AM/PM in en-US, م/ص in ar-EG) but\n // still needs .hour on the input to compute which period it is\n ['a', (t, locale) => dayPeriodPart(t.hour!, locale), 'hour'],\n ['zzz', (t) => t.timeZoneId!, 'timeZoneId'],\n];\n","import { TOKENS } from './tokens.js';\n\nexport type Piece =\n | { kind: 'token'; value: string }\n | { kind: 'literal'; value: string };\n\n// longest-first so the greedy scan never matches \"M\" when \"MMMM\" was there\nconst SORTED_TOKEN_STRINGS = TOKENS.map(([tok]) => tok).sort((a, b) => b.length - a.length);\n\n/**\n * Splits a format string like `\"yyyy-MM-dd 'at' HH:mm\"` into token/literal\n * pieces. Text in single quotes is always literal (e.g. write 'rd' in\n * \"3rd\" so it's not read as the day token). A doubled quote ('') means a\n * literal quote character, both inside a quoted span and standalone.\n */\nexport function tokenize(format: string): Piece[] {\n const pieces: Piece[] = [];\n let i = 0;\n\n while (i < format.length) {\n const ch = format[i];\n\n if (ch === \"'\") {\n // check doubled-quote first or \"''best''\" parses wrong\n if (format[i + 1] === \"'\") {\n appendLiteral(pieces, \"'\");\n i += 2;\n continue;\n }\n\n let j = i + 1;\n let literal = '';\n let closed = false;\n while (j < format.length) {\n if (format[j] === \"'\") {\n if (format[j + 1] === \"'\") {\n literal += \"'\";\n j += 2;\n continue;\n }\n closed = true;\n j += 1;\n break;\n }\n literal += format[j];\n j += 1;\n }\n\n if (!closed) {\n throw new Error(`temporal-fmt: unterminated quote in format string \"${format}\"`);\n }\n\n appendLiteral(pieces, literal);\n i = j;\n continue;\n }\n\n const match = SORTED_TOKEN_STRINGS.find((tok) => format.startsWith(tok, i));\n if (match) {\n pieces.push({ kind: 'token', value: match });\n i += match.length;\n continue;\n }\n\n // not a token or quote — pass through as-is \n appendLiteral(pieces, ch);\n i += 1;\n }\n\n return pieces;\n}\n\n// merges into the previous piece if it's also a literal, so \"---\" is one\n// piece instead of three\nfunction appendLiteral(pieces: Piece[], value: string): void {\n const last = pieces[pieces.length - 1];\n if (last && last.kind === 'literal') {\n last.value += value;\n } else {\n pieces.push({ kind: 'literal', value });\n }\n}\n","import { TOKENS, DEFAULT_LOCALE, type TemporalLike, type FormatOptions } from './tokens.js';\nimport { tokenize } from './tokenize.js';\nimport { MAX_FORMAT_LENGTH } from './constants.js';\n\nconst HANDLER_BY_TOKEN = new Map(TOKENS.map(([tok, fn, field]) => [tok, { fn, field }]));\n\n/**\n * Format a Temporal.PlainDate, PlainTime, PlainDateTime, or ZonedDateTime\n * using a date-fns-style token string.\n *\n * @example\n * format(Temporal.Now.plainDateISO(), 'yyyy-MM-dd') // \"2026-08-04\"\n * format(zdt, \"MMM d, yyyy 'at' h:mm a\") // \"Aug 4, 2026 at 3:45 PM\"\n * format(zdt, 'MMMM d, yyyy', { locale: 'fr-FR' }) // \"août 4, 2026\"\n * format(zdt, 'EEEE d MMMM', { locale: 'ar-EG' }) // Arabic weekday/month names\n *\n * Numeric fields always render in ASCII digits regardless of locale.\n * Named fields (MMMM, EEEE, a) are fully localized via Intl, including\n * non-Gregorian calendars if the Temporal object carries one.\n *\n * Throws if the format string uses a token the input type doesn't support\n * (e.g. 'HH' on a PlainDate) rather than silently printing \"undefined\".\n */\nexport function format(temporal: TemporalLike, formatStr: string, options: FormatOptions = {}): string {\n if (formatStr.length > MAX_FORMAT_LENGTH) {\n throw new Error(\n `temporal-fmt: format string exceeds maximum length of ${MAX_FORMAT_LENGTH} characters ` +\n `(got ${formatStr.length}).`\n );\n }\n\n const locale = options.locale ?? DEFAULT_LOCALE;\n const pieces = tokenize(formatStr);\n let result = '';\n\n for (const piece of pieces) {\n if (piece.kind === 'literal') {\n result += piece.value;\n continue;\n }\n\n const handler = HANDLER_BY_TOKEN.get(piece.value);\n if (!handler) {\n // shouldn't happen — tokenize() only emits tokens from TOKENS\n throw new Error(`temporal-fmt: unknown token \"${piece.value}\"`);\n }\n\n if (temporal[handler.field] === undefined) {\n throw new Error(\n `temporal-fmt: token \"${piece.value}\" requires \"${handler.field}\", ` +\n `which this Temporal object doesn't have. ` +\n `(e.g. PlainDate has no time fields, PlainTime has no date fields)`\n );\n }\n\n result += handler.fn(temporal, locale);\n }\n\n return result;\n}\n","// Closed-vocabulary lookups for locale-aware tokens (MMMM, MMM, EEEE, EEE, a).\n// Each set 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\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\nconst vocabCache = new Map<string, LocaleVocab>();\n\nfunction partValue(formatter: Intl.DateTimeFormat, date: Date, type: Intl.DateTimeFormatPartTypes): string {\n const part = formatter.formatToParts(date).find((p) => p.type === type);\n if (!part) {\n throw new Error(`temporal-fmt: locale produced no \"${type}\" part while building match vocabulary.`);\n }\n return part.value;\n}\n\nexport function getLocaleVocab(locale: string): LocaleVocab {\n const cached = vocabCache.get(locale);\n if (cached) {\n return cached;\n }\n\n const monthLongFmt = new Intl.DateTimeFormat(locale, { month: 'long', timeZone: 'UTC' });\n const monthShortFmt = new Intl.DateTimeFormat(locale, { 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\n const weekdayLongFmt = new Intl.DateTimeFormat(locale, { weekday: 'long', timeZone: 'UTC' });\n const weekdayShortFmt = new Intl.DateTimeFormat(locale, { 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\n const dayPeriodFmt = new Intl.DateTimeFormat(locale, { 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 vocabCache.set(locale, vocab);\n return vocab;\n}\n","import { getLocaleVocab } from './localeVocab.js';\n\nfunction escapeRegExp(literal: string): string {\n return literal.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nfunction alternation(values: string[]): string {\n return `(?:${values.map(escapeRegExp).join('|')})`;\n}\n\nlet timeZoneFragment: string | undefined;\n\nfunction getTimeZoneFragment(): string {\n if (timeZoneFragment) {\n return timeZoneFragment;\n }\n const supportedValuesOf = (Intl as unknown as { supportedValuesOf?: (key: string) => string[] }).supportedValuesOf;\n if (typeof supportedValuesOf === 'function') {\n // supportedValuesOf('timeZone') leaves out 'UTC', but format() can\n // produce it from a real ZonedDateTime — without this, parse() couldn't\n // parse our own library's own output back.\n timeZoneFragment = alternation([...supportedValuesOf('timeZone'), 'UTC']);\n } else {\n // no Intl.supportedValuesOf — match on shape only\n timeZoneFragment = '[A-Za-z_]+(?:\\\\/[A-Za-z_+\\\\-0-9]+)+|UTC';\n }\n return timeZoneFragment;\n}\n\n// mirrors the ranges pad() in tokens.ts actually produces — keep in sync\n// if those ever change\nconst NUMERIC_FRAGMENTS: Record<string, string> = {\n yyyy: '\\\\d{4}',\n yy: '\\\\d{2}',\n MM: '(?:0[1-9]|1[0-2])',\n M: '(?:[1-9]|1[0-2])',\n dd: '(?:0[1-9]|[12]\\\\d|3[01])',\n d: '(?:[1-9]|[12]\\\\d|3[01])',\n HH: '(?:[01]\\\\d|2[0-3])',\n H: '(?:[0-9]|1\\\\d|2[0-3])',\n hh: '(?:0[1-9]|1[0-2])',\n h: '(?:[1-9]|1[0-2])',\n mm: '(?:[0-5]\\\\d)',\n m: '(?:[0-9]|[1-5]\\\\d)',\n ss: '(?:[0-5]\\\\d)',\n s: '(?:[0-9]|[1-5]\\\\d)',\n SSS: '\\\\d{3}',\n};\n\nexport function tokenFragment(token: string, locale: string): string {\n const numeric = NUMERIC_FRAGMENTS[token];\n if (numeric) {\n return numeric;\n }\n\n const vocab = getLocaleVocab(locale);\n switch (token) {\n case 'MMMM': return alternation(vocab.monthLong);\n case 'MMM': return alternation(vocab.monthShort);\n case 'EEEE': return alternation(vocab.weekdayLong);\n case 'EEE': return alternation(vocab.weekdayShort);\n case 'a': return alternation(vocab.dayPeriod);\n case 'zzz': return getTimeZoneFragment();\n default:\n throw new Error(`temporal-fmt: unknown token \"${token}\"`);\n }\n}\n","import type { Piece } from './tokenize.js';\nimport { tokenFragment } from './pattern.js';\n\nfunction escapeRegExp(literal: string): string {\n return literal.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nexport interface CapturingPattern {\n regex: RegExp;\n groups: Array<{ name: string; token: string }>; // token pieces, in order\n}\n\n/**\n * Same walk as buildPatternSource() in pattern.ts, but each token piece\n * gets its own named capture group (positionally named so the same token,\n * e.g. \"yyyy\", could in theory appear twice) so a caller can pull the\n * matched substring for each token back out after a successful match.\n */\nexport function buildCapturingPattern(pieces: Piece[], locale: string): CapturingPattern {\n const groups: Array<{ name: string; token: string }> = [];\n let source = '';\n let i = 0;\n\n for (const piece of pieces) {\n if (piece.kind === 'literal') {\n source += escapeRegExp(piece.value);\n continue;\n }\n const name = `g${i++}`;\n groups.push({ name, token: piece.value });\n source += `(?<${name}>${tokenFragment(piece.value, locale)})`;\n }\n\n return { regex: new RegExp(`^(?:${source})$`, 'u'), groups };\n}\n","// This package's tsconfig assumes lib: [\"ESNext\"] only — no ambient\n// `Temporal` namespace type. Everywhere else in this codebase only ever\n// *reads* fields off a Temporal-like object the caller already built\n// (TemporalLike in tokens.ts). parse() is the first place that needs to\n// *construct* one, via the global `Temporal` the README already requires\n// consumers to provide (native on Node 26+, or a polyfill). Kept loosely\n// typed on purpose, consistent with the rest of the codebase.\ninterface TemporalFactory {\n from(fields: Record<string, number | string | undefined>, options?: { overflow?: 'constrain' | 'reject' }): unknown;\n}\n\nexport interface TemporalNamespace {\n PlainDate: TemporalFactory;\n PlainTime: TemporalFactory;\n PlainDateTime: TemporalFactory;\n ZonedDateTime: TemporalFactory;\n}\n\nexport function getTemporal(): TemporalNamespace {\n const temporal = (globalThis as unknown as { Temporal?: TemporalNamespace }).Temporal;\n if (!temporal) {\n throw new Error(\n 'temporal-fmt: parse() needs a global `Temporal` to construct its result. ' +\n 'Native on Node 26+, or assign a polyfill (e.g. temporal-polyfill) to globalThis.Temporal first.'\n );\n }\n return temporal;\n}\n","import { DEFAULT_LOCALE, type FormatOptions } from './tokens.js';\nimport { tokenize } from './tokenize.js';\nimport { buildCapturingPattern, type CapturingPattern } from './parsePattern.js';\nimport { getLocaleVocab } from './localeVocab.js';\nimport { getTemporal } from './temporalGlobal.js';\nimport { MAX_FORMAT_LENGTH } from './constants.js';\n\n// format strings are short hand-written literals reused across many calls —\n// cache the compiled capturing pattern per (formatStr, locale) pair instead\n// of rebuilding it every call.\nconst patternCache = new Map<string, CapturingPattern>();\nconst MAX_CACHE_SIZE = 500;\n\nfunction getPattern(formatStr: string, locale: string): CapturingPattern {\n const key = locale + ' ' + formatStr;\n let pattern = patternCache.get(key);\n if (pattern) {\n return pattern;\n }\n if (patternCache.size >= MAX_CACHE_SIZE) {\n const oldestKey = patternCache.keys().next().value;\n if (oldestKey !== undefined) patternCache.delete(oldestKey);\n }\n pattern = buildCapturingPattern(tokenize(formatStr), locale);\n patternCache.set(key, pattern);\n return pattern;\n}\n\n// Intl.DateTimeFormat(locale).resolvedOptions().calendar reports the\n// locale's default calendar so passing locale with a `-u-ca-` extension in the tag\n// allows setting non-gregorian calendars. 'gregory' is treated as \"no calendar\" so\n// the default locale ('en-US') keeps constructing plain ISO 8601\nconst calendarCache = new Map<string, string | undefined>();\nconst MAX_CALENDAR_CACHE_SIZE = 500;\n\nfunction resolveCalendar(locale: string): string | undefined {\n if (calendarCache.has(locale)) {\n return calendarCache.get(locale);\n }\n if (calendarCache.size >= MAX_CALENDAR_CACHE_SIZE) {\n const oldestKey = calendarCache.keys().next().value;\n if (oldestKey !== undefined) calendarCache.delete(oldestKey);\n }\n const resolved = new Intl.DateTimeFormat(locale).resolvedOptions().calendar;\n const calendar = resolved === 'gregory' ? undefined : resolved;\n calendarCache.set(locale, calendar);\n return calendar;\n}\n\ninterface Fields {\n year?: number;\n twoDigitYear?: number;\n month?: number;\n day?: number;\n hour?: number;\n hour12?: number;\n isPM?: boolean;\n minute?: number;\n second?: number;\n millisecond?: number;\n timeZoneId?: string;\n weekdayExpected?: number; // ISO dayOfWeek, 1 (Mon) - 7 (Sun)\n weekdayRaw?: string;\n}\n\nfunction applyGroup(fields: Fields, token: string, raw: string, locale: string): void {\n switch (token) {\n case 'yyyy': fields.year = parseInt(raw, 10); break;\n case 'yy': fields.twoDigitYear = parseInt(raw, 10); break;\n case 'MM': case 'M': fields.month = parseInt(raw, 10); break;\n case 'MMMM': fields.month = getLocaleVocab(locale).monthLong.indexOf(raw) + 1; break;\n case 'MMM': fields.month = getLocaleVocab(locale).monthShort.indexOf(raw) + 1; break;\n case 'dd': case 'd': fields.day = parseInt(raw, 10); break;\n case 'EEEE':\n fields.weekdayRaw = raw;\n fields.weekdayExpected = getLocaleVocab(locale).weekdayLong.indexOf(raw) + 1;\n break;\n case 'EEE':\n fields.weekdayRaw = raw;\n fields.weekdayExpected = getLocaleVocab(locale).weekdayShort.indexOf(raw) + 1;\n break;\n case 'HH': case 'H': fields.hour = parseInt(raw, 10); break;\n case 'hh': case 'h': fields.hour12 = parseInt(raw, 10); break;\n case 'mm': case 'm': fields.minute = parseInt(raw, 10); break;\n case 'ss': case 's': fields.second = parseInt(raw, 10); break;\n case 'SSS': fields.millisecond = parseInt(raw, 10); break;\n case 'a': fields.isPM = raw === getLocaleVocab(locale).dayPeriod[1]; break;\n case 'zzz': fields.timeZoneId = raw; break;\n }\n}\n\n/**\n * Resolves year value into 4-digit year\n * \n * For 2-digit values it emulates strptime (POSIX)\n * so that resolving value is not clock-dependent\n * \n * * 00-68 -> 2000-2068\n * * 69-99 -> 1900-1999\n * \n * @see https://www.man7.org/linux//man-pages/man3/strptime.3p.html\n */\nfunction resolveYear(fields: Fields): number | undefined {\n if (fields.year !== undefined) return fields.year;\n if (fields.twoDigitYear !== undefined) {\n return fields.twoDigitYear <= 68 ? 2000 + fields.twoDigitYear : 1900 + fields.twoDigitYear;\n }\n return undefined;\n}\n\nfunction resolveHour(fields: Fields, formatStr: string): number | undefined {\n if (fields.hour !== undefined && fields.hour12 !== undefined) {\n throw new Error(\n `temporal-fmt: format string \"${formatStr}\" mixes a 24-hour token (\"HH\"/\"H\") with a ` +\n `12-hour token (\"hh\"/\"h\"). Pick one or the other — parse() won't guess which is authoritative.`\n );\n }\n if (fields.hour !== undefined) return fields.hour;\n if (fields.hour12 !== undefined) {\n if (fields.isPM === undefined) {\n throw new Error(\n `temporal-fmt: format string \"${formatStr}\" uses a 12-hour token (\"hh\"/\"h\") without an \"a\" token, ` +\n `so parse() can't tell AM from PM.`\n );\n }\n return (fields.hour12 % 12) + (fields.isPM ? 12 : 0);\n }\n return undefined;\n}\n\n/**\n * Parses `input` against `formatStr` and builds the real Temporal value it\n * describes: a `Temporal.PlainDate`, `PlainTime`, `PlainDateTime`, or\n * `ZonedDateTime` depending on which tokens are present.\n * \n * Value is returned as `unknown` since this package assumes no ambient `Temporal` types.\n *\n * Optionally, `options.locale` picks the calendar the result is built in. Pass a\n * locale tag with a `-u-ca-` extension (e.g. `'en-u-ca-hebrew'`) to parse\n * into a non-Gregorian calendar.\n * \n * @throws if `input` doesn't match `formatStr`'s shape at all\n * @throws if it matches the shape but escribes an impossible date (e.g. Feb 30)\n * or self-contradictory data (e.g. a weekday name that doesn't match the actual date)\n *\n * @example\n * parse('yyyy-MM-dd HH:mm', '2026-08-04 15:45') // Temporal.PlainDateTime\n * parse('yyyy-MM', '2026-08-04T15:45:30') // throws — not a valid pattern and input shape\n * parse('yyyy-MM-dd', '2026-02-30') // throws — not a real date\n */\nexport function parse(formatStr: string, input: string, options: FormatOptions = {}): unknown | undefined {\n if (formatStr.length > MAX_FORMAT_LENGTH) {\n throw new Error(\n `temporal-fmt: format string exceeds maximum length of ${MAX_FORMAT_LENGTH} characters ` +\n `(got ${formatStr.length}).`\n );\n }\n\n const locale = options.locale ?? DEFAULT_LOCALE;\n const calendar = resolveCalendar(locale);\n const pattern = getPattern(formatStr, locale);\n const match = pattern.regex.exec(input);\n if (!match) {\n throw new Error(`temporal-fmt: no valid pattern matches the format string and input shape`);\n }\n\n if (pattern.groups.length === 0) {\n throw new Error(`temporal-fmt: format string \"${formatStr}\" has no tokens — nothing to parse into a value.`);\n }\n\n const fields: Fields = {};\n for (const { name, token } of pattern.groups) {\n applyGroup(fields, token, match.groups![name]!, locale);\n }\n\n const year = resolveYear(fields);\n const hour = resolveHour(fields, formatStr);\n const { month, day, minute, second, millisecond, timeZoneId, weekdayExpected, weekdayRaw } = fields;\n\n const hasAnyDatePart = year !== undefined || month !== undefined || day !== undefined;\n const hasFullDate = year !== undefined && month !== undefined && day !== undefined;\n if (hasAnyDatePart && !hasFullDate) {\n throw new Error(\n `temporal-fmt: format string \"${formatStr}\" has an incomplete date — ` +\n `year, month, and day tokens must all be present together.`\n );\n }\n\n const hasTime = hour !== undefined || minute !== undefined || second !== undefined || millisecond !== undefined;\n\n if (timeZoneId !== undefined && !(hasFullDate && hasTime)) {\n throw new Error(\n `temporal-fmt: format string \"${formatStr}\" has a \"zzz\" token but needs a full date and time ` +\n `to build a ZonedDateTime.`\n );\n }\n\n if (weekdayExpected !== undefined && !hasFullDate) {\n throw new Error(\n `temporal-fmt: format string \"${formatStr}\" has a weekday token (\"EEEE\"/\"EEE\") but needs ` +\n `a full date to validate it against.`\n );\n }\n\n if (!hasFullDate && !hasTime) {\n // shouldn't happen — every token maps to a date, time, zone, or\n // weekday field, and weekday-without-date already threw above\n throw new Error(`temporal-fmt: format string \"${formatStr}\" has no date or time tokens to parse.`);\n }\n\n const temporal = getTemporal();\n const timeFields = { hour: hour ?? 0, minute: minute ?? 0, second: second ?? 0, millisecond: millisecond ?? 0 };\n // omitted entirely for the default calendar (see resolveCalendar) so\n // construction stays plain ISO 8601 unless a caller's locale asks for\n // something else — Temporal calendars don't apply to time-only values.\n const calendarField = calendar ? { calendar } : {};\n\n // overflow: 'reject' — without it Temporal *clamps* out-of-range fields\n // (Feb 30 silently becomes Feb 28) instead of throwing, which would\n // contradict the \"throws on genuinely invalid data\" behavior parse() promises.\n const reject = { overflow: 'reject' as const };\n\n let result: unknown;\n try {\n if (timeZoneId !== undefined) {\n result = temporal.ZonedDateTime.from({ year: year!, month: month!, day: day!, ...timeFields, ...calendarField, timeZone: timeZoneId }, reject);\n } else if (hasFullDate && hasTime) {\n result = temporal.PlainDateTime.from({ year: year!, month: month!, day: day!, ...timeFields, ...calendarField }, reject);\n } else if (hasFullDate) {\n result = temporal.PlainDate.from({ year: year!, month: month!, day: day!, ...calendarField }, reject);\n } else {\n result = temporal.PlainTime.from(timeFields, reject);\n }\n } catch (err) {\n throw new Error(\n `temporal-fmt: \"${input}\" doesn't describe a valid date/time for format \"${formatStr}\": ` +\n `${(err as Error).message}`\n );\n }\n\n if (weekdayExpected !== undefined) {\n const actual = (result as { dayOfWeek: number }).dayOfWeek;\n if (actual !== weekdayExpected) {\n const vocab = getLocaleVocab(locale);\n throw new Error(\n `temporal-fmt: \"${weekdayRaw}\" doesn't match the actual weekday (${vocab.weekdayLong[actual - 1]}) ` +\n `for the parsed date.`\n );\n }\n }\n\n return result;\n}\n"],"mappings":"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","names":["pad","n","len","DEFAULT_LOCALE","formatterCache","MAX_CACHE_SIZE","getFormatter","locale","options","key","formatter","oldestKey","nativeSupport","intlSupportsNativeTemporal","Temporal","intlPart","temporal","partType","calendar","formatterOptions","toInstant","timeZoneId","isZoned","intlSafeTemporal","nativeOptions","part","p","dayPeriodPart","hour","date","TOKENS","t","SORTED_TOKEN_STRINGS","TOKENS","tok","a","b","tokenize","format","pieces","i","ch","appendLiteral","j","literal","closed","match","value","last","HANDLER_BY_TOKEN","TOKENS","tok","fn","field","format","temporal","formatStr","options","locale","DEFAULT_LOCALE","pieces","tokenize","result","piece","handler","vocabCache","partValue","formatter","date","type","part","p","getLocaleVocab","locale","cached","monthLongFmt","monthShortFmt","monthLong","monthShort","m","weekdayLongFmt","weekdayShortFmt","weekdayLong","weekdayShort","dayPeriodFmt","am","pm","dayPeriod","vocab","escapeRegExp","literal","alternation","values","timeZoneFragment","getTimeZoneFragment","supportedValuesOf","NUMERIC_FRAGMENTS","tokenFragment","token","locale","numeric","vocab","getLocaleVocab","escapeRegExp","literal","buildCapturingPattern","pieces","locale","groups","source","i","piece","name","tokenFragment","getTemporal","temporal","patternCache","MAX_CACHE_SIZE","getPattern","formatStr","locale","key","pattern","oldestKey","buildCapturingPattern","tokenize","calendarCache","MAX_CALENDAR_CACHE_SIZE","resolveCalendar","resolved","calendar","applyGroup","fields","token","raw","getLocaleVocab","resolveYear","resolveHour","parse","input","options","DEFAULT_LOCALE","match","name","year","hour","month","day","minute","second","millisecond","timeZoneId","weekdayExpected","weekdayRaw","hasAnyDatePart","hasFullDate","hasTime","temporal","getTemporal","timeFields","calendarField","reject","result","err","actual","vocab"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "temporal-fmt",
3
- "version": "0.7.0",
3
+ "version": "0.7.2",
4
4
  "description": "Format Temporal.PlainDate/PlainDateTime/PlainTime/ZonedDateTime objects using date-fns-style token strings.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",