From 1408fac7a8daaf4f9ef3dff4bdc2940fd156c402 Mon Sep 17 00:00:00 2001 From: SukkaW Date: Tue, 9 Apr 2024 13:37:27 +0800 Subject: [PATCH 01/11] Remove `lodash/omit` --- src/lib/getNcuRc.ts | 10 ++++++++-- src/package-managers/npm.ts | 40 +++++++++++++++++++++++-------------- 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/src/lib/getNcuRc.ts b/src/lib/getNcuRc.ts index 205be93b..31597d0b 100644 --- a/src/lib/getNcuRc.ts +++ b/src/lib/getNcuRc.ts @@ -1,6 +1,5 @@ import flatten from 'lodash/flatten' import map from 'lodash/map' -import omit from 'lodash/omit' import os from 'os' import path from 'path' import { rcFile } from 'rc-config-loader' @@ -36,10 +35,17 @@ async function getNcuRc({ programError(options, `Config file ${configFileName} not found in ${configFilePath || process.cwd()}`) } + let rawConfigWithoutSchema = {}; + if (rawResult?.config) { + // @ts-expect-error -- rawResult.config is not typed thus TypeScript does not know that it has a $schema property + const { $schema, ...rest } = rawResult.config + rawConfigWithoutSchema = rest + } + const result = { filePath: rawResult?.filePath, // Prevent the cli tool from choking because of an unknown option "$schema" - config: omit(rawResult?.config, '$schema'), + config: rawConfigWithoutSchema, } // validate arguments here to provide a better error message diff --git a/src/package-managers/npm.ts b/src/package-managers/npm.ts index e420364a..e3499347 100644 --- a/src/package-managers/npm.ts +++ b/src/package-managers/npm.ts @@ -1,12 +1,11 @@ import memoize from 'fast-memoize' import fs from 'fs' import ini from 'ini' -import { uniq } from 'lodash' +import uniq from 'lodash/uniq' import camelCase from 'lodash/camelCase' import filter from 'lodash/filter' import isEqual from 'lodash/isEqual' import last from 'lodash/last' -import omit from 'lodash/omit' import sortBy from 'lodash/sortBy' import npmRegistryFetch from 'npm-registry-fetch' import path from 'path' @@ -371,11 +370,13 @@ export const mockFetchUpgradedPackument = ...(isPackument(partialPackument) ? partialPackument : null), } + const { versions, ...packumentWithoutVersions } = packument + return Promise.resolve({ ...packument, versions: { ...((isPackument(partialPackument) && partialPackument.versions) || { - [version]: omit(packument, 'versions'), + [version]: packumentWithoutVersions, }), }, }) @@ -404,28 +405,33 @@ const mergeNpmConfigs = memoize( if (npmConfigWorkspaceProject && Object.keys(npmConfigWorkspaceProject).length > 0) { print(options, `\nnpm config (workspace project):`, 'verbose') - printSorted(options, omit(npmConfigWorkspaceProject, 'cache'), 'verbose') + const { cache, ...npmConfigWorkspaceProjectWithoutCache } = npmConfigWorkspaceProject + printSorted(options, npmConfigWorkspaceProjectWithoutCache, 'verbose') } if (npmConfigUser && Object.keys(npmConfigUser).length > 0) { print(options, `\nnpm config (user):`, 'verbose') - printSorted(options, omit(npmConfigUser, 'cache'), 'verbose') + const { cache, ...npmConfigUserWithoutCache } = npmConfigUser + printSorted(options, npmConfigUserWithoutCache, 'verbose') } if (npmConfigLocal && Object.keys(npmConfigLocal).length > 0) { print(options, `\nnpm config (local override):`, 'verbose') - printSorted(options, omit(npmConfigLocal, 'cache'), 'verbose') + const { cache, ...npmConfigLocalWithoutCache } = npmConfigLocal + printSorted(options, npmConfigLocalWithoutCache, 'verbose') } if (npmConfigProject && Object.keys(npmConfigProject).length > 0) { print(options, `\nnpm config (project: ${npmConfigProjectPath}):`, 'verbose') - printSorted(options, omit(npmConfigProject, 'cache'), 'verbose') + const { cache, ...npmConfigProjectWithoutCache } = npmConfigProject + printSorted(options, npmConfigProjectWithoutCache, 'verbose') } if (npmConfigCWD && Object.keys(npmConfigCWD).length > 0) { print(options, `\nnpm config (cwd: ${npmConfigCWDPath}):`, 'verbose') // omit cache since it is added to every config - printSorted(options, omit(npmConfigCWD, 'cache'), 'verbose') + const { cache, ...npmConfigCWDWithoutCache } = npmConfigCWD + printSorted(options, npmConfigCWDWithoutCache, 'verbose') } const npmConfigMerged = { @@ -442,7 +448,9 @@ const mergeNpmConfigs = memoize( if (isMerged) { print(options, `\nmerged npm config:`, 'verbose') // omit cache since it is added to every config - printSorted(options, omit(npmConfigMerged, 'cache'), 'verbose') + // @ts-expect-error -- though not typed, but the "cache" property does exist on the object and needs to be omitted + const { cache, ...npmConfigMergedWithoutCache } = npmConfigMerged + printSorted(options, npmConfigMergedWithoutCache, 'verbose') } return npmConfigMerged @@ -527,20 +535,22 @@ export const fetchUpgradedPackumentMemo = memoize(fetchUpgradedPackument, { retried, npmConfigLocal, npmConfigWorkspaceProject, - ]: Parameters) => - JSON.stringify([ + ]: Parameters) => { + // packageFile varies by cwd in workspaces/deep mode, so we do not want to memoize on that + const { packageFile, ...optionsWithoutPackageFile } = options + return JSON.stringify([ packageName, fields, // currentVersion does not change the behavior of fetchUpgradedPackument unless it is an invalid/inexact version which causes it to short circuit isExactVersion(currentVersion), - // packageFile varies by cwd in workspaces/deep mode, so we do not want to memoize on that - omit(options, 'packageFile'), + optionsWithoutPackageFile, // make sure retries do not get memoized retried, npmConfigLocal, npmConfigWorkspaceProject, - ])) as (args: any[]) => string, -}) + ]); + }) as (args: any[]) => string +}); /** * Spawns npm with --json. Handles different commands for Window and Linux/OSX. From eb431f020375b3e0531778aa51757ef8381d66cc Mon Sep 17 00:00:00 2001 From: SukkaW Date: Tue, 9 Apr 2024 13:44:59 +0800 Subject: [PATCH 02/11] Remove `lodash/map` --- src/lib/getNcuRc.ts | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/src/lib/getNcuRc.ts b/src/lib/getNcuRc.ts index 31597d0b..5a98e04a 100644 --- a/src/lib/getNcuRc.ts +++ b/src/lib/getNcuRc.ts @@ -1,5 +1,3 @@ -import flatten from 'lodash/flatten' -import map from 'lodash/map' import os from 'os' import path from 'path' import { rcFile } from 'rc-config-loader' @@ -61,19 +59,17 @@ async function getNcuRc({ // flatten config object into command line arguments to be read by commander const args = result - ? flatten( - map(result.config, (value, name) => - // if a boolean option is true, include only the nullary option --${name} - // an option is considered boolean if its type is explicitly set to boolean, or if it is has a proper Javascript boolean value - value === true || (cliOptionsMap[name]?.type === 'boolean' && value) - ? [`--${name}`] - : // if a boolean option is false, exclude it - value === false || (cliOptionsMap[name]?.type === 'boolean' && !value) - ? [] - : // otherwise render as a 2-tuple - [`--${name}`, value], - ), - ) + ? Object.entries(result.config).flatMap(([name, value]): string[] => + // if a boolean option is true, include only the nullary option --${name} + // an option is considered boolean if its type is explicitly set to boolean, or if it is has a proper Javascript boolean value + value === true || (cliOptionsMap[name]?.type === 'boolean' && value) + ? [`--${name}`] + : // if a boolean option is false, exclude it + value === false || (cliOptionsMap[name]?.type === 'boolean' && !value) + ? [] + : // otherwise render as a 2-tuple + [`--${name}`, String(value)], + ) : [] return result ? { ...result, args } : null From d7f503bbfef935b1baa679d34418dd1f3b97e5f0 Mon Sep 17 00:00:00 2001 From: SukkaW Date: Tue, 9 Apr 2024 14:02:38 +0800 Subject: [PATCH 03/11] Make ESLint Happy --- .eslintrc.js | 10 +++++++++- src/lib/getNcuRc.ts | 24 ++++++++++++------------ src/package-managers/gitTags.ts | 1 - src/package-managers/npm.ts | 24 ++++++++++++------------ 4 files changed, 33 insertions(+), 26 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index df0ce73d..128b0fc8 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -24,7 +24,15 @@ module.exports = { '@typescript-eslint/no-explicit-any': 'off', '@typescript-eslint/no-non-null-assertion': 'off', '@typescript-eslint/no-use-before-define': 'error', - '@typescript-eslint/no-unused-vars': 'error', + '@typescript-eslint/no-unused-vars': [ + 'error', + { + // using destructuring to omit properties from objects + destructuredArrayIgnorePattern: '^_', + argsIgnorePattern: '^_', + varsIgnorePattern: '^_', + }, + ], '@typescript-eslint/array-type': [ 'error', { diff --git a/src/lib/getNcuRc.ts b/src/lib/getNcuRc.ts index 5a98e04a..dc62514e 100644 --- a/src/lib/getNcuRc.ts +++ b/src/lib/getNcuRc.ts @@ -33,10 +33,10 @@ async function getNcuRc({ programError(options, `Config file ${configFileName} not found in ${configFilePath || process.cwd()}`) } - let rawConfigWithoutSchema = {}; + let rawConfigWithoutSchema = {} if (rawResult?.config) { // @ts-expect-error -- rawResult.config is not typed thus TypeScript does not know that it has a $schema property - const { $schema, ...rest } = rawResult.config + const { $schema: _, ...rest } = rawResult.config rawConfigWithoutSchema = rest } @@ -60,16 +60,16 @@ async function getNcuRc({ // flatten config object into command line arguments to be read by commander const args = result ? Object.entries(result.config).flatMap(([name, value]): string[] => - // if a boolean option is true, include only the nullary option --${name} - // an option is considered boolean if its type is explicitly set to boolean, or if it is has a proper Javascript boolean value - value === true || (cliOptionsMap[name]?.type === 'boolean' && value) - ? [`--${name}`] - : // if a boolean option is false, exclude it - value === false || (cliOptionsMap[name]?.type === 'boolean' && !value) - ? [] - : // otherwise render as a 2-tuple - [`--${name}`, String(value)], - ) + // if a boolean option is true, include only the nullary option --${name} + // an option is considered boolean if its type is explicitly set to boolean, or if it is has a proper Javascript boolean value + value === true || (cliOptionsMap[name]?.type === 'boolean' && value) + ? [`--${name}`] + : // if a boolean option is false, exclude it + value === false || (cliOptionsMap[name]?.type === 'boolean' && !value) + ? [] + : // otherwise render as a 2-tuple + [`--${name}`, String(value)], + ) : [] return result ? { ...result, args } : null diff --git a/src/package-managers/gitTags.ts b/src/package-managers/gitTags.ts index 4cf8e98f..2af8e5a4 100644 --- a/src/package-managers/gitTags.ts +++ b/src/package-managers/gitTags.ts @@ -87,7 +87,6 @@ export const patch = greatestLevel('patch') /** All git tags are exact versions, so --target semver should never upgrade git tags. */ // https://github.com/raineorshine/npm-check-updates/pull/1368 -// eslint-disable-next-line @typescript-eslint/no-unused-vars export const semver: GetVersion = async (_name: string, _declaration: VersionSpec, _options?: Options) => { return { version: null } } diff --git a/src/package-managers/npm.ts b/src/package-managers/npm.ts index e3499347..9be64d82 100644 --- a/src/package-managers/npm.ts +++ b/src/package-managers/npm.ts @@ -1,12 +1,12 @@ import memoize from 'fast-memoize' import fs from 'fs' import ini from 'ini' -import uniq from 'lodash/uniq' import camelCase from 'lodash/camelCase' import filter from 'lodash/filter' import isEqual from 'lodash/isEqual' import last from 'lodash/last' import sortBy from 'lodash/sortBy' +import uniq from 'lodash/uniq' import npmRegistryFetch from 'npm-registry-fetch' import path from 'path' import nodeSemver from 'semver' @@ -370,7 +370,7 @@ export const mockFetchUpgradedPackument = ...(isPackument(partialPackument) ? partialPackument : null), } - const { versions, ...packumentWithoutVersions } = packument + const { versions: _, ...packumentWithoutVersions } = packument return Promise.resolve({ ...packument, @@ -405,32 +405,32 @@ const mergeNpmConfigs = memoize( if (npmConfigWorkspaceProject && Object.keys(npmConfigWorkspaceProject).length > 0) { print(options, `\nnpm config (workspace project):`, 'verbose') - const { cache, ...npmConfigWorkspaceProjectWithoutCache } = npmConfigWorkspaceProject + const { cache: _, ...npmConfigWorkspaceProjectWithoutCache } = npmConfigWorkspaceProject printSorted(options, npmConfigWorkspaceProjectWithoutCache, 'verbose') } if (npmConfigUser && Object.keys(npmConfigUser).length > 0) { print(options, `\nnpm config (user):`, 'verbose') - const { cache, ...npmConfigUserWithoutCache } = npmConfigUser + const { cache: _, ...npmConfigUserWithoutCache } = npmConfigUser printSorted(options, npmConfigUserWithoutCache, 'verbose') } if (npmConfigLocal && Object.keys(npmConfigLocal).length > 0) { print(options, `\nnpm config (local override):`, 'verbose') - const { cache, ...npmConfigLocalWithoutCache } = npmConfigLocal + const { cache: _, ...npmConfigLocalWithoutCache } = npmConfigLocal printSorted(options, npmConfigLocalWithoutCache, 'verbose') } if (npmConfigProject && Object.keys(npmConfigProject).length > 0) { print(options, `\nnpm config (project: ${npmConfigProjectPath}):`, 'verbose') - const { cache, ...npmConfigProjectWithoutCache } = npmConfigProject + const { cache: _, ...npmConfigProjectWithoutCache } = npmConfigProject printSorted(options, npmConfigProjectWithoutCache, 'verbose') } if (npmConfigCWD && Object.keys(npmConfigCWD).length > 0) { print(options, `\nnpm config (cwd: ${npmConfigCWDPath}):`, 'verbose') // omit cache since it is added to every config - const { cache, ...npmConfigCWDWithoutCache } = npmConfigCWD + const { cache: _, ...npmConfigCWDWithoutCache } = npmConfigCWD printSorted(options, npmConfigCWDWithoutCache, 'verbose') } @@ -449,7 +449,7 @@ const mergeNpmConfigs = memoize( print(options, `\nmerged npm config:`, 'verbose') // omit cache since it is added to every config // @ts-expect-error -- though not typed, but the "cache" property does exist on the object and needs to be omitted - const { cache, ...npmConfigMergedWithoutCache } = npmConfigMerged + const { cache: _, ...npmConfigMergedWithoutCache } = npmConfigMerged printSorted(options, npmConfigMergedWithoutCache, 'verbose') } @@ -537,7 +537,7 @@ export const fetchUpgradedPackumentMemo = memoize(fetchUpgradedPackument, { npmConfigWorkspaceProject, ]: Parameters) => { // packageFile varies by cwd in workspaces/deep mode, so we do not want to memoize on that - const { packageFile, ...optionsWithoutPackageFile } = options + const { packageFile: _, ...optionsWithoutPackageFile } = options return JSON.stringify([ packageName, fields, @@ -548,9 +548,9 @@ export const fetchUpgradedPackumentMemo = memoize(fetchUpgradedPackument, { retried, npmConfigLocal, npmConfigWorkspaceProject, - ]); - }) as (args: any[]) => string -}); + ]) + }) as (args: any[]) => string, +}) /** * Spawns npm with --json. Handles different commands for Window and Linux/OSX. From f4ccab6c94696e8f4b953efeeb71340a6095d553 Mon Sep 17 00:00:00 2001 From: SukkaW Date: Tue, 9 Apr 2024 14:08:32 +0800 Subject: [PATCH 04/11] Remove `lodash/isEmpty` --- src/lib/runLocal.ts | 3 +-- src/lib/upgradePackageDefinitions.ts | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/lib/runLocal.ts b/src/lib/runLocal.ts index d1ea876f..c1f22d42 100644 --- a/src/lib/runLocal.ts +++ b/src/lib/runLocal.ts @@ -1,7 +1,6 @@ import fs from 'fs/promises' import jph from 'json-parse-helpfulerror' import get from 'lodash/get' -import isEmpty from 'lodash/isEmpty' import pick from 'lodash/pick' import prompts from 'prompts-ncu' import nodeSemver from 'semver' @@ -249,7 +248,7 @@ async function runLocal( ) if (options.peer) { const ignoredUpdates = await getIgnoredUpgrades(current, upgraded, upgradedPeerDependencies!, options) - if (!isEmpty(ignoredUpdates)) { + if (Object.keys(ignoredUpdates).length > 0) { printIgnoredUpdates(options, ignoredUpdates) } } diff --git a/src/lib/upgradePackageDefinitions.ts b/src/lib/upgradePackageDefinitions.ts index 4a78583f..822c7965 100644 --- a/src/lib/upgradePackageDefinitions.ts +++ b/src/lib/upgradePackageDefinitions.ts @@ -1,4 +1,3 @@ -import isEmpty from 'lodash/isEmpty' import isEqual from 'lodash/isEqual' import pickBy from 'lodash/pickBy' import { satisfies } from 'semver' @@ -48,7 +47,7 @@ export async function upgradePackageDefinitions( const filteredLatestDependencies = pickBy(latestVersions, (spec, dep) => filteredUpgradedDependencies[dep]) - if (options.peer && !isEmpty(filteredUpgradedDependencies)) { + if (options.peer && Object.keys(filteredLatestDependencies).length > 0) { const upgradedPeerDependencies = await getPeerDependenciesFromRegistry(filteredLatestDependencies, options) const peerDependencies = { ...options.peerDependencies, ...upgradedPeerDependencies } if (!isEqual(options.peerDependencies, peerDependencies)) { From 9038fb05825e4bdbb2740c9c8300a44dbe3ec934 Mon Sep 17 00:00:00 2001 From: SukkaW Date: Tue, 9 Apr 2024 14:45:00 +0800 Subject: [PATCH 05/11] Remove `lodash/last` --- src/lib/version-util.ts | 3 +-- src/package-managers/npm.ts | 12 +++++------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/lib/version-util.ts b/src/lib/version-util.ts index 1a87a599..b120148c 100755 --- a/src/lib/version-util.ts +++ b/src/lib/version-util.ts @@ -2,7 +2,6 @@ import ary from 'lodash/ary' import curry from 'lodash/curry' import flow from 'lodash/flow' import intersection from 'lodash/intersection' -import last from 'lodash/last' import propertyOf from 'lodash/propertyOf' import reject from 'lodash/reject' import sortBy from 'lodash/sortBy' @@ -333,7 +332,7 @@ export function findGreatestByLevel(versions: string[], current: string, level: ) }) - return last(versionsSorted) || null + return versionsSorted.at(-1) || null } /** diff --git a/src/package-managers/npm.ts b/src/package-managers/npm.ts index 9be64d82..6f681ca5 100644 --- a/src/package-managers/npm.ts +++ b/src/package-managers/npm.ts @@ -4,7 +4,6 @@ import ini from 'ini' import camelCase from 'lodash/camelCase' import filter from 'lodash/filter' import isEqual from 'lodash/isEqual' -import last from 'lodash/last' import sortBy from 'lodash/sortBy' import uniq from 'lodash/uniq' import npmRegistryFetch from 'npm-registry-fetch' @@ -646,11 +645,10 @@ export const greatest: GetVersion = async ( return { version: - last( - filter(versions, filterPredicate(options)) - .map(o => o.version) - .sort(versionUtil.compareVersions), - ) || null, + filter(versions, filterPredicate(options)) + .map(o => o.version) + .sort(versionUtil.compareVersions) + .at(-1) || null, } } @@ -816,7 +814,7 @@ export const newest: GetVersion = async ( // sort by timestamp (entry[1]) and map versions const versionsSortedByTime = sortBy(Object.entries(timesSatisfyingNodeEngine), 1).map(([version]) => version) - return { version: last(versionsSortedByTime) } + return { version: versionsSortedByTime.at(-1) } } /** From 091d64884b65e7a881a96d0d8ed752f23e63603d Mon Sep 17 00:00:00 2001 From: SukkaW Date: Tue, 9 Apr 2024 14:54:36 +0800 Subject: [PATCH 06/11] Remove `lodash/transform` --- src/lib/logging.ts | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/lib/logging.ts b/src/lib/logging.ts index 61fdd88d..1eec5301 100755 --- a/src/lib/logging.ts +++ b/src/lib/logging.ts @@ -2,7 +2,6 @@ * Loggin functions. */ import Table from 'cli-table3' -import transform from 'lodash/transform' import { IgnoredUpgrade } from '../types/IgnoredUpgrade' import { Index } from '../types/IndexType' import { Options } from '../types/Options' @@ -87,13 +86,10 @@ export function printSimpleJoinedString(object: any, join: string) { /** Prints an object sorted by key. */ export function printSorted(options: Options, obj: T, loglevel: LogLevel) { const sortedKeys = Object.keys(obj).sort() as (keyof T)[] - const objSorted = transform( - sortedKeys, - (accum, key) => { - accum[key] = obj[key] - }, - {} as T, - ) + const objSorted = sortedKeys.reduce((accum, key) => { + accum[key] = obj[key] + return accum + }, {} as T) print(options, objSorted, loglevel) } From b57f433c4794c4e3fd1c5cd79b56db5558797f81 Mon Sep 17 00:00:00 2001 From: SukkaW Date: Tue, 9 Apr 2024 15:44:47 +0800 Subject: [PATCH 07/11] Remove `lodash/filter` --- src/package-managers/npm.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/package-managers/npm.ts b/src/package-managers/npm.ts index 6f681ca5..0f59fa1c 100644 --- a/src/package-managers/npm.ts +++ b/src/package-managers/npm.ts @@ -643,9 +643,14 @@ export const greatest: GetVersion = async ( await fetchUpgradedPackumentMemo(packageName, ['versions'], currentVersion, options, 0, npmConfig, npmConfigProject) )?.versions + if (!versions) { + return { version: null } + } + return { version: - filter(versions, filterPredicate(options)) + Object.values(versions) + .filter(filterPredicate(options)) .map(o => o.version) .sort(versionUtil.compareVersions) .at(-1) || null, From aaa7f42f935be1f52097bda604ba57924280ba1e Mon Sep 17 00:00:00 2001 From: SukkaW Date: Tue, 9 Apr 2024 16:17:43 +0800 Subject: [PATCH 08/11] Fix tests --- src/lib/getNcuRc.ts | 12 ++++-------- src/package-managers/npm.ts | 6 +----- 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/src/lib/getNcuRc.ts b/src/lib/getNcuRc.ts index dc62514e..ac096dd1 100644 --- a/src/lib/getNcuRc.ts +++ b/src/lib/getNcuRc.ts @@ -33,12 +33,8 @@ async function getNcuRc({ programError(options, `Config file ${configFileName} not found in ${configFilePath || process.cwd()}`) } - let rawConfigWithoutSchema = {} - if (rawResult?.config) { - // @ts-expect-error -- rawResult.config is not typed thus TypeScript does not know that it has a $schema property - const { $schema: _, ...rest } = rawResult.config - rawConfigWithoutSchema = rest - } + // @ts-expect-error -- rawResult.config is not typed thus TypeScript does not know that it has a $schema property + const { $schema: _, ...rawConfigWithoutSchema } = rawResult?.config || {} const result = { filePath: rawResult?.filePath, @@ -59,7 +55,7 @@ async function getNcuRc({ // flatten config object into command line arguments to be read by commander const args = result - ? Object.entries(result.config).flatMap(([name, value]): string[] => + ? Object.entries(result.config).flatMap(([name, value]): any[] => // if a boolean option is true, include only the nullary option --${name} // an option is considered boolean if its type is explicitly set to boolean, or if it is has a proper Javascript boolean value value === true || (cliOptionsMap[name]?.type === 'boolean' && value) @@ -68,7 +64,7 @@ async function getNcuRc({ value === false || (cliOptionsMap[name]?.type === 'boolean' && !value) ? [] : // otherwise render as a 2-tuple - [`--${name}`, String(value)], + [`--${name}`, value], ) : [] diff --git a/src/package-managers/npm.ts b/src/package-managers/npm.ts index 0f59fa1c..79862185 100644 --- a/src/package-managers/npm.ts +++ b/src/package-managers/npm.ts @@ -643,13 +643,9 @@ export const greatest: GetVersion = async ( await fetchUpgradedPackumentMemo(packageName, ['versions'], currentVersion, options, 0, npmConfig, npmConfigProject) )?.versions - if (!versions) { - return { version: null } - } - return { version: - Object.values(versions) + Object.values(versions || {}) .filter(filterPredicate(options)) .map(o => o.version) .sort(versionUtil.compareVersions) From e4736bb38108cebfcc30d2c4c236e45be7c52e03 Mon Sep 17 00:00:00 2001 From: SukkaW Date: Tue, 9 Apr 2024 16:19:21 +0800 Subject: [PATCH 09/11] Remove `lodash/isString` --- src/index.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/index.ts b/src/index.ts index 71ce47bd..b83eb2ac 100755 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,3 @@ -import isString from 'lodash/isString' import path from 'path' import prompts from 'prompts-ncu' import spawn from 'spawn-please' @@ -296,7 +295,7 @@ export async function run( let timeout: NodeJS.Timeout | undefined let timeoutPromise: Promise = new Promise(() => null) if (options.timeout) { - const timeoutMs = isString(options.timeout) ? Number.parseInt(options.timeout, 10) : options.timeout + const timeoutMs = typeof options.timeout === 'string' ? Number.parseInt(options.timeout, 10) : options.timeout timeoutPromise = new Promise((resolve, reject) => { timeout = setTimeout(() => { // must catch the error and reject explicitly since we are in a setTimeout From b57bec4b8fc7574d2866c0d623f1daf44c6d2971 Mon Sep 17 00:00:00 2001 From: SukkaW Date: Tue, 9 Apr 2024 16:22:15 +0800 Subject: [PATCH 10/11] Remove `lodash/get` --- src/lib/runLocal.ts | 3 +-- src/package-managers/filters.ts | 5 ++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/lib/runLocal.ts b/src/lib/runLocal.ts index c1f22d42..858c14da 100644 --- a/src/lib/runLocal.ts +++ b/src/lib/runLocal.ts @@ -1,6 +1,5 @@ import fs from 'fs/promises' import jph from 'json-parse-helpfulerror' -import get from 'lodash/get' import pick from 'lodash/pick' import prompts from 'prompts-ncu' import nodeSemver from 'semver' @@ -178,7 +177,7 @@ async function runLocal( print(options, current, 'verbose') if (options.enginesNode) { - options.nodeEngineVersion = get(pkg, 'engines.node') + options.nodeEngineVersion = pkg?.engines?.node } if (options.peer) { diff --git a/src/package-managers/filters.ts b/src/package-managers/filters.ts index 1bb19f90..887f0a2d 100644 --- a/src/package-managers/filters.ts +++ b/src/package-managers/filters.ts @@ -1,4 +1,3 @@ -import get from 'lodash/get' import overEvery from 'lodash/overEvery' import semver from 'semver' import * as versionUtil from '../lib/version-util' @@ -36,9 +35,9 @@ export function allowPreOrIsNotPre(versionResult: Partial, options: O */ export function satisfiesNodeEngine(versionResult: Partial, nodeEngineVersion: Maybe): boolean { if (!nodeEngineVersion) return true - const minVersion = get(semver.minVersion(nodeEngineVersion), 'version') + const minVersion = semver.minVersion(nodeEngineVersion)?.version if (!minVersion) return true - const versionNodeEngine: string | undefined = get(versionResult, 'engines.node') + const versionNodeEngine: string | undefined = versionResult?.engines?.node return !versionNodeEngine || semver.satisfies(minVersion, versionNodeEngine) } From 6a07c3925619bdc30fdf6b3b845cec310b07e408 Mon Sep 17 00:00:00 2001 From: SukkaW Date: Tue, 9 Apr 2024 16:24:18 +0800 Subject: [PATCH 11/11] Remove `lodash/filter` --- src/package-managers/npm.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/package-managers/npm.ts b/src/package-managers/npm.ts index 79862185..550a3960 100644 --- a/src/package-managers/npm.ts +++ b/src/package-managers/npm.ts @@ -2,7 +2,6 @@ import memoize from 'fast-memoize' import fs from 'fs' import ini from 'ini' import camelCase from 'lodash/camelCase' -import filter from 'lodash/filter' import isEqual from 'lodash/isEqual' import sortBy from 'lodash/sortBy' import uniq from 'lodash/uniq' @@ -837,7 +836,9 @@ export const minor: GetVersion = async ( await fetchUpgradedPackumentMemo(packageName, ['versions'], currentVersion, options, 0, npmConfig, npmConfigProject) )?.versions as Index const version = versionUtil.findGreatestByLevel( - filter(versions, filterPredicate(options)).map(o => o.version), + Object.values(versions || {}) + .filter(filterPredicate(options)) + .map(o => o.version), currentVersion, 'minor', ) @@ -863,7 +864,9 @@ export const patch: GetVersion = async ( await fetchUpgradedPackumentMemo(packageName, ['versions'], currentVersion, options, 0, npmConfig, npmConfigProject) )?.versions as Index const version = versionUtil.findGreatestByLevel( - filter(versions, filterPredicate(options)).map(o => o.version), + Object.values(versions || {}) + .filter(filterPredicate(options)) + .map(o => o.version), currentVersion, 'patch', ) @@ -891,7 +894,9 @@ export const semver: GetVersion = async ( // ignore explicit version ranges if (isExplicitRange(currentVersion)) return { version: null } - const versionsFiltered = filter(versions, filterPredicate(options)).map(o => o.version) + const versionsFiltered = Object.values(versions || {}) + .filter(filterPredicate(options)) + .map(o => o.version) // TODO: Upgrading within a prerelease does not seem to work. // { includePrerelease: true } does not help. const version = nodeSemver.maxSatisfying(versionsFiltered, currentVersion)