Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
throw new Error(`Invalid maxResults (${maxResults})`);
const existing = typeof workspace !== `undefined` && workspace !== null
? workspace.manifest[target].get(request.identHash) || null
: null;
const suggested = [];
for (const strategy of strategies) {
if (suggested.length >= maxResults)
break;
switch (strategy) {
case Strategy.KEEP: {
if (existing) {
const reason = `Keep ${structUtils.prettyDescriptor(project.configuration, existing)} (no changes)`;
suggested.push({descriptor: existing, reason});
}
} break;
case Strategy.REUSE: {
for (const {descriptor, locators} of (await findProjectDescriptors(request, {project, target})).values()) {
// We don't print the "reuse" key for the current workspace if the KEEP strategy is set since that would be redundant
if (locators.length === 1 && locators[0].locatorHash === workspace.anchoredLocator.locatorHash)
if (strategies.includes(Strategy.KEEP))
continue;
let reason = `Reuse ${structUtils.prettyDescriptor(project.configuration, descriptor)} (originally used by ${structUtils.prettyLocator(project.configuration, locators[0])}`;
reason += locators.length > 1
? ` and ${locators.length - 1} other${locators.length > 2 ? `s` : ``})`
: `)`;
switch (strategy) {
case Strategy.KEEP: {
if (existing) {
const reason = `Keep ${structUtils.prettyDescriptor(project.configuration, existing)} (no changes)`;
suggested.push({descriptor: existing, reason});
}
} break;
case Strategy.REUSE: {
for (const {descriptor, locators} of (await findProjectDescriptors(request, {project, target})).values()) {
// We don't print the "reuse" key for the current workspace if the KEEP strategy is set since that would be redundant
if (locators.length === 1 && locators[0].locatorHash === workspace.anchoredLocator.locatorHash)
if (strategies.includes(Strategy.KEEP))
continue;
let reason = `Reuse ${structUtils.prettyDescriptor(project.configuration, descriptor)} (originally used by ${structUtils.prettyLocator(project.configuration, locators[0])}`;
reason += locators.length > 1
? ` and ${locators.length - 1} other${locators.length > 2 ? `s` : ``})`
: `)`;
suggested.push({descriptor, reason});
}
} break;
case Strategy.CACHE: {
for (const descriptor of project.storedDescriptors.values()) {
if (descriptor.identHash === request.identHash) {
const reason = `Reuse ${structUtils.prettyDescriptor(project.configuration, descriptor)} (already used somewhere in the lockfile)`;
suggested.push({descriptor, reason});
}
}
}
}
const project = workspace.project;
for (const dependencyType of DEPENDENCY_TYPES) {
for (const [identHash, descriptor] of workspace.manifest.getForScope(dependencyType)) {
const matchingWorkspaces = project.findWorkspacesByDescriptor(descriptor);
const range = structUtils.parseRange(descriptor.range);
if (range.protocol !== WORKSPACE_PROTOCOL)
continue;
if (matchingWorkspaces.length === 0) {
if (project.workspacesByIdent.has(identHash)) {
throw new ReportError(MessageName.WORKSPACE_NOT_FOUND, `${structUtils.prettyDescriptor(project.configuration, descriptor)}: No local workspace found for this range`);
}
} else if (matchingWorkspaces.length > 1) {
throw new ReportError(MessageName.TOO_MANY_MATCHING_WORKSPACES, `${structUtils.prettyDescriptor(project.configuration, descriptor)}: Too many workspaces match this range, please disambiguate`);
} else {
const [matchingWorkspace] = matchingWorkspaces;
let versionToWrite: string;
// For workspace:path/to/workspace and workspace:* we look up the workspace version
if (structUtils.areDescriptorsEqual(descriptor, matchingWorkspace.anchoredDescriptor) || range.selector === `*`)
versionToWrite = matchingWorkspace.manifest.version!;
else
// for workspace:version we simply strip the protocol
versionToWrite = range.selector;
rawManifest[dependencyType][structUtils.stringifyIdent(descriptor)] = versionToWrite;
}, async report => {
for (const [/*workspace*/, /*target*/, existing, suggestions] of allSuggestions) {
const nonNullSuggestions = suggestions.filter(suggestion => {
return suggestion.descriptor !== null;
});
if (nonNullSuggestions.length === 0) {
if (!project.configuration.get(`enableNetwork`)) {
report.reportError(MessageName.CANT_SUGGEST_RESOLUTIONS, `${structUtils.prettyDescriptor(configuration, existing)} can't be resolved to a satisfying range (note: network resolution has been disabled)`);
} else {
report.reportError(MessageName.CANT_SUGGEST_RESOLUTIONS, `${structUtils.prettyDescriptor(configuration, existing)} can't be resolved to a satisfying range`);
}
} else if (nonNullSuggestions.length > 1 && !this.interactive) {
report.reportError(MessageName.CANT_SUGGEST_RESOLUTIONS, `${structUtils.prettyDescriptor(configuration, existing)} has multiple possible upgrade strategies; use -i to disambiguate manually`);
}
}
});
async function processManifest(workspace: Workspace, {configuration, report}: {configuration: Configuration, report: Report}) {
const resolveFn = await makeResolveFn(workspace.project);
for (const dependencyType of Manifest.hardDependencies) {
for (const viaDescriptor of workspace.manifest[dependencyType].values()) {
let pkg;
try {
pkg = await resolveFn(viaDescriptor);
} catch (error) {
report.reportWarning(MessageName.UNNAMED, `Resolving ${structUtils.prettyDescriptor(configuration, viaDescriptor)} errored with ${error.message}`);
continue;
}
if (!pkg) {
report.reportWarning(MessageName.UNNAMED, `Couldn't find a valid resolution for ${structUtils.prettyDescriptor(configuration, viaDescriptor)}`);
continue;
}
for (const peerDescriptor of pkg.peerDependencies.values()) {
await checkForUnmetPeerDependency(workspace, dependencyType, viaDescriptor, peerDescriptor, {configuration, report});
}
}
}
}
async function checkForUnmetPeerDependency(workspace: Workspace, dependencyType: HardDependencies, via: Descriptor, peer: Descriptor, {configuration, report}: {configuration: Configuration, report: Report}) {
if (dependencyType === `dependencies` && workspace.manifest.hasConsumerDependency(peer))
return;
if (dependencyType === `devDependencies` && workspace.manifest.hasHardDependency(peer))
return;
const propertyNode = await buildJsonNode(ppath.join(workspace.cwd, Manifest.fileName), [dependencyType, structUtils.stringifyIdent(via)]);
const prettyLocation = ast.prettyNodeLocation(configuration, propertyNode);
report.reportError(MessageName.UNNAMED, `${prettyLocation}: Unmet transitive peer dependency on ${structUtils.prettyDescriptor(configuration, peer)}, via ${structUtils.prettyDescriptor(configuration, via)}`);
}
}, async report => {
for (const [request, suggestions] of allSuggestions) {
const nonNullSuggestions = suggestions.filter(suggestion => {
return suggestion.descriptor !== null;
});
if (nonNullSuggestions.length === 0) {
if (!project.configuration.get(`enableNetwork`)) {
report.reportError(MessageName.CANT_SUGGEST_RESOLUTIONS, `${structUtils.prettyDescriptor(configuration, request)} can't be resolved to a satisfying range (note: network resolution has been disabled)`);
} else {
report.reportError(MessageName.CANT_SUGGEST_RESOLUTIONS, `${structUtils.prettyDescriptor(configuration, request)} can't be resolved to a satisfying range`);
}
}
}
});