mirror of
https://github.com/microsoft/vscode.git
synced 2025-12-23 19:59:37 +00:00
[json] "Fetch Online Package Info" feature doesn't work when npm is not present. Fixes #77066
This commit is contained in:
@@ -25,7 +25,7 @@ export interface IJSONContribution {
|
|||||||
getDocumentSelector(): DocumentSelector;
|
getDocumentSelector(): DocumentSelector;
|
||||||
getInfoContribution(fileName: string, location: Location): Thenable<MarkedString[] | null> | null;
|
getInfoContribution(fileName: string, location: Location): Thenable<MarkedString[] | null> | null;
|
||||||
collectPropertySuggestions(fileName: string, location: Location, currentWord: string, addValue: boolean, isLast: boolean, result: ISuggestionsCollector): Thenable<any> | null;
|
collectPropertySuggestions(fileName: string, location: Location, currentWord: string, addValue: boolean, isLast: boolean, result: ISuggestionsCollector): Thenable<any> | null;
|
||||||
collectValueSuggestions(fileName: string, location: Location, result: ISuggestionsCollector): Thenable<any> | null;
|
collectValueSuggestions(fileName: string, location: Location, result: ISuggestionsCollector): Thenable<any>;
|
||||||
collectDefaultSuggestions(fileName: string, result: ISuggestionsCollector): Thenable<any>;
|
collectDefaultSuggestions(fileName: string, result: ISuggestionsCollector): Thenable<any>;
|
||||||
resolveSuggestion?(item: CompletionItem): Thenable<CompletionItem | null> | null;
|
resolveSuggestion?(item: CompletionItem): Thenable<CompletionItem | null> | null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -182,11 +182,7 @@ export class PackageJSONContribution implements IJSONContribution {
|
|||||||
return Promise.resolve(null);
|
return Promise.resolve(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public collectValueSuggestions(
|
public async collectValueSuggestions(_fileName: string, location: Location, result: ISuggestionsCollector): Promise<any> {
|
||||||
_fileName: string,
|
|
||||||
location: Location,
|
|
||||||
result: ISuggestionsCollector
|
|
||||||
): Thenable<any> | null {
|
|
||||||
if (!this.onlineEnabled()) {
|
if (!this.onlineEnabled()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -194,34 +190,30 @@ export class PackageJSONContribution implements IJSONContribution {
|
|||||||
if ((location.matches(['dependencies', '*']) || location.matches(['devDependencies', '*']) || location.matches(['optionalDependencies', '*']) || location.matches(['peerDependencies', '*']))) {
|
if ((location.matches(['dependencies', '*']) || location.matches(['devDependencies', '*']) || location.matches(['optionalDependencies', '*']) || location.matches(['peerDependencies', '*']))) {
|
||||||
const currentKey = location.path[location.path.length - 1];
|
const currentKey = location.path[location.path.length - 1];
|
||||||
if (typeof currentKey === 'string') {
|
if (typeof currentKey === 'string') {
|
||||||
return this.npmView(currentKey).then(info => {
|
const info = await this.fetchPackageInfo(currentKey);
|
||||||
const latest = info.distTagsLatest;
|
if (info && info.distTagsLatest) {
|
||||||
if (latest) {
|
|
||||||
let name = JSON.stringify(latest);
|
|
||||||
let proposal = new CompletionItem(name);
|
|
||||||
proposal.kind = CompletionItemKind.Property;
|
|
||||||
proposal.insertText = name;
|
|
||||||
proposal.documentation = localize('json.npm.latestversion', 'The currently latest version of the package');
|
|
||||||
result.add(proposal);
|
|
||||||
|
|
||||||
name = JSON.stringify('^' + latest);
|
let name = JSON.stringify(info.distTagsLatest);
|
||||||
proposal = new CompletionItem(name);
|
let proposal = new CompletionItem(name);
|
||||||
proposal.kind = CompletionItemKind.Property;
|
proposal.kind = CompletionItemKind.Property;
|
||||||
proposal.insertText = name;
|
proposal.insertText = name;
|
||||||
proposal.documentation = localize('json.npm.majorversion', 'Matches the most recent major version (1.x.x)');
|
proposal.documentation = localize('json.npm.latestversion', 'The currently latest version of the package');
|
||||||
result.add(proposal);
|
result.add(proposal);
|
||||||
|
|
||||||
name = JSON.stringify('~' + latest);
|
name = JSON.stringify('^' + info.distTagsLatest);
|
||||||
proposal = new CompletionItem(name);
|
proposal = new CompletionItem(name);
|
||||||
proposal.kind = CompletionItemKind.Property;
|
proposal.kind = CompletionItemKind.Property;
|
||||||
proposal.insertText = name;
|
proposal.insertText = name;
|
||||||
proposal.documentation = localize('json.npm.minorversion', 'Matches the most recent minor version (1.2.x)');
|
proposal.documentation = localize('json.npm.majorversion', 'Matches the most recent major version (1.x.x)');
|
||||||
result.add(proposal);
|
result.add(proposal);
|
||||||
}
|
|
||||||
return 0;
|
name = JSON.stringify('~' + info.distTagsLatest);
|
||||||
}, () => {
|
proposal = new CompletionItem(name);
|
||||||
return 0;
|
proposal.kind = CompletionItemKind.Property;
|
||||||
});
|
proposal.insertText = name;
|
||||||
|
proposal.documentation = localize('json.npm.minorversion', 'Matches the most recent minor version (1.2.x)');
|
||||||
|
result.add(proposal);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@@ -243,37 +235,73 @@ export class PackageJSONContribution implements IJSONContribution {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private getInfo(pack: string): Thenable<string[]> {
|
private async getInfo(pack: string): Promise<string[]> {
|
||||||
return this.npmView(pack).then(info => {
|
let info = await this.fetchPackageInfo(pack);
|
||||||
|
if (info) {
|
||||||
const result: string[] = [];
|
const result: string[] = [];
|
||||||
result.push(info.description || '');
|
result.push(info.description || '');
|
||||||
result.push(info.distTagsLatest ? localize('json.npm.version.hover', 'Latest version: {0}', info.distTagsLatest) : '');
|
result.push(info.distTagsLatest ? localize('json.npm.version.hover', 'Latest version: {0}', info.distTagsLatest) : '');
|
||||||
result.push(info.homepage || '');
|
result.push(info.homepage || '');
|
||||||
return result;
|
return result;
|
||||||
}, () => {
|
}
|
||||||
return [];
|
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
private async fetchPackageInfo(pack: string): Promise<ViewPackageInfo | undefined> {
|
||||||
|
let info = await this.npmView(pack);
|
||||||
|
if (!info) {
|
||||||
|
info = await this.npmjsView(pack);
|
||||||
|
}
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private npmView(pack: string): Promise<ViewPackageInfo | undefined> {
|
||||||
|
return new Promise((resolve, _reject) => {
|
||||||
|
const command = 'npm view --json ' + pack + ' description dist-tags.latest homepage';
|
||||||
|
cp.exec(command, (error, stdout) => {
|
||||||
|
if (!error) {
|
||||||
|
try {
|
||||||
|
const content = JSON.parse(stdout);
|
||||||
|
resolve({
|
||||||
|
description: content['description'],
|
||||||
|
distTagsLatest: content['dist-tags.latest'],
|
||||||
|
homepage: content['homepage']
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
} catch (e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resolve(undefined);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private npmView(pack: string): Promise<ViewPackageInfo> {
|
private async npmjsView(pack: string): Promise<ViewPackageInfo | undefined> {
|
||||||
return new Promise((resolve, reject) => {
|
const queryUrl = 'https://registry.npmjs.org/' + encodeURIComponent(pack).replace(/%40/g, '@');
|
||||||
const command = 'npm view --json ' + pack + ' description dist-tags.latest homepage';
|
try {
|
||||||
cp.exec(command, (error, stdout) => {
|
const success = await this.xhr({
|
||||||
if (error) {
|
url: queryUrl,
|
||||||
return reject();
|
agent: USER_AGENT
|
||||||
}
|
|
||||||
try {
|
|
||||||
const content = JSON.parse(stdout);
|
|
||||||
resolve({
|
|
||||||
description: content['description'],
|
|
||||||
distTagsLatest: content['dist-tags.latest'],
|
|
||||||
homepage: content['homepage']
|
|
||||||
});
|
|
||||||
} catch (e) {
|
|
||||||
reject();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
const obj = JSON.parse(success.responseText);
|
||||||
|
if (obj) {
|
||||||
|
const latest = obj && obj['dist-tags'] && obj['dist-tags']['latest'];
|
||||||
|
if (latest) {
|
||||||
|
return {
|
||||||
|
description: obj.description || '',
|
||||||
|
distTagsLatest: latest,
|
||||||
|
homepage: obj.homepage || ''
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
//ignore
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getInfoContribution(_fileName: string, location: Location): Thenable<MarkedString[] | null> | null {
|
public getInfoContribution(_fileName: string, location: Location): Thenable<MarkedString[] | null> | null {
|
||||||
|
|||||||
Reference in New Issue
Block a user