Skip to content

Commit

Permalink
Merge pull request #1394 from SukkaW/reduce-bundle-size-1
Browse files Browse the repository at this point in the history
  • Loading branch information
raineorshine committed Apr 9, 2024
2 parents 4a9a34f + 6a07c39 commit c6a9723
Show file tree
Hide file tree
Showing 10 changed files with 73 additions and 64 deletions.
10 changes: 9 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -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',
{
Expand Down
3 changes: 1 addition & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import isString from 'lodash/isString'
import path from 'path'
import prompts from 'prompts-ncu'
import spawn from 'spawn-please'
Expand Down Expand Up @@ -296,7 +295,7 @@ export async function run(
let timeout: NodeJS.Timeout | undefined
let timeoutPromise: Promise<void> = 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
Expand Down
30 changes: 14 additions & 16 deletions src/lib/getNcuRc.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
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'
Expand Down Expand Up @@ -36,10 +33,13 @@ async function getNcuRc({
programError(options, `Config file ${configFileName} not found in ${configFilePath || process.cwd()}`)
}

// @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,
// 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
Expand All @@ -55,18 +55,16 @@ 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]): 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)
? [`--${name}`]
: // if a boolean option is false, exclude it
value === false || (cliOptionsMap[name]?.type === 'boolean' && !value)
? []
: // otherwise render as a 2-tuple
[`--${name}`, value],
)
: []

Expand Down
12 changes: 4 additions & 8 deletions src/lib/logging.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -87,13 +86,10 @@ export function printSimpleJoinedString(object: any, join: string) {
/** Prints an object sorted by key. */
export function printSorted<T extends { [key: string]: any }>(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<T>((accum, key) => {
accum[key] = obj[key]
return accum
}, {} as T)
print(options, objSorted, loglevel)
}

Expand Down
6 changes: 2 additions & 4 deletions src/lib/runLocal.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
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'
Expand Down Expand Up @@ -179,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) {
Expand Down Expand Up @@ -249,7 +247,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)
}
}
Expand Down
3 changes: 1 addition & 2 deletions src/lib/upgradePackageDefinitions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import isEmpty from 'lodash/isEmpty'
import isEqual from 'lodash/isEqual'
import pickBy from 'lodash/pickBy'
import { satisfies } from 'semver'
Expand Down Expand Up @@ -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)) {
Expand Down
3 changes: 1 addition & 2 deletions src/lib/version-util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -333,7 +332,7 @@ export function findGreatestByLevel(versions: string[], current: string, level:
)
})

return last(versionsSorted) || null
return versionsSorted.at(-1) || null
}

/**
Expand Down
5 changes: 2 additions & 3 deletions src/package-managers/filters.ts
Original file line number Diff line number Diff line change
@@ -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'
Expand Down Expand Up @@ -36,9 +35,9 @@ export function allowPreOrIsNotPre(versionResult: Partial<Packument>, options: O
*/
export function satisfiesNodeEngine(versionResult: Partial<Packument>, nodeEngineVersion: Maybe<string>): 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)
}

Expand Down
1 change: 0 additions & 1 deletion src/package-managers/gitTags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
}
Expand Down
64 changes: 39 additions & 25 deletions src/package-managers/npm.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
import memoize from 'fast-memoize'
import fs from 'fs'
import ini from 'ini'
import { uniq } from 'lodash'
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 uniq from 'lodash/uniq'
import npmRegistryFetch from 'npm-registry-fetch'
import path from 'path'
import nodeSemver from 'semver'
Expand Down Expand Up @@ -371,11 +368,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,
}),
},
})
Expand Down Expand Up @@ -404,28 +403,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 = {
Expand All @@ -442,7 +446,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
Expand Down Expand Up @@ -527,19 +533,21 @@ export const fetchUpgradedPackumentMemo = memoize(fetchUpgradedPackument, {
retried,
npmConfigLocal,
npmConfigWorkspaceProject,
]: Parameters<typeof fetchUpgradedPackument>) =>
JSON.stringify([
]: Parameters<typeof fetchUpgradedPackument>) => {
// 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,
})

/**
Expand Down Expand Up @@ -636,11 +644,11 @@ export const greatest: GetVersion = async (

return {
version:
last(
filter(versions, filterPredicate(options))
.map(o => o.version)
.sort(versionUtil.compareVersions),
) || null,
Object.values(versions || {})
.filter(filterPredicate(options))
.map(o => o.version)
.sort(versionUtil.compareVersions)
.at(-1) || null,
}
}

Expand Down Expand Up @@ -806,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) }
}

/**
Expand All @@ -828,7 +836,9 @@ export const minor: GetVersion = async (
await fetchUpgradedPackumentMemo(packageName, ['versions'], currentVersion, options, 0, npmConfig, npmConfigProject)
)?.versions as Index<Packument>
const version = versionUtil.findGreatestByLevel(
filter(versions, filterPredicate(options)).map(o => o.version),
Object.values(versions || {})
.filter(filterPredicate(options))
.map(o => o.version),
currentVersion,
'minor',
)
Expand All @@ -854,7 +864,9 @@ export const patch: GetVersion = async (
await fetchUpgradedPackumentMemo(packageName, ['versions'], currentVersion, options, 0, npmConfig, npmConfigProject)
)?.versions as Index<Packument>
const version = versionUtil.findGreatestByLevel(
filter(versions, filterPredicate(options)).map(o => o.version),
Object.values(versions || {})
.filter(filterPredicate(options))
.map(o => o.version),
currentVersion,
'patch',
)
Expand Down Expand Up @@ -882,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)
Expand Down

0 comments on commit c6a9723

Please sign in to comment.