diff --git a/index.js b/index.js index 8c93251..60ecd43 100755 --- a/index.js +++ b/index.js @@ -55,23 +55,24 @@ const overProperty = : object const sortGitHooks = sortObjectBy(gitHooks) -const sortObjectBySemver = sortObjectBy((a, b) => { - const parseNameAndVersionRange = (specifier) => { - // Ignore anything after > & rely on fallback alphanumeric sorting for that - const [nameAndVersion] = specifier.split('>') - const atMatches = [...nameAndVersion.matchAll('@')] - if ( - !atMatches.length || - (atMatches.length === 1 && atMatches[0].index === 0) - ) { - return { name: specifier } - } - const splitIndex = atMatches.pop().index - return { - name: nameAndVersion.substring(0, splitIndex), - range: nameAndVersion.substring(splitIndex + 1), - } +const parseNameAndVersionRange = (specifier) => { + // Ignore anything after > & rely on fallback alphanumeric sorting for that + const [nameAndVersion] = specifier.split('>') + const atMatches = [...nameAndVersion.matchAll('@')] + if ( + !atMatches.length || + (atMatches.length === 1 && atMatches[0].index === 0) + ) { + return { name: specifier } } + const splitIndex = atMatches.pop().index + return { + name: nameAndVersion.substring(0, splitIndex), + range: nameAndVersion.substring(splitIndex + 1), + } +} + +const sortObjectBySemver = sortObjectBy((a, b) => { const { name: aName, range: aRange } = parseNameAndVersionRange(a) const { name: bName, range: bRange } = parseNameAndVersionRange(b) @@ -87,6 +88,27 @@ const sortObjectBySemver = sortObjectBy((a, b) => { return semver.compare(semver.minVersion(aRange), semver.minVersion(bRange)) }) +const getPackageName = (ident) => { + const parts = ident.split('@') + + if (ident.startsWith('@')) { + // Handle cases where package name starts with '@' + return parts.length > 2 ? parts.slice(0, -1).join('@') : ident + } + + // Handle cases where package name doesn't start with '@' + return parts.length > 1 ? parts.slice(0, -1).join('@') : ident +} + +const sortObjectByIdent = (a, b) => { + const PackageNameA = getPackageName(a) + const PackageNameB = getPackageName(b) + + if (PackageNameA < PackageNameB) return -1 + if (PackageNameA > PackageNameB) return 1 + return 0 +} + // https://github.com/eslint/eslint/blob/acc0e47572a9390292b4e313b4a4bf360d236358/conf/config-schema.js const eslintBaseConfigProperties = [ // `files` and `excludedFiles` are only on `overrides[]` @@ -341,7 +363,7 @@ const fields = [ { key: 'resolutions', over: sortObject }, { key: 'dependencies', over: sortObject }, { key: 'devDependencies', over: sortObject }, - { key: 'dependenciesMeta', over: sortObjectBy(undefined, true) }, + { key: 'dependenciesMeta', over: sortObjectBy(sortObjectByIdent, true) }, { key: 'peerDependencies', over: sortObject }, // TODO: only sort depth = 2 { key: 'peerDependenciesMeta', over: sortObjectBy(undefined, true) }, diff --git a/tests/_helpers.js b/tests/_helpers.js index 711e562..7f2ba70 100644 --- a/tests/_helpers.js +++ b/tests/_helpers.js @@ -59,6 +59,40 @@ function sortObjectAlphabetically(t, options = {}) { } } +function sortObjectWithRangeAlphabetically(t, options = {}) { + const { maxDepth = 1, expect } = options + + for (let depth = 1; depth < maxDepth + 1; depth++) { + sortObject(t, { + ...options, + value: keysToObject( + [ + '@z-package@1.2.3', + 'c-package@1.2.3', + 'b-package-package@1.2.3', + '@a-package@1.2.3', + 'b-package@1.2.3', + '@b-package', + ], + depth, + ), + expect: + expect || + keysToObject( + [ + '@a-package@1.2.3', + '@b-package', + '@z-package@1.2.3', + 'b-package@1.2.3', + 'b-package-package@1.2.3', + 'c-package@1.2.3', + ], + depth, + ), + }) + } +} + function sortObject( t, { @@ -211,6 +245,7 @@ export const macro = { sortObject, asItIs, sortObjectAlphabetically, + sortObjectWithRangeAlphabetically, testCLI, uniqueArray, uniqueAndSort, diff --git a/tests/deps.js b/tests/deps.js index c263554..eaca27b 100644 --- a/tests/deps.js +++ b/tests/deps.js @@ -30,10 +30,17 @@ test('peerDependenciesMeta', macro.sortObjectAlphabetically, { expect: 'snapshot', }) -// peerDependenciesMeta +// dependenciesMeta test('dependenciesMeta', macro.sortObjectAlphabetically, { path: 'dependenciesMeta', maxDepth: 2, // TODO: don't use snapshot, find a esaier way for review expect: 'snapshot', }) + +test('dependenciesMetaRange', macro.sortObjectWithRangeAlphabetically, { + path: 'dependenciesMeta', + maxDepth: 2, + // TODO: don't use snapshot, find a esaier way for review + expect: 'snapshot', +}) diff --git a/tests/snapshots/deps.js.md b/tests/snapshots/deps.js.md index 4dc7c8b..ce3b680 100644 --- a/tests/snapshots/deps.js.md +++ b/tests/snapshots/deps.js.md @@ -107,3 +107,143 @@ Generated by [AVA](https://avajs.dev). }`, pretty: true, } + +## dependenciesMetaRange + +> Should sort `dependenciesMeta` as object. + + { + input: `{␊ + "dependenciesMeta": {␊ + "@z-package@1.2.3": "@z-package@1.2.3",␊ + "c-package@1.2.3": "c-package@1.2.3",␊ + "b-package-package@1.2.3": "b-package-package@1.2.3",␊ + "@a-package@1.2.3": "@a-package@1.2.3",␊ + "b-package@1.2.3": "b-package@1.2.3",␊ + "@b-package": "@b-package"␊ + }␊ + }`, + options: undefined, + output: `{␊ + "dependenciesMeta": {␊ + "@a-package@1.2.3": "@a-package@1.2.3",␊ + "@b-package": "@b-package",␊ + "@z-package@1.2.3": "@z-package@1.2.3",␊ + "b-package@1.2.3": "b-package@1.2.3",␊ + "b-package-package@1.2.3": "b-package-package@1.2.3",␊ + "c-package@1.2.3": "c-package@1.2.3"␊ + }␊ + }`, + pretty: true, + } + +> Should sort `dependenciesMeta` as object. + + { + input: `{␊ + "dependenciesMeta": {␊ + "@z-package@1.2.3": {␊ + "@z-package@1.2.3": "@z-package@1.2.3",␊ + "c-package@1.2.3": "c-package@1.2.3",␊ + "b-package-package@1.2.3": "b-package-package@1.2.3",␊ + "@a-package@1.2.3": "@a-package@1.2.3",␊ + "b-package@1.2.3": "b-package@1.2.3",␊ + "@b-package": "@b-package"␊ + },␊ + "c-package@1.2.3": {␊ + "@z-package@1.2.3": "@z-package@1.2.3",␊ + "c-package@1.2.3": "c-package@1.2.3",␊ + "b-package-package@1.2.3": "b-package-package@1.2.3",␊ + "@a-package@1.2.3": "@a-package@1.2.3",␊ + "b-package@1.2.3": "b-package@1.2.3",␊ + "@b-package": "@b-package"␊ + },␊ + "b-package-package@1.2.3": {␊ + "@z-package@1.2.3": "@z-package@1.2.3",␊ + "c-package@1.2.3": "c-package@1.2.3",␊ + "b-package-package@1.2.3": "b-package-package@1.2.3",␊ + "@a-package@1.2.3": "@a-package@1.2.3",␊ + "b-package@1.2.3": "b-package@1.2.3",␊ + "@b-package": "@b-package"␊ + },␊ + "@a-package@1.2.3": {␊ + "@z-package@1.2.3": "@z-package@1.2.3",␊ + "c-package@1.2.3": "c-package@1.2.3",␊ + "b-package-package@1.2.3": "b-package-package@1.2.3",␊ + "@a-package@1.2.3": "@a-package@1.2.3",␊ + "b-package@1.2.3": "b-package@1.2.3",␊ + "@b-package": "@b-package"␊ + },␊ + "b-package@1.2.3": {␊ + "@z-package@1.2.3": "@z-package@1.2.3",␊ + "c-package@1.2.3": "c-package@1.2.3",␊ + "b-package-package@1.2.3": "b-package-package@1.2.3",␊ + "@a-package@1.2.3": "@a-package@1.2.3",␊ + "b-package@1.2.3": "b-package@1.2.3",␊ + "@b-package": "@b-package"␊ + },␊ + "@b-package": {␊ + "@z-package@1.2.3": "@z-package@1.2.3",␊ + "c-package@1.2.3": "c-package@1.2.3",␊ + "b-package-package@1.2.3": "b-package-package@1.2.3",␊ + "@a-package@1.2.3": "@a-package@1.2.3",␊ + "b-package@1.2.3": "b-package@1.2.3",␊ + "@b-package": "@b-package"␊ + }␊ + }␊ + }`, + options: undefined, + output: `{␊ + "dependenciesMeta": {␊ + "@a-package@1.2.3": {␊ + "@a-package@1.2.3": "@a-package@1.2.3",␊ + "@b-package": "@b-package",␊ + "@z-package@1.2.3": "@z-package@1.2.3",␊ + "b-package@1.2.3": "b-package@1.2.3",␊ + "b-package-package@1.2.3": "b-package-package@1.2.3",␊ + "c-package@1.2.3": "c-package@1.2.3"␊ + },␊ + "@b-package": {␊ + "@a-package@1.2.3": "@a-package@1.2.3",␊ + "@b-package": "@b-package",␊ + "@z-package@1.2.3": "@z-package@1.2.3",␊ + "b-package@1.2.3": "b-package@1.2.3",␊ + "b-package-package@1.2.3": "b-package-package@1.2.3",␊ + "c-package@1.2.3": "c-package@1.2.3"␊ + },␊ + "@z-package@1.2.3": {␊ + "@a-package@1.2.3": "@a-package@1.2.3",␊ + "@b-package": "@b-package",␊ + "@z-package@1.2.3": "@z-package@1.2.3",␊ + "b-package@1.2.3": "b-package@1.2.3",␊ + "b-package-package@1.2.3": "b-package-package@1.2.3",␊ + "c-package@1.2.3": "c-package@1.2.3"␊ + },␊ + "b-package@1.2.3": {␊ + "@a-package@1.2.3": "@a-package@1.2.3",␊ + "@b-package": "@b-package",␊ + "@z-package@1.2.3": "@z-package@1.2.3",␊ + "b-package@1.2.3": "b-package@1.2.3",␊ + "b-package-package@1.2.3": "b-package-package@1.2.3",␊ + "c-package@1.2.3": "c-package@1.2.3"␊ + },␊ + "b-package-package@1.2.3": {␊ + "@a-package@1.2.3": "@a-package@1.2.3",␊ + "@b-package": "@b-package",␊ + "@z-package@1.2.3": "@z-package@1.2.3",␊ + "b-package@1.2.3": "b-package@1.2.3",␊ + "b-package-package@1.2.3": "b-package-package@1.2.3",␊ + "c-package@1.2.3": "c-package@1.2.3"␊ + },␊ + "c-package@1.2.3": {␊ + "@a-package@1.2.3": "@a-package@1.2.3",␊ + "@b-package": "@b-package",␊ + "@z-package@1.2.3": "@z-package@1.2.3",␊ + "b-package@1.2.3": "b-package@1.2.3",␊ + "b-package-package@1.2.3": "b-package-package@1.2.3",␊ + "c-package@1.2.3": "c-package@1.2.3"␊ + }␊ + }␊ + }`, + pretty: true, + } diff --git a/tests/snapshots/deps.js.snap b/tests/snapshots/deps.js.snap index 4d621cf..26fa3e1 100644 Binary files a/tests/snapshots/deps.js.snap and b/tests/snapshots/deps.js.snap differ