diff --git a/index.d.ts b/index.d.ts index 1099dc21..cc837705 100644 --- a/index.d.ts +++ b/index.d.ts @@ -3,36 +3,49 @@ declare namespace sortPackageJsonExports { interface SortPackageJsonFn { /** - * Sort packageJson object. - * - * @param packageJson - A packageJson - * @param options - * @returns Sorted packageJson object - */ - >(packageJson: T, options?: Options): T, + * Sort packageJson object. + * + * @param packageJson - A packageJson + * @param options + * @returns Sorted packageJson object + */ + >(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>( + 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 diff --git a/index.js b/index.js index a361b034..c6c924c2 100755 --- a/index.js +++ b/index.js @@ -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') { @@ -332,7 +333,16 @@ 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)) }), ) } @@ -340,4 +350,5 @@ function sortPackageJson(jsonIsh, options = {}) { module.exports = sortPackageJson module.exports.sortPackageJson = sortPackageJson module.exports.sortOrder = defaultSortOrder +module.exports.sortObjectBy = sortObjectBy module.exports.default = sortPackageJson diff --git a/tests/options.js b/tests/options.js index a55c3c04..e2aeda3d 100644 --- a/tests/options.js +++ b/tests/options.js @@ -1,5 +1,6 @@ const test = require('ava') const { keysToObject, macro } = require('./_helpers') +const sortPackageJson = require('..') test('options.sortOrder', macro.sortObject, { options: { @@ -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`', +})