Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions src/commands/keep-sorted.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,29 @@ const arr = [
{ index: 4, name: 'foo' },
]
```

#### Sort Object of Objects

Uses optional inline JSON configuration (like [Sort Array of Objects](#sort-array-of-objects)) to define sort keys.

```js
/// keep-sorted { "keys": ["index","label"] }
const obj = {
a: { index: 3, label: 'banana' },
b: { index: 2, label: 'cherry' },
c: { index: 2, label: 'apple' },
d: { index: 1, label: 'berry' }
}
```

Will be converted to:

```js
/// keep-sorted { "keys": ["index","label"] }
const obj = {
d: { index: 1, label: 'berry' },
c: { index: 2, label: 'apple' },
b: { index: 2, label: 'cherry' },
a: { index: 3, label: 'banana' },
}
```
22 changes: 22 additions & 0 deletions src/commands/keep-sorted.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -405,4 +405,26 @@ run(
`,
errors: ['command-error'],
},
{
description: 'Sort object of objects',
code: $`
/// keep-sorted { "keys": ["index","label"] }
const obj = {
a: { index: 3, label: 'banana' },
b: { index: 2, label: 'cherry' },
c: { index: 2, label: 'apple' },
d: { index: 1, label: 'berry' }
}
`,
output: $`
/// keep-sorted { "keys": ["index","label"] }
const obj = {
d: { index: 1, label: 'berry' },
c: { index: 2, label: 'apple' },
b: { index: 2, label: 'cherry' },
a: { index: 3, label: 'banana' },
}
`,
errors: ['command-fix'],
},
)
22 changes: 18 additions & 4 deletions src/commands/keep-sorted.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,17 +72,31 @@ export const keepSorted: Command = {
...(options?.keys || []),
].filter(x => x != null) as string[]

if (objectKeys.length > 0 && node.type !== 'ArrayExpression')
return ctx.reportError(`Only arrays can be sorted by keys, but got ${node.type}`)
if (objectKeys.length > 0 && node.type !== 'ArrayExpression' && node.type !== 'ObjectExpression')
return ctx.reportError(`Only arrays and objects can be sorted by keys, but got ${node.type}`)

if (node.type === 'ObjectExpression') {
return sort(
ctx,
node,
node.properties,
node.properties.filter(Boolean) as (Tree.ObjectExpression | Tree.Property)[],
(prop) => {
if (prop.type === 'Property')
if (objectKeys.length) {
if (prop.type === 'Property' && prop.value.type === 'ObjectExpression') {
const objectProp = prop.value
return objectKeys.map((key) => {
for (const innerProp of objectProp.properties) {
if (innerProp.type === 'Property' && getString(innerProp.key) === key) {
return getString(innerProp.value)
}
}
return null
})
}
}
else if (prop.type === 'Property') {
return getString(prop.key)
}
return null
},
)
Expand Down