@@ -16,6 +16,7 @@ const uniqAndSortArray = pipe([uniq, sortArray])
1616const onObject = ( fn ) => ( x ) => ( isPlainObject ( x ) ? fn ( x ) : x )
1717const sortObjectBy = ( comparator , deep ) => {
1818 const over = onObject ( ( object ) => {
19+ // TODO: check for comments and update comparator accordingly
1920 object = sortObjectKeys ( object , comparator )
2021 if ( deep ) {
2122 for ( const [ key , value ] of Object . entries ( object ) ) {
@@ -132,6 +133,7 @@ const defaultNpmScripts = new Set([
132133] )
133134
134135const sortScripts = onObject ( ( scripts ) => {
136+ // TODO: apply comments extraction and re-application here.
135137 const names = Object . keys ( scripts )
136138 const prefixable = new Set ( )
137139
@@ -309,6 +311,7 @@ function editStringJSON(json, over) {
309311}
310312
311313const isPrivateKey = ( key ) => key [ 0 ] === '_'
314+ const isCommentKey = ( key ) => key . trim ( ) . startsWith ( '//' )
312315const partition = ( array , predicate ) =>
313316 array . reduce (
314317 ( result , value ) => {
@@ -317,21 +320,52 @@ const partition = (array, predicate) =>
317320 } ,
318321 [ [ ] , [ ] ] ,
319322 )
323+ const removeAndGatherComments = ( keys , predicate ) =>
324+ keys . reduceRight (
325+ ( result , key ) => {
326+ const prev = result [ 0 ] [ 0 ]
327+ ; ( predicate ( key )
328+ ? prev
329+ ? result [ 1 ] [ prev ] || ( result [ 1 ] [ prev ] = [ ] )
330+ : result [ 2 ]
331+ : result [ 0 ]
332+ ) . unshift ( key )
333+ return result
334+ } ,
335+ // 0: non-comment keys and trailing comments
336+ // 1: comments that precede a key
337+ // 2: trailing comments
338+ [ [ ] , { } , [ ] ] ,
339+ )
320340function sortPackageJson ( jsonIsh , options = { } ) {
321341 return editStringJSON (
322342 jsonIsh ,
323343 onObject ( ( json ) => {
324344 let sortOrder = options . sortOrder ? options . sortOrder : defaultSortOrder
325345
326346 if ( Array . isArray ( sortOrder ) ) {
327- const keys = Object . keys ( json )
347+ const allKeys = Object . keys ( json )
348+ const [ keys , comments , trailing ] = removeAndGatherComments (
349+ allKeys ,
350+ isCommentKey ,
351+ )
328352 const [ privateKeys , publicKeys ] = partition ( keys , isPrivateKey )
329353 sortOrder = [
330354 ...sortOrder ,
331355 ...defaultSortOrder ,
332356 ...publicKeys . sort ( ) ,
333357 ...privateKeys . sort ( ) ,
358+ ...trailing ,
334359 ]
360+ if ( allKeys . length !== keys . length ) {
361+ // re-add comment keys
362+ for ( let i = sortOrder . length - 1 ; i >= 0 ; i -- ) {
363+ const c = comments [ sortOrder [ i ] ]
364+ if ( c ) {
365+ sortOrder . splice ( i , 0 , ...c )
366+ }
367+ }
368+ }
335369 }
336370
337371 return overFields ( sortObjectKeys ( json , sortOrder ) )
0 commit comments