diff --git a/src/commands/keep-sorted.md b/src/commands/keep-sorted.md index c5c533b..69b3857 100644 --- a/src/commands/keep-sorted.md +++ b/src/commands/keep-sorted.md @@ -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' }, +} +``` diff --git a/src/commands/keep-sorted.test.ts b/src/commands/keep-sorted.test.ts index 175fc21..ba1c870 100644 --- a/src/commands/keep-sorted.test.ts +++ b/src/commands/keep-sorted.test.ts @@ -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'], + }, ) diff --git a/src/commands/keep-sorted.ts b/src/commands/keep-sorted.ts index 939e072..d792495 100644 --- a/src/commands/keep-sorted.ts +++ b/src/commands/keep-sorted.ts @@ -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 }, )