Skip to content

Commit 57bf64b

Browse files
authored
fix, allow dependencies to be installed from https/git urls (teambit#9680)
1 parent 43501a3 commit 57bf64b

File tree

2 files changed

+18
-13
lines changed

2 files changed

+18
-13
lines changed

scopes/dependencies/dependency-resolver/dependency-resolver.main.runtime.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1379,11 +1379,13 @@ export class DependencyResolverMain {
13791379

13801380
validateAspectData(data: DependencyResolverComponentData) {
13811381
const errorPrefix = `failed validating ${DependencyResolverAspect.id} aspect-data.`;
1382+
const allowedPrefixes = ['https://', 'git:', 'git+ssh://', 'git+https://'];
13821383
let errorMsg: undefined | string;
13831384
data.dependencies?.forEach((dep) => {
13841385
const isVersionValid = Boolean(semver.valid(dep.version) || semver.validRange(dep.version));
13851386
if (isVersionValid) return;
13861387
if (dep.__type === COMPONENT_DEP_TYPE && isSnap(dep.version)) return;
1388+
if (allowedPrefixes.some((prefix) => dep.version.startsWith(prefix))) return; // some packages are installed from https/git
13871389
errorMsg = `${errorPrefix} the dependency version "${dep.version}" of ${dep.id} is not a valid semver version or range`;
13881390
});
13891391
data.policy?.forEach((policy) => {

scopes/workspace/install/install.cmd.tsx

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -163,24 +163,27 @@ export function getAnotherInstallRequiredOutput(recurringInstall = false, oldNon
163163
}
164164

165165
function extractPackageName(packageString: string): string {
166-
const lastAtIndex = packageString.lastIndexOf('@');
166+
if (!packageString) return '';
167167

168-
// If no '@' is present, or it's at the start (meaning it's just a scope),
169-
// we can assume there's no separate version part to remove.
170-
if (lastAtIndex <= 0) {
168+
// Handle https and git protocols. We don't allow "file" protocol here. It won't work for the consumer.
169+
const allowedPrefixes = ['https://', 'git:', 'git+ssh://', 'git+https://'];
170+
if (allowedPrefixes.some((prefix) => packageString.startsWith(prefix))) {
171171
return packageString;
172172
}
173173

174-
// Get everything after the last '@'
175-
const afterLastAt = packageString.slice(lastAtIndex + 1);
176-
177-
// If the substring after the last '@' contains a slash, it's part of the scoped package name,
178-
// not a version. In that case, do not remove anything.
179-
if (afterLastAt.includes('/')) {
180-
return packageString;
174+
// If it's a scoped package
175+
if (packageString.startsWith('@')) {
176+
// Find the second '@' (first is for scope, second is for version/tag)
177+
const atIndex = packageString.indexOf('@', 1);
178+
if (atIndex === -1) return packageString;
179+
const possibleVersion = packageString.slice(atIndex + 1);
180+
// If the part after the second '@' contains a slash, it's not a version/tag
181+
if (possibleVersion.includes('/')) return packageString;
182+
return packageString.slice(0, atIndex);
181183
}
182184

183-
// Otherwise, we assume that last '@' starts the version,
184-
// so we remove that part.
185+
// For unscoped packages, split at the last '@'
186+
const lastAtIndex = packageString.lastIndexOf('@');
187+
if (lastAtIndex <= 0) return packageString;
185188
return packageString.slice(0, lastAtIndex);
186189
}

0 commit comments

Comments
 (0)