Skip to content

Commit 5bc6b66

Browse files
committed
feat: allow "npm:name@version" dependency redirections in manifest
1 parent 2f7a489 commit 5bc6b66

File tree

4 files changed

+37
-5
lines changed

4 files changed

+37
-5
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
"execa": "^8.0.1",
3333
"pony-cause": "^2.1.9",
3434
"semver": "^7.5.4",
35+
"validate-npm-package-name": "^5.0.0",
3536
"which": "^3.0.0",
3637
"yaml": "^2.2.2",
3738
"yargs": "^17.7.1"

src/package-manifest.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ describe('package-manifest', () => {
6767
b: '^2.0.0',
6868
c: '~4.3.0',
6969
d: 'workspace:^',
70+
e: 'npm:a@^2.0.0',
7071
},
7172
};
7273
const validated = {
@@ -79,6 +80,7 @@ describe('package-manifest', () => {
7980
b: '^2.0.0',
8081
c: '~4.3.0',
8182
d: 'workspace:^',
83+
e: 'npm:a@^2.0.0',
8284
},
8385
peerDependencies: {},
8486
};

src/package-manifest.ts

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
ManifestDependencyFieldNames as PackageManifestDependenciesFieldNames,
55
} from '@metamask/action-utils';
66
import { isPlainObject } from '@metamask/utils';
7+
import validateNPMPackageName from 'validate-npm-package-name';
78
import { readJsonObjectFile } from './fs.js';
89
import { isTruthyString } from './misc-utils.js';
910
import { semver, SemVer } from './semver.js';
@@ -144,8 +145,10 @@ function isValidPackageManifestVersionField(
144145

145146
/**
146147
* Type guard to ensure that the provided version value is a valid dependency version
147-
* specifier for a package manifest. This function validates both semantic versioning
148-
* ranges and the special 'workspace:^' notation.
148+
* specifier for a package manifest. This function validates:
149+
* semantic versioning ranges
150+
* 'workspace:^' notation
151+
* 'npm:{packageName}:{semverRange}' redirections.
149152
*
150153
* @param version - The value to check.
151154
* @returns `true` if the version is a valid string that either
@@ -155,9 +158,34 @@ function isValidPackageManifestVersionField(
155158
function isValidPackageManifestDependencyValue(
156159
version: unknown,
157160
): version is string {
158-
return (
159-
isValidPackageManifestVersionField(version) || version === 'workspace:^'
160-
);
161+
if (typeof version !== 'string') {
162+
return false;
163+
}
164+
165+
if (
166+
isValidPackageManifestVersionField(version) ||
167+
version === 'workspace:^'
168+
) {
169+
return true;
170+
}
171+
172+
const redirectedDependencyRegexp = /^npm:(.*)@(.*?)$/u;
173+
174+
try {
175+
const redirectedDependencyMatch = redirectedDependencyRegexp.exec(version);
176+
177+
if (!redirectedDependencyMatch || redirectedDependencyMatch.length < 3) {
178+
return false;
179+
}
180+
181+
const [, redirectedName, redirectedVersion] = redirectedDependencyMatch;
182+
return (
183+
validateNPMPackageName(redirectedName)?.validForOldPackages &&
184+
isValidPackageManifestVersionField(redirectedVersion)
185+
);
186+
} catch (e) {
187+
return false;
188+
}
161189
}
162190

163191
/**

yarn.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2117,6 +2117,7 @@ __metadata:
21172117
stdio-mock: ^1.2.0
21182118
tsx: ^4.6.1
21192119
typescript: ~5.1.6
2120+
validate-npm-package-name: ^5.0.0
21202121
which: ^3.0.0
21212122
yaml: ^2.2.2
21222123
yargs: ^17.7.1

0 commit comments

Comments
 (0)