@@ -1856,7 +1856,7 @@ test('should patch date field from example toml', () => {
18561856
18571857 [owner]
18581858 name = "Tom Preston-Werner"
1859- dob = 1979-05-28T07:32:00Z # First class dates? Why not?
1859+ dob = 1979-05-28T07:32:00Z # First class dates? Why not?
18601860
18611861 [database]
18621862 enabled = true
@@ -2188,6 +2188,170 @@ test('should patch offset datetime with milliseconds and preserve precision', ()
21882188 ` + '\n' ) ;
21892189} ) ;
21902190
2191+ test ( 'should preserve aligned inline comments when patching mixed date kinds with regular Date values' , ( ) => {
2192+ const existing = dedent `
2193+ # Demo fixture covering TOML date and time value kinds
2194+ title = "Date parser demo"
2195+
2196+ [dates]
2197+ offset_date_time = 1979-05-28T07:32:00-08:00 # offset date-time
2198+ local_date_time = 1979-05-28T07:32:00 # local date-time
2199+ local_date = 1979-05-28 # local date
2200+ local_time = 07:32:00 # local time
2201+
2202+ [events]
2203+ published_at = 2026-04-17T09:15:30Z # UTC timestamp
2204+ cutoff_time = 18:45:00 # time only
2205+ release_day = 2026-05-02 # date only
2206+ ` + '\n' ;
2207+
2208+ type Operation = { keyPath : string ; changed : boolean } ;
2209+
2210+ const ONE_DAY_IN_MS = 24 * 60 * 60 * 1000 ;
2211+ const TIME_ONLY_RE = / ^ \d { 2 } : \d { 2 } (?: : \d { 2 } ) ? (?: \. \d + ) ? $ / u;
2212+ const value = parse ( existing ) ;
2213+ const operations : Operation [ ] = [ ] ;
2214+
2215+ const incrementDateValues = ( input : Record < string , unknown > , pathParts : string [ ] ) => {
2216+ for ( const [ key , nestedValue ] of Object . entries ( input ) ) {
2217+ const nextPath = [ ...pathParts , key ] ;
2218+
2219+ if ( nestedValue instanceof Date && TIME_ONLY_RE . test ( nestedValue . toISOString ( ) ) ) {
2220+ operations . push ( { keyPath : nextPath . join ( '.' ) , changed : false } ) ;
2221+ continue ;
2222+ }
2223+
2224+ if ( nestedValue instanceof Date ) {
2225+ input [ key ] = new Date ( nestedValue . getTime ( ) + ONE_DAY_IN_MS ) ;
2226+ operations . push ( { keyPath : nextPath . join ( '.' ) , changed : true } ) ;
2227+ continue ;
2228+ }
2229+
2230+ if ( ! nestedValue || typeof nestedValue !== 'object' ) {
2231+ continue ;
2232+ }
2233+
2234+ incrementDateValues ( nestedValue as Record < string , unknown > , nextPath ) ;
2235+ }
2236+ } ;
2237+
2238+ incrementDateValues ( value as Record < string , unknown > , [ ] ) ;
2239+
2240+ expect ( operations . filter ( operation => operation . changed ) . map ( operation => operation . keyPath ) ) . toEqual ( [
2241+ 'dates.offset_date_time' ,
2242+ 'dates.local_date_time' ,
2243+ 'dates.local_date' ,
2244+ 'events.published_at' ,
2245+ 'events.release_day'
2246+ ] ) ;
2247+
2248+ expect ( operations . filter ( operation => ! operation . changed ) . map ( operation => operation . keyPath ) ) . toEqual ( [
2249+ 'dates.local_time' ,
2250+ 'events.cutoff_time'
2251+ ] ) ;
2252+
2253+ const patched = patch ( existing , value ) ;
2254+
2255+ expect ( patched ) . toEqual ( dedent `
2256+ # Demo fixture covering TOML date and time value kinds
2257+ title = "Date parser demo"
2258+
2259+ [dates]
2260+ offset_date_time = 1979-05-29T07:32:00-08:00 # offset date-time
2261+ local_date_time = 1979-05-29T07:32:00 # local date-time
2262+ local_date = 1979-05-29 # local date
2263+ local_time = 07:32:00 # local time
2264+
2265+ [events]
2266+ published_at = 2026-04-18T09:15:30Z # UTC timestamp
2267+ cutoff_time = 18:45:00 # time only
2268+ release_day = 2026-05-03 # date only
2269+ ` + '\n' ) ;
2270+ } ) ;
2271+
2272+ test ( 'should preserve aligned inline comments when patching single-line basic strings, arrays and numbers with same width' , ( ) => {
2273+ const existing = dedent `
2274+ # Demo fixture covering strings, arrays and number value kinds
2275+ title = "Release plan" # single-line basic string
2276+ retry_count = 3 # integer
2277+ error_rate = 0.125 # float
2278+ build_numbers = [1, 2, 3] # inline array
2279+
2280+ [service]
2281+ display_name = "API" # string in table
2282+ ports = [8080, 8081] # array in table
2283+ timeout_ms = 1500 # number in table
2284+ ` + '\n' ;
2285+
2286+ const value = parse ( existing ) ;
2287+
2288+ value . title = 'Sprint notes' ;
2289+ value . retry_count = 7 ;
2290+ value . error_rate = 0.875 ;
2291+ value . build_numbers = [ 2 , 4 , 6 ] ;
2292+ value . service . display_name = 'CLI' ;
2293+ value . service . ports = [ 9000 , 9001 ] ;
2294+ value . service . timeout_ms = 2500 ;
2295+
2296+ const patched = patch ( existing , value ) ;
2297+
2298+ expect ( patched ) . toEqual ( dedent `
2299+ # Demo fixture covering strings, arrays and number value kinds
2300+ title = "Sprint notes" # single-line basic string
2301+ retry_count = 7 # integer
2302+ error_rate = 0.875 # float
2303+ build_numbers = [2, 4, 6] # inline array
2304+
2305+ [service]
2306+ display_name = "CLI" # string in table
2307+ ports = [9000, 9001] # array in table
2308+ timeout_ms = 2500 # number in table
2309+ ` + '\n' ) ;
2310+ } ) ;
2311+
2312+ // TODO: Implement comments alignment detection across lines to preserve
2313+ // even when value width changes. This is currently not supported,
2314+ // so the test is skipped.
2315+ test . skip ( 'should preserve aligned inline comments when patching single-line basic strings, arrays and numbers with different width' , ( ) => {
2316+ const existing = dedent `
2317+ # Demo fixture covering strings, arrays and number value kinds
2318+ title = "Release plan" # single-line basic string
2319+ retry_count = 3 # integer
2320+ error_rate = 0.125 # float
2321+ build_numbers = [1, 2, 3] # inline array
2322+
2323+ [service]
2324+ display_name = "API" # string in table
2325+ ports = [8080, 8081] # array in table
2326+ timeout_ms = 1500 # number in table
2327+ ` + '\n' ;
2328+
2329+ const value = parse ( existing ) ;
2330+
2331+ value . title = 'Release plan v2' ;
2332+ value . retry_count = 12 ;
2333+ value . error_rate = 0.5 ;
2334+ value . build_numbers = [ 1 , 2 , 3 , 5 , 8 ] ;
2335+ value . service . display_name = 'API Gateway' ;
2336+ value . service . ports = [ 8080 , 8081 , 8082 ] ;
2337+ value . service . timeout_ms = 25000 ;
2338+
2339+ const patched = patch ( existing , value ) ;
2340+
2341+ expect ( patched ) . toEqual ( dedent `
2342+ # Demo fixture covering strings, arrays and number value kinds
2343+ title = "Release plan v2" # single-line basic string
2344+ retry_count = 12 # integer
2345+ error_rate = 0.5 # float
2346+ build_numbers = [1, 2, 3, 5, 8] # inline array
2347+
2348+ [service]
2349+ display_name = "API Gateway" # string in table
2350+ ports = [8080, 8081, 8082] # array in table
2351+ timeout_ms = 25000 # number in table
2352+ ` + '\n' ) ;
2353+ } ) ;
2354+
21912355describe ( 'should preserve all TOML date/time formats when patching' , ( ) => {
21922356 const testCases = [
21932357 {
0 commit comments