Skip to content

Commit

Permalink
feat: add option for custom sorting fields
Browse files Browse the repository at this point in the history
The fields option will override the values in the builtin fields array,
allowing users to signify that a given key should not be sorted, or sorted
in a particular way.
  • Loading branch information
jonathanmorley committed Nov 12, 2020
1 parent 1e28942 commit 8935395
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 30 deletions.
55 changes: 34 additions & 21 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,49 @@
declare namespace sortPackageJsonExports {
interface SortPackageJsonFn {
/**
* Sort packageJson object.
*
* @param packageJson - A packageJson
* @param options
* @returns Sorted packageJson object
*/
<T extends Record<any, any>>(packageJson: T, options?: Options): T,
* Sort packageJson object.
*
* @param packageJson - A packageJson
* @param options
* @returns Sorted packageJson object
*/
<T extends Record<any, any>>(packageJson: T, options?: Options): T

/**
* Sort packageJson string.
*
* @param packageJson - A packageJson string.
* @param options
* @returns Sorted packageJson string.
*/
(packageJson: string, options?: Options): string,
* Sort packageJson string.
*
* @param packageJson - A packageJson string.
* @param options
* @returns Sorted packageJson string.
*/
(packageJson: string, options?: Options): string
}

type ComparatorFunction = (left: string, right: string) => number;
type ComparatorFunction = (left: string, right: string) => number
function sortObjectBy<T extends Record<any, any>>(
comparator: ComparatorFunction,
deep: boolean,
): (x: T) => T

interface Field {
readonly key: string
readonly over: sortObjectBy
}

interface Options {
readonly sortOrder?: readonly string[] | ComparatorFunction;
readonly sortOrder?: readonly string[] | ComparatorFunction
readonly fields?: Field[]
}
}

interface sortPackageJsonExports extends sortPackageJsonExports.SortPackageJsonFn {
readonly default: sortPackageJsonExports.SortPackageJsonFn;
readonly sortPackageJson: sortPackageJsonExports.SortPackageJsonFn;
interface sortPackageJsonExports
extends sortPackageJsonExports.SortPackageJsonFn {
readonly default: sortPackageJsonExports.SortPackageJsonFn
readonly sortPackageJson: sortPackageJsonExports.SortPackageJsonFn
readonly sortOrder: string[]
readonly sortObjectBy: sortPackageJsonExports.sortObjectBy
}

declare const sortPackageJsonExports: sortPackageJsonExports;
declare const sortPackageJsonExports: sortPackageJsonExports

export = sortPackageJsonExports;
export = sortPackageJsonExports
29 changes: 20 additions & 9 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -280,14 +280,15 @@ const fields = [
]

const defaultSortOrder = fields.map(({ key }) => key)
const overFields = pipe(
fields.reduce((fns, { key, over }) => {
if (over) {
fns.push(overProperty(key, over))
}
return fns
}, []),
)
const overFields = (fields) =>
pipe(
fields.reduce((fns, { key, over }) => {
if (over) {
fns.push(overProperty(key, over))
}
return fns
}, []),
)

function editStringJSON(json, over) {
if (typeof json === 'string') {
Expand Down Expand Up @@ -332,12 +333,22 @@ function sortPackageJson(jsonIsh, options = {}) {
]
}

return overFields(sortObjectKeys(json, sortOrder))
if (options.fields) {
for (const field of options.fields) {
const idx = fields.findIndex((f) => f.key === field.key)

if (idx > -1) fields[idx] = field
if (idx === -1) fields.push(field)
}
}

return overFields(fields)(sortObjectKeys(json, sortOrder))
}),
)
}

module.exports = sortPackageJson
module.exports.sortPackageJson = sortPackageJson
module.exports.sortOrder = defaultSortOrder
module.exports.sortObjectBy = sortObjectBy
module.exports.default = sortPackageJson
21 changes: 21 additions & 0 deletions tests/options.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const test = require('ava')
const { keysToObject, macro } = require('./_helpers')
const sortPackageJson = require('..')

test('options.sortOrder', macro.sortObject, {
options: {
Expand Down Expand Up @@ -48,3 +49,23 @@ test('options.sortOrder with private key', macro.sortObject, {
expect: keysToObject(['_z', 'name', 'a', 'z', '_a']),
message: 'options.sortOrder should work with private keys`',
})

test('options.fields with existing key', macro.sortObject, {
options: {
fields: [{ key: 'scripts' }],
},
value: `{"scripts":{"z":"","a":""}}`,
expect: `{"scripts":{"z":"","a":""}}`,
message:
'options.fields should work with keys that are already present in the fields list`',
})

test('options.fields with new key', macro.sortObject, {
options: {
fields: [{ key: 'new-key', over: sortPackageJson.sortObjectBy() }],
},
value: `{"new-key":{"z":"","a":""}}`,
expect: `{"new-key":{"a":"","z":""}}`,
message:
'options.fields should work with keys that are not already present in the fields list`',
})

0 comments on commit 8935395

Please sign in to comment.