diff --git a/README.md b/README.md
index c6c7eb69..7110a7d5 100644
--- a/README.md
+++ b/README.md
@@ -251,7 +251,7 @@ Options that take no arguments can be negated by prefixing them with `--no-`, e.
--format <value> |
- Modify the output formatting or show additional information. Specify one or more comma-delimited values: group, ownerChanged, repo, time, lines. (default: []) |
+ Modify the output formatting or show additional information. Specify one or more comma-delimited values: group, ownerChanged, repo, time, lines, exactCurrentVersion. (default: []) |
-g, --global |
@@ -544,6 +544,7 @@ Modify the output formatting or show additional information. Specify one or more
repo | Infers and displays links to the package's source code repository. Requires packages to be installed. |
time | Shows the publish time of each upgrade. |
lines | Prints name@version on separate lines. Useful for piping to npm install. |
+ exactCurrentVersion | Prints the exact current version number instead of a range. |
## groupFunction
diff --git a/src/cli-options.ts b/src/cli-options.ts
index d96f4eac..b7023bee 100755
--- a/src/cli-options.ts
+++ b/src/cli-options.ts
@@ -176,6 +176,7 @@ const extendedHelpFormat: ExtendedHelp = ({ markdown }) => {
['repo', `Infers and displays links to the package's source code repository. Requires packages to be installed.`],
['time', 'Shows the publish time of each upgrade.'],
['lines', 'Prints name@version on separate lines. Useful for piping to npm install.'],
+ ['exactCurrentVersion', 'Prints the exact current version number instead of a range.'],
],
})
@@ -664,11 +665,11 @@ const cliOptions: CLIOption[] = [
long: 'format',
arg: 'value',
description:
- 'Modify the output formatting or show additional information. Specify one or more comma-delimited values: group, ownerChanged, repo, time, lines.',
+ 'Modify the output formatting or show additional information. Specify one or more comma-delimited values: group, ownerChanged, repo, time, lines, exactCurrentVersion.',
parse: value => (typeof value === 'string' ? value.split(',') : value),
default: [],
type: 'string[]',
- choices: ['group', 'ownerChanged', 'repo', 'time', 'lines'],
+ choices: ['group', 'ownerChanged', 'repo', 'time', 'lines', 'exactCurrentVersion'],
help: extendedHelpFormat,
},
{
diff --git a/src/lib/getPackageJson.ts b/src/lib/getPackageJson.ts
new file mode 100644
index 00000000..1c86c76e
--- /dev/null
+++ b/src/lib/getPackageJson.ts
@@ -0,0 +1,34 @@
+import fs from 'fs/promises'
+import path from 'path'
+import { PackageFile } from '../types/PackageFile'
+import exists from './exists'
+
+/** Gets the package.json contents of an installed package. */
+async function getPackageJson(
+ packageName: string,
+ {
+ pkgFile,
+ }: {
+ /** Specify the package file location to add to the node_modules search paths. Needed in workspaces/deep mode. */
+ pkgFile?: string
+ } = {},
+): Promise {
+ const requirePaths = require.resolve.paths(packageName) || []
+ const pkgFileNodeModules = pkgFile ? [path.join(path.dirname(pkgFile), 'node_modules')] : []
+ const localNodeModules = [path.join(process.cwd(), 'node_modules')]
+ const nodeModulePaths = [...pkgFileNodeModules, ...localNodeModules, ...requirePaths]
+
+ for (const basePath of nodeModulePaths) {
+ const packageJsonPath = path.join(basePath, packageName, 'package.json')
+ if (await exists(packageJsonPath)) {
+ try {
+ const packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf-8'))
+ return packageJson
+ } catch (e) {}
+ }
+ }
+
+ return null
+}
+
+export default getPackageJson
diff --git a/src/lib/getPackageVersion.ts b/src/lib/getPackageVersion.ts
new file mode 100644
index 00000000..89f7ed93
--- /dev/null
+++ b/src/lib/getPackageVersion.ts
@@ -0,0 +1,27 @@
+import { PackageFile } from '../types/PackageFile'
+import getPackageJson from './getPackageJson'
+
+/**
+ * @param packageName A package name as listed in package.json's dependencies list
+ * @param packageJson Optional param to specify a object representation of a package.json file instead of loading from node_modules
+ * @returns The package version or null if a version could not be determined
+ */
+async function getPackageVersion(
+ packageName: string,
+ packageJson?: PackageFile,
+ {
+ pkgFile,
+ }: {
+ /** Specify the package file location to add to the node_modules search paths. Needed in workspaces/deep mode. */
+ pkgFile?: string
+ } = {},
+) {
+ if (packageJson) {
+ return packageJson.version
+ }
+
+ const loadedPackageJson = await getPackageJson(packageName, { pkgFile })
+ return loadedPackageJson?.version ?? null
+}
+
+export default getPackageVersion
diff --git a/src/lib/getRepoUrl.ts b/src/lib/getRepoUrl.ts
index f6851985..49e42cd0 100644
--- a/src/lib/getRepoUrl.ts
+++ b/src/lib/getRepoUrl.ts
@@ -1,10 +1,8 @@
-import fs from 'fs/promises'
import hostedGitInfo from 'hosted-git-info'
-import path from 'path'
import { URL } from 'url'
import { PackageFile } from '../types/PackageFile'
import { PackageFileRepository } from '../types/PackageFileRepository'
-import exists from './exists'
+import getPackageJson from './getPackageJson'
/** Gets the repo url of an installed package. */
async function getPackageRepo(
@@ -15,23 +13,9 @@ async function getPackageRepo(
/** Specify the package file location to add to the node_modules search paths. Needed in workspaces/deep mode. */
pkgFile?: string
} = {},
-): Promise {
- const requirePaths = require.resolve.paths(packageName) || []
- const pkgFileNodeModules = pkgFile ? [path.join(path.dirname(pkgFile), 'node_modules')] : []
- const localNodeModules = [path.join(process.cwd(), 'node_modules')]
- const nodeModulePaths = [...pkgFileNodeModules, ...localNodeModules, ...requirePaths]
-
- for (const basePath of nodeModulePaths) {
- const packageJsonPath = path.join(basePath, packageName, 'package.json')
- if (await exists(packageJsonPath)) {
- try {
- const packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf-8'))
- return packageJson.repository
- } catch (e) {}
- }
- }
-
- return null
+): Promise {
+ const packageJson = await getPackageJson(packageName, { pkgFile })
+ return packageJson?.repository ?? null
}
/**
diff --git a/src/lib/logging.ts b/src/lib/logging.ts
index 091c3427..fdc69588 100755
--- a/src/lib/logging.ts
+++ b/src/lib/logging.ts
@@ -10,6 +10,7 @@ import { VersionResult } from '../types/VersionResult'
import { VersionSpec } from '../types/VersionSpec'
import chalk from './chalk'
import filterObject from './filterObject'
+import getPackageVersion from './getPackageVersion'
import getRepoUrl from './getRepoUrl'
import {
colorizeDiff,
@@ -168,7 +169,10 @@ export async function toDependencyTable({
Object.keys(toDeps)
.sort()
.map(async dep => {
- const from = fromDeps[dep] || ''
+ const from =
+ (format?.includes('exactCurrentVersion')
+ ? await getPackageVersion(dep, undefined, { pkgFile })
+ : fromDeps[dep]) || ''
const toRaw = toDeps[dep] || ''
const to = getVersion(toRaw)
const ownerChanged = ownersChangedDeps
diff --git a/src/types/PackageFile.ts b/src/types/PackageFile.ts
index 99223c1e..e7ad7d87 100644
--- a/src/types/PackageFile.ts
+++ b/src/types/PackageFile.ts
@@ -22,4 +22,5 @@ export interface PackageFile {
repository?: string | PackageFileRepository
scripts?: Index
workspaces?: string[] | { packages: string[] }
+ version?: string
}
diff --git a/src/types/RunOptions.json b/src/types/RunOptions.json
index 900237ba..4f716ad8 100644
--- a/src/types/RunOptions.json
+++ b/src/types/RunOptions.json
@@ -68,6 +68,9 @@
"$ref": "#/definitions/Index",
"description": "A very generic object."
},
+ "version": {
+ "type": "string"
+ },
"workspaces": {
"anyOf": [
{
@@ -284,7 +287,7 @@
"description": "Filter on package version using comma-or-space-delimited list, /regex/, or predicate function. Run \"ncu --help --filterVersion\" for details."
},
"format": {
- "description": "Modify the output formatting or show additional information. Specify one or more comma-delimited values: group, ownerChanged, repo, time, lines. Run \"ncu --help --format\" for details.",
+ "description": "Modify the output formatting or show additional information. Specify one or more comma-delimited values: group, ownerChanged, repo, time, lines, exactCurrentVersion. Run \"ncu --help --format\" for details.",
"items": {
"type": "string"
},
diff --git a/src/types/RunOptions.ts b/src/types/RunOptions.ts
index e4565233..f45d6b38 100644
--- a/src/types/RunOptions.ts
+++ b/src/types/RunOptions.ts
@@ -85,7 +85,7 @@ export interface RunOptions {
/** Filter on package version using comma-or-space-delimited list, /regex/, or predicate function. Run "ncu --help --filterVersion" for details. */
filterVersion?: string | RegExp | (string | RegExp)[] | FilterFunction
- /** Modify the output formatting or show additional information. Specify one or more comma-delimited values: group, ownerChanged, repo, time, lines. Run "ncu --help --format" for details. */
+ /** Modify the output formatting or show additional information. Specify one or more comma-delimited values: group, ownerChanged, repo, time, lines, exactCurrentVersion. Run "ncu --help --format" for details. */
format?: string[]
/** Check global packages instead of in the current project. */