diff --git a/actions/info.action.ts b/actions/info.action.ts index 39161a7c1..22bf29bfe 100644 --- a/actions/info.action.ts +++ b/actions/info.action.ts @@ -21,7 +21,7 @@ interface PackageJsonDependencies { interface NestDependency { name: string; value: string; - fullName: string; + packageName: string; } interface NestDependencyWarnings { @@ -126,19 +126,18 @@ export class InfoAction extends AbstractAction { console.info(chalk.yellow('[Warnings]')); console.info('The following packages are not in the same minor version'); console.info('This could lead to runtime errors'); - minorVersions.forEach(version => { + minorVersions.forEach((version) => { console.info(chalk.bold(`* Under version ${version}`)); - warnings[version].forEach(({ fullName, value }) => { - console.info((`- ${fullName} ${value}`)); + warnings[version].forEach(({ packageName, value }) => { + console.info(`- ${packageName} ${value}`); }); - }) + }); } } buildNestVersionsWarningMessage( nestDependencies: NestDependency[], ): NestDependencyWarnings { - const dependenciesWhiteList = [ '@nestjs/core', '@nestjs/common', @@ -150,19 +149,25 @@ export class InfoAction extends AbstractAction { '@nestjs/websockets', ]; - const unsortedWarnings: NestDependencyWarnings = nestDependencies.reduce( - (acc, { name, fullName, value }) => { - if (!dependenciesWhiteList.includes(fullName)) { - return acc; - } + const unsortedWarnings: NestDependencyWarnings = + nestDependencies.reduce( + (acc, { name, packageName, value }) => { + if (!dependenciesWhiteList.includes(packageName)) { + return acc; + } + + const cleanedValue = value.replace(/[^\d.]/g, ''); + const [major, minor] = cleanedValue.split('.'); + const minorVersion = `${major}.${minor}`; + acc[minorVersion] = [ + ...(acc[minorVersion] || []), + { name, packageName, value }, + ]; - const [major, minor] = value.split('.').map(parseFloat); - const minorVersion = `${major}.${minor}`; - acc[minorVersion] = [...(acc[minorVersion] || []), { name, fullName, value }]; - return acc; - }, - {} - ); + return acc; + }, + {}, + ); const unsortedMinorVersions = Object.keys(unsortedWarnings); if (unsortedMinorVersions.length <= 1) { @@ -170,13 +175,27 @@ export class InfoAction extends AbstractAction { } const sortedMinorVersions = unsortedMinorVersions.sort( - (versionA, versionB) => parseFloat(versionB) - parseFloat(versionA) + (versionA, versionB) => { + const numA = parseFloat(versionA); + const numB = parseFloat(versionB); + + if (isNaN(numA) && isNaN(numB)) { + // If both are not valid numbers, maintain the current order. + return 0; + } + + // NaN is considered greater than any number, so if numA is NaN, place it later. + return isNaN(numA) ? 1 : isNaN(numB) ? -1 : numB - numA; + }, ); - return sortedMinorVersions.reduce((warnings, minorVersion) => { - warnings[minorVersion] = unsortedWarnings[minorVersion]; - return warnings; - }, {}); + return sortedMinorVersions.reduce( + (warnings, minorVersion) => { + warnings[minorVersion] = unsortedWarnings[minorVersion]; + return warnings; + }, + {}, + ); } buildNestVersionsMessage( @@ -200,7 +219,7 @@ export class InfoAction extends AbstractAction { nestDependencies.push({ name: `${key.replace(/@nestjs\//, '').replace(/@.*/, '')} version`, value: value || dependencies[key].version, - fullName: key, + packageName: key, }); } }); diff --git a/test/actions/info.action.spec.ts b/test/actions/info.action.spec.ts index 1d5a37362..259a4090f 100644 --- a/test/actions/info.action.spec.ts +++ b/test/actions/info.action.spec.ts @@ -23,63 +23,163 @@ describe('InfoAction', () => { describe('buildNestVersionsWarningMessage', () => { it('should return an empty object for one or zero minor versions', () => { const dependencies = [ - { fullName: '@nestjs/core', name: 'core', value: '1.2.3' }, - { fullName: '@nestjs/common', name: 'common', value: '1.2.4' }, + { packageName: '@nestjs/core', name: 'core', value: '1.2.3' }, + { packageName: '@nestjs/common', name: 'common', value: '1.2.4' }, ]; const result = infoAction.buildNestVersionsWarningMessage(dependencies); expect(result).toEqual({}); - }); it('should return an object only with whitelisted dependencies', () => { const dependencies = [ - { fullName: '@nestjs/core', name: 'core', value: '1.2.3' }, - { fullName: '@nestjs/common', name: 'common', value: '1.2.4' }, - { fullName: '@nestjs/schematics', name: 'schematics', value: '1.2.4' }, - { fullName: '@nestjs/platform-express', name: 'platform-express', value: '1.2.4' }, - { fullName: '@nestjs/platform-fastify', name: 'platform-fastify', value: '1.2.4' }, - { fullName: '@nestjs/platform-socket.io', name: 'platform-socket.io', value: '1.2.4' }, - { fullName: '@nestjs/platform-ws', name: 'platform-ws', value: '2.1.0' }, - { fullName: '@nestjs/websockets', name: 'websockets', value: '2.1.0' }, - { fullName: '@nestjs/test1', name: 'test1', value: '1.2.4' }, - { fullName: '@nestjs/test2', name: 'test2', value: '1.2.4' }, + { packageName: '@nestjs/core', name: 'core', value: '1.2.3' }, + { packageName: '@nestjs/common', name: 'common', value: '1.2.4' }, + { + packageName: '@nestjs/schematics', + name: 'schematics', + value: '1.2.4', + }, + { + packageName: '@nestjs/platform-express', + name: 'platform-express', + value: '1.2.4', + }, + { + packageName: '@nestjs/platform-fastify', + name: 'platform-fastify', + value: '1.2.4', + }, + { + packageName: '@nestjs/platform-socket.io', + name: 'platform-socket.io', + value: '1.2.4', + }, + { + packageName: '@nestjs/platform-ws', + name: 'platform-ws', + value: '2.1.0', + }, + { + packageName: '@nestjs/websockets', + name: 'websockets', + value: '2.1.0', + }, + { packageName: '@nestjs/test1', name: 'test1', value: '1.2.4' }, + { packageName: '@nestjs/test2', name: 'test2', value: '1.2.4' }, ]; const result = infoAction.buildNestVersionsWarningMessage(dependencies); const expected = { '1.2': [ - { fullName: '@nestjs/core', name: 'core', value: '1.2.3' }, - { fullName: '@nestjs/common', name: 'common', value: '1.2.4' }, - { fullName: '@nestjs/schematics', name: 'schematics', value: '1.2.4' }, - { fullName: '@nestjs/platform-express', name: 'platform-express', value: '1.2.4' }, - { fullName: '@nestjs/platform-fastify', name: 'platform-fastify', value: '1.2.4' }, - { fullName: '@nestjs/platform-socket.io', name: 'platform-socket.io', value: '1.2.4' }, + { packageName: '@nestjs/core', name: 'core', value: '1.2.3' }, + { packageName: '@nestjs/common', name: 'common', value: '1.2.4' }, + { + packageName: '@nestjs/schematics', + name: 'schematics', + value: '1.2.4', + }, + { + packageName: '@nestjs/platform-express', + name: 'platform-express', + value: '1.2.4', + }, + { + packageName: '@nestjs/platform-fastify', + name: 'platform-fastify', + value: '1.2.4', + }, + { + packageName: '@nestjs/platform-socket.io', + name: 'platform-socket.io', + value: '1.2.4', + }, ], - '2.1':[ - { fullName: '@nestjs/platform-ws', name: 'platform-ws', value: '2.1.0' }, - { fullName: '@nestjs/websockets', name: 'websockets', value: '2.1.0' }, + '2.1': [ + { + packageName: '@nestjs/platform-ws', + name: 'platform-ws', + value: '2.1.0', + }, + { + packageName: '@nestjs/websockets', + name: 'websockets', + value: '2.1.0', + }, ], }; expect(result).toEqual(expected); - }); it('should group dependencies by minor versions and sort them in descending order', () => { const dependencies = [ - { name: 'schematics', fullName: '@nestjs/schematics', value: '1.2.3' }, - { name: 'platform-express', fullName: '@nestjs/platform-express', value: '1.2.4' }, - { name: 'platform-fastify', fullName: '@nestjs/platform-fastify', value: '2.1.0' }, - { name: 'platform-socket.io', fullName: '@nestjs/platform-socket.io', value: '2.0.1' }, + { + name: 'schematics', + packageName: '@nestjs/schematics', + value: '1.2.3', + }, + { + name: 'platform-express', + packageName: '@nestjs/platform-express', + value: '1.2.4', + }, + { + name: 'platform-fastify', + packageName: '@nestjs/platform-fastify', + value: '2.1.0', + }, + { + packageName: '@nestjs/platform-socket.io', + name: 'platform-socket.io', + value: '1.2$$.4', + }, + { + name: 'platform-socket.io', + packageName: '@nestjs/platform-socket.io', + value: '2.0.1', + }, + { + packageName: '@nestjs/websockets', + name: 'websockets', + value: '^2.*&1.0', + }, ]; const result = infoAction.buildNestVersionsWarningMessage(dependencies); const expected = { - '2.1': [{ name: 'platform-fastify', fullName: '@nestjs/platform-fastify', value: '2.1.0' }], + '2.1': [ + { + name: 'platform-fastify', + packageName: '@nestjs/platform-fastify', + value: '2.1.0', + }, + { + packageName: '@nestjs/websockets', + name: 'websockets', + value: '^2.*&1.0', + }, + ], '2.0': [ - { name: 'platform-socket.io', fullName: '@nestjs/platform-socket.io', value: '2.0.1' }, + { + name: 'platform-socket.io', + packageName: '@nestjs/platform-socket.io', + value: '2.0.1', + }, ], '1.2': [ - { name: 'schematics', fullName: '@nestjs/schematics', value: '1.2.3' }, - { name: 'platform-express', fullName: '@nestjs/platform-express', value: '1.2.4' }, + { + name: 'schematics', + packageName: '@nestjs/schematics', + value: '1.2.3', + }, + { + name: 'platform-express', + packageName: '@nestjs/platform-express', + value: '1.2.4', + }, + { + packageName: '@nestjs/platform-socket.io', + name: 'platform-socket.io', + value: '1.2$$.4', + }, ], }; @@ -87,4 +187,3 @@ describe('InfoAction', () => { }); }); }); -