Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: raineorshine/npm-check-updates
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v12.5.11
Choose a base ref
...
head repository: raineorshine/npm-check-updates
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v12.5.12
Choose a head ref
  • 3 commits
  • 8 files changed
  • 3 contributors

Commits on May 1, 2022

  1. Copy the full SHA
    650be0d View commit details

Commits on May 15, 2022

  1. Copy the full SHA
    fb63d4c View commit details
  2. 12.5.12

    raineorshine committed May 15, 2022
    Copy the full SHA
    d9377d7 View commit details
Showing with 141 additions and 108 deletions.
  1. +17 −15 README.md
  2. +2 −2 package-lock.json
  3. +1 −1 package.json
  4. +57 −57 src/cli-options.ts
  5. +4 −2 src/package-managers/npm.ts
  6. +25 −21 src/package-managers/yarn.ts
  7. +10 −10 src/types.ts
  8. +25 −0 test/package-managers/yarn/index.test.ts
32 changes: 17 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
@@ -128,9 +128,10 @@ ncu "/^(?!react-).*$/" # windows
--color Force color in terminal
--concurrency <n> Max number of concurrent HTTP requests to
registry. (default: 8)
--configFileName <filename> Config file name (default: .ncurc.{json,yml,js})
--configFilePath <path> Directory of .ncurc config file (default:
directory of `packageFile`).
--configFileName <filename> Config file name. (default:
.ncurc.{json,yml,js})
--configFilePath <path> Directory of .ncurc config file. (default:
directory of `packageFile`)
--cwd <path> Working directory in which npm will be executed.
--deep Run recursively in current working directory.
Alias of (--packageFile '**/package.json').
@@ -143,9 +144,9 @@ ncu "/^(?!react-).*$/" # windows
identify breaking upgrades. Run "ncu --doctor"
for detailed help. Add "-u" to execute.
--doctorInstall <command> Specifies the install script to use in doctor
mode (default: npm install/yarn).
--doctorTest <command> Specifies the test script to use in doctor mode
(default: npm test).
mode. (default: npm install/yarn)
--doctorTest <command> Specifies the test script to use in doctor mode.
(default: npm test)
--enginesNode Include only packages that satisfy engines.node
as specified in the package file.
-e, --errorLevel <n> Set the error level. 1: exits with error code 0
@@ -177,22 +178,22 @@ ncu "/^(?!react-).*$/" # windows
-l, --loglevel <n> Amount to log: silent, error, minimal, warn,
info, verbose, silly. (default: "warn")
--mergeConfig Merges nested configs with the root config file
for --deep or --packageFile options (default:
false)').
for --deep or --packageFile options. (default:
false)
-m, --minimal Do not upgrade newer versions that are already
satisfied by the version range according to
semver.
-n, --newest DEPRECATED. Renamed to "--target newest".
-o, --ownerChanged DEPRECATED. Renamed to "--format ownerChanged".
--packageData <value> Package file data (you can also use stdin).
--packageFile <path|glob> Package file(s) location (default:
./package.json).
--packageFile <path|glob> Package file(s) location. (default:
./package.json)
-p, --packageManager <name> npm, yarn (default: "npm")
--peer Check peer dependencies of installed packages
and filter updates to compatible versions. Run
"ncu --help --peer" for details.
--pre <n> Include -alpha, -beta, -rc. (default: 0; default
with --newest and --greatest: 1).
with --newest and --greatest: 1)
--prefix <path> Current working directory of npm.
-r, --registry <url> Third-party npm registry.
-x, --reject <matches> Exclude packages matching the given string,
@@ -206,12 +207,13 @@ ncu "/^(?!react-).*$/" # windows
package info. (default: 3)
--semverLevel <value> DEPRECATED. Renamed to --target.
-s, --silent Don't output anything (--loglevel silent).
-t, --target <value> Target version to upgrade to: latest, newest,
greatest, minor, patch. Run "ncu --help
--target" for details.` (default: "latest")
-t, --target <value> Target version or function that returns version
to upgrade to: latest, newest, greatest, minor,
patch. Run "ncu --help --target" for details.
(default: "latest")
--timeout <ms> Global timeout in milliseconds. (default: no
global timeout and 30 seconds per
npm-registry-fetch).
npm-registry-fetch)
-u, --upgrade Overwrite package file with upgraded versions
instead of just outputting to console.
-V, --version output the version number
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "npm-check-updates",
"version": "12.5.11",
"version": "12.5.12",
"author": "Tomas Junnonen <tomas1@gmail.com>",
"license": "Apache-2.0",
"contributors": [
114 changes: 57 additions & 57 deletions src/cli-options.ts
Original file line number Diff line number Diff line change
@@ -40,7 +40,7 @@ by each project's maintainers. Default.`])
other version numbers that are higher. Includes prereleases.`])
table.push(['patch', `Upgrade to the highest patch version without bumping the minor or major versions.`])

return `Set the target version that is upgraded to (default: "latest").
return `Set the target version that is upgraded to. (default: "latest")
${table.toString()}
@@ -62,47 +62,6 @@ You can also specify a custom function in your .ncurc.js file, or when importing

// store CLI options separately from bin file so that they can be used to build type definitions
const cliOptions: CLIOption[] = [
{
long: 'peer',
description: 'Check peer dependencies of installed packages and filter updates to compatible versions. Run "ncu --help --peer" for details.',
type: 'boolean',
help: `Check peer dependencies of installed packages and filter updates to compatible versions.
${chalk.bold('Example')}
The following example demonstrates how --peer works, and how it uses peer dependencies from upgraded modules.
The package ${chalk.bold('ncu-test-peer-update')} has two versions published:
- 1.0.0 has peer dependency "ncu-test-return-version": "1.0.x"
- 1.1.0 has peer dependency "ncu-test-return-version": "1.1.x"
Our test app has the following dependencies:
"ncu-test-peer-update": "1.0.0",
"ncu-test-return-version": "1.0.0"
The latest versions of these packages are:
"ncu-test-peer-update": "1.1.0",
"ncu-test-return-version": "2.0.0"
${chalk.bold('With --peer')}
ncu upgrades packages to the highest version that still adheres to the peer dependency constraints:
ncu-test-peer-update 1.0.0 → 1.${chalk.cyan('1.0')}
ncu-test-return-version 1.0.0 → 1.${chalk.cyan('1.0')}
${chalk.bold('Without --peer')}
As a comparison: without using the --peer option, ncu will suggest the latest versions, ignoring peer dependencies:
ncu-test-peer-update 1.0.0 → 1.${chalk.cyan('1.0')}
ncu-test-return-version 1.0.0 → ${chalk.red('2.0.0')}
`
},
{
long: 'color',
description: 'Force color in terminal',
@@ -117,12 +76,12 @@ As a comparison: without using the --peer option, ncu will suggest the latest ve
{
long: 'configFileName',
arg: 'filename',
description: 'Config file name (default: .ncurc.{json,yml,js})',
description: 'Config file name. (default: .ncurc.{json,yml,js})',
},
{
long: 'configFilePath',
arg: 'path',
description: 'Directory of .ncurc config file (default: directory of `packageFile`).',
description: 'Directory of .ncurc config file. (default: directory of `packageFile`)',
},
{
long: 'cwd',
@@ -134,11 +93,6 @@ As a comparison: without using the --peer option, ncu will suggest the latest ve
description: `Run recursively in current working directory. Alias of (--packageFile '${deepPatternPrefix}package.json').`,
type: 'boolean',
},
{
long: 'mergeConfig',
description: `Merges nested configs with the root config file for --deep or --packageFile options (default: false)').`,
type: 'boolean'
},
{
long: 'dep',
arg: 'value',
@@ -156,12 +110,12 @@ As a comparison: without using the --peer option, ncu will suggest the latest ve
{
long: 'doctorInstall',
arg: 'command',
description: 'Specifies the install script to use in doctor mode (default: npm install/yarn).',
description: 'Specifies the install script to use in doctor mode. (default: npm install/yarn)',
},
{
long: 'doctorTest',
arg: 'command',
description: 'Specifies the test script to use in doctor mode (default: npm test).',
description: 'Specifies the test script to use in doctor mode. (default: npm test)',
},
{
long: 'enginesNode',
@@ -233,13 +187,18 @@ As a comparison: without using the --peer option, ncu will suggest the latest ve
default: 'warn',
},
{
short: 'm',
long: 'mergeConfig',
description: `Merges nested configs with the root config file for --deep or --packageFile options. (default: false)`,
type: 'boolean'
},
{
long: 'minimal',
short: 'm',
description: 'Do not upgrade newer versions that are already satisfied by the version range according to semver.',
},
{
short: 'n',
long: 'newest',
short: 'n',
description: 'DEPRECATED. Renamed to "--target newest".',
deprecated: true,
},
@@ -257,7 +216,7 @@ As a comparison: without using the --peer option, ncu will suggest the latest ve
{
long: 'packageFile',
arg: 'path|glob',
description: 'Package file(s) location (default: ./package.json).',
description: 'Package file(s) location. (default: ./package.json)',
},
{
long: 'packageManager',
@@ -266,10 +225,51 @@ As a comparison: without using the --peer option, ncu will suggest the latest ve
// manual default to allow overriding auto yarn detection
description: 'npm, yarn (default: "npm")',
},
{
long: 'peer',
description: 'Check peer dependencies of installed packages and filter updates to compatible versions. Run "ncu --help --peer" for details.',
type: 'boolean',
help: `Check peer dependencies of installed packages and filter updates to compatible versions.
${chalk.bold('Example')}
The following example demonstrates how --peer works, and how it uses peer dependencies from upgraded modules.
The package ${chalk.bold('ncu-test-peer-update')} has two versions published:
- 1.0.0 has peer dependency "ncu-test-return-version": "1.0.x"
- 1.1.0 has peer dependency "ncu-test-return-version": "1.1.x"
Our test app has the following dependencies:
"ncu-test-peer-update": "1.0.0",
"ncu-test-return-version": "1.0.0"
The latest versions of these packages are:
"ncu-test-peer-update": "1.1.0",
"ncu-test-return-version": "2.0.0"
${chalk.bold('With --peer')}
ncu upgrades packages to the highest version that still adheres to the peer dependency constraints:
ncu-test-peer-update 1.0.0 → 1.${chalk.cyan('1.0')}
ncu-test-return-version 1.0.0 → 1.${chalk.cyan('1.0')}
${chalk.bold('Without --peer')}
As a comparison: without using the --peer option, ncu will suggest the latest versions, ignoring peer dependencies:
ncu-test-peer-update 1.0.0 → 1.${chalk.cyan('1.0')}
ncu-test-return-version 1.0.0 → ${chalk.red('2.0.0')}
`
},
{
long: 'pre',
arg: 'n',
description: 'Include -alpha, -beta, -rc. (default: 0; default with --newest and --greatest: 1).',
description: 'Include -alpha, -beta, -rc. (default: 0; default with --newest and --greatest: 1)',
type: 'number',
parse: s => !!parseInt(s, 10),
},
@@ -323,14 +323,14 @@ As a comparison: without using the --peer option, ncu will suggest the latest ve
long: 'target',
short: 't',
arg: 'value',
description: 'Target version to upgrade to: latest, newest, greatest, minor, patch. Run "ncu --help --target" for details.` (default: "latest")',
description: 'Target version or function that returns version to upgrade to: latest, newest, greatest, minor, patch. Run "ncu --help --target" for details. (default: "latest")',
help: getHelpTargetTable(),
type: 'string | TargetFunction',
},
{
long: 'timeout',
arg: 'ms',
description: 'Global timeout in milliseconds. (default: no global timeout and 30 seconds per npm-registry-fetch).',
description: 'Global timeout in milliseconds. (default: no global timeout and 30 seconds per npm-registry-fetch)',
},
{
long: 'upgrade',
6 changes: 4 additions & 2 deletions src/package-managers/npm.ts
Original file line number Diff line number Diff line change
@@ -134,6 +134,8 @@ export async function packageAuthorChanged(packageName: string, currentVersion:
return false
}

interface ViewOptions { registry?: string, timeout?: number, retry?: number }

/**
* Returns an object of specified values retrieved by npm view.
*
@@ -142,7 +144,7 @@ export async function packageAuthorChanged(packageName: string, currentVersion:
* @param currentVersion
* @returns Promised result
*/
export async function viewMany(packageName: string, fields: string[], currentVersion: Version, { registry, timeout, retry }: { registry?: string, timeout?: number, retry?: number } = {}, retryed = 0, npmConfigLocal?: Index<string | boolean>) {
export async function viewMany(packageName: string, fields: string[], currentVersion: Version, { registry, timeout, retry }: ViewOptions = {}, retryed = 0, npmConfigLocal?: Index<string | boolean>) {
if (currentVersion && (!semver.validRange(currentVersion) || versionUtil.isWildCard(currentVersion))) {
return Promise.resolve({} as Packument)
}
@@ -185,7 +187,7 @@ export const viewManyMemoized = memoize(viewMany)
* @param currentVersion
* @returns Promised result
*/
export async function viewOne(packageName: string, field: string, currentVersion: Version, options: Options = {}, npmConfigLocal?: Index<string | boolean>) {
export async function viewOne(packageName: string, field: string, currentVersion: Version, options: ViewOptions = {}, npmConfigLocal?: Index<string | boolean>) {
const result = await viewManyMemoized(packageName, [field], currentVersion, options, 0, npmConfigLocal)
return result && result[field as keyof Packument]
}
46 changes: 25 additions & 21 deletions src/package-managers/yarn.ts
Original file line number Diff line number Diff line change
@@ -19,7 +19,7 @@ interface ParsedDep {
from: string,
}

interface NpmScope {
export interface NpmScope {
npmAlwaysAuth?: boolean,
npmAuthToken?: string,
npmRegistryServer?: string,
@@ -31,15 +31,32 @@ interface YarnConfig {

const TIME_FIELDS = ['modified', 'created']

/** Safely interpolates a string as a template string. */
const interpolate = (s: string, data: any) => s.replace(/\$\{([^:-]+)(?:(:)?-([^}]*))?\}/g, (match, key, name, fallbackOnEmpty, fallback) => data[key] || (fallbackOnEmpty ? fallback : ''))

/** Reads an auth token from a yarn config, interpolates it, and sets it on the npm config. */
export const setNpmAuthToken = (npmConfig: Index<string|boolean>, [dep, scopedConfig]: [string, NpmScope]) => {
if (scopedConfig.npmAuthToken) {
// get registry server from this config or a previous config (assumes setNpmRegistry has already been called on all npm scopes)
const registryServer = scopedConfig.npmRegistryServer || npmConfig[`@${dep}:registry`] as string | undefined
// interpolate environment variable fallback
// https://yarnpkg.com/configuration/yarnrc
if (registryServer) {
let trimmedRegistryServer = registryServer.replace(/^https?:/, '')

if (trimmedRegistryServer.endsWith('/')) {
trimmedRegistryServer = trimmedRegistryServer.substring(0, trimmedRegistryServer.length - 1)
}

npmConfig[`${trimmedRegistryServer}/:_authToken`] = interpolate(scopedConfig.npmAuthToken, process.env)
}
}
}

// If private registry auth is specified in npmScopes in .yarnrc.yml, read them in and convert them to npm config variables.
// Define as a memoized function to efficiently call existsSync and readFileSync only once, and only if yarn is being used.
// https://github.com/raineorshine/npm-check-updates/issues/1036
const npmConfigFromYarn = memoize((): Index<string | boolean> => {

/** Safely interpolates a string as a template string. */
const interpolate = (s: string, data: any) =>
s.replace(/\$\{([^:-]+)(?:(:)?-([^}]*))?\}/g, (match, key, name, fallbackOnEmpty, fallback) => data[key] || (fallbackOnEmpty ? fallback : ''))

const npmConfig: Index<string | boolean> = {}
const yarnrcLocalExists = fs.existsSync('.yarnrc.yml')
const yarnrcUserExists = fs.existsSync('~/.yarnrc.yml')
@@ -48,19 +65,6 @@ const npmConfigFromYarn = memoize((): Index<string | boolean> => {
const yarnConfigLocal: YarnConfig = yaml.parse(yarnrcLocal)
const yarnConfigUser: YarnConfig = yaml.parse(yarnrcUser)

/** Reads an auth token from a yarn config, interpolates it, and sets it on the npm config. */
const setNpmAuthToken = ([dep, scopedConfig]: [string, NpmScope]) => {
if (scopedConfig.npmAuthToken) {
// get registry server from this config or a previous config (assumes setNpmRegistry has already been called on all npm scopes)
const registryServer = scopedConfig.npmRegistryServer || npmConfig[`@${dep}:registry`] as string | undefined
// interpolate environment variable fallback
// https://yarnpkg.com/configuration/yarnrc
if (registryServer) {
npmConfig[`${registryServer.replace(/^https?:/, '')}/:_authToken`] = interpolate(scopedConfig.npmAuthToken, process.env)
}
}
}

/** Reads a registry from a yarn config. interpolates it, and sets it on the npm config. */
const setNpmRegistry = ([dep, scopedConfig]: [string, NpmScope]) => {
if (scopedConfig.npmRegistryServer) {
@@ -73,8 +77,8 @@ const npmConfigFromYarn = memoize((): Index<string | boolean> => {
Object.entries(yarnConfigLocal?.npmScopes || {}).forEach(setNpmRegistry)

// set auth token after npm registry, since auth token syntax uses regitry
Object.entries(yarnConfigUser?.npmScopes || {}).forEach(setNpmAuthToken)
Object.entries(yarnConfigLocal?.npmScopes || {}).forEach(setNpmAuthToken)
Object.entries(yarnConfigUser?.npmScopes || {}).forEach(s => setNpmAuthToken(npmConfig, s))
Object.entries(yarnConfigLocal?.npmScopes || {}).forEach(s => setNpmAuthToken(npmConfig, s))

return npmConfig
})
Loading