@@ -16,6 +16,7 @@ const uniqAndSortArray = pipe([uniq, sortArray])
16
16
const onObject = ( fn ) => ( x ) => ( isPlainObject ( x ) ? fn ( x ) : x )
17
17
const sortObjectBy = ( comparator , deep ) => {
18
18
const over = onObject ( ( object ) => {
19
+ // TODO: check for comments and update comparator accordingly
19
20
object = sortObjectKeys ( object , comparator )
20
21
if ( deep ) {
21
22
for ( const [ key , value ] of Object . entries ( object ) ) {
@@ -132,6 +133,7 @@ const defaultNpmScripts = new Set([
132
133
] )
133
134
134
135
const sortScripts = onObject ( ( scripts ) => {
136
+ // TODO: apply comments extraction and re-application here.
135
137
const names = Object . keys ( scripts )
136
138
const prefixable = new Set ( )
137
139
@@ -309,6 +311,7 @@ function editStringJSON(json, over) {
309
311
}
310
312
311
313
const isPrivateKey = ( key ) => key [ 0 ] === '_'
314
+ const isCommentKey = ( key ) => key . trim ( ) . startsWith ( '//' )
312
315
const partition = ( array , predicate ) =>
313
316
array . reduce (
314
317
( result , value ) => {
@@ -317,21 +320,52 @@ const partition = (array, predicate) =>
317
320
} ,
318
321
[ [ ] , [ ] ] ,
319
322
)
323
+ const removeAndGatherComments = ( keys , predicate ) =>
324
+ keys . reduceRight (
325
+ ( result , key ) => {
326
+ const prev = result [ 0 ] [ 0 ]
327
+ ; ( predicate ( key )
328
+ ? result [ 0 ] . length > 0
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
+ )
320
340
function sortPackageJson ( jsonIsh , options = { } ) {
321
341
return editStringJSON (
322
342
jsonIsh ,
323
343
onObject ( ( json ) => {
324
344
let sortOrder = options . sortOrder ? options . sortOrder : defaultSortOrder
325
345
326
346
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
+ )
328
352
const [ privateKeys , publicKeys ] = partition ( keys , isPrivateKey )
329
353
sortOrder = [
330
354
...sortOrder ,
331
355
...defaultSortOrder ,
332
356
...publicKeys . sort ( ) ,
333
357
...privateKeys . sort ( ) ,
358
+ ...trailing ,
334
359
]
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
+ }
335
369
}
336
370
337
371
return overFields ( sortObjectKeys ( json , sortOrder ) )
0 commit comments