Move npm spec out of upstream

Part of #284593
This commit is contained in:
Daniel Imms
2025-12-20 06:24:14 -08:00
parent d87d06f0e6
commit c348a9a82b
3 changed files with 72 additions and 71 deletions
@@ -16,82 +16,82 @@ const atsInStr = (s: string) => (s.match(/@/g) || []).length;
export const createNpmSearchHandler =
(keywords?: string[]) =>
async (
context: string[],
executeShellCommand: Fig.ExecuteCommandFunction,
shellContext: Fig.ShellContext
): Promise<Fig.Suggestion[]> => {
const searchTerm = context[context.length - 1];
if (searchTerm === "") {
return [];
}
// Add optional keyword parameter
const keywordParameter =
keywords && keywords.length > 0 ? `+keywords:${keywords.join(",")}` : "";
async (
context: string[],
executeShellCommand: Fig.ExecuteCommandFunction,
shellContext: Fig.ShellContext
): Promise<Fig.Suggestion[]> => {
const searchTerm = context[context.length - 1];
if (searchTerm === "") {
return [];
}
// Add optional keyword parameter
const keywordParameter =
keywords && keywords.length > 0 ? `+keywords:${keywords.join(",")}` : "";
const queryPackagesUrl = keywordParameter
? `https://api.npms.io/v2/search?size=20&q=${searchTerm}${keywordParameter}`
: `https://api.npms.io/v2/search/suggestions?q=${searchTerm}&size=20`;
const queryPackagesUrl = keywordParameter
? `https://api.npms.io/v2/search?size=20&q=${searchTerm}${keywordParameter}`
: `https://api.npms.io/v2/search/suggestions?q=${searchTerm}&size=20`;
// Query the API with the package name
const queryPackages = [
"-s",
"-H",
"Accept: application/json",
queryPackagesUrl,
];
// We need to remove the '@' at the end of the searchTerm before querying versions
const queryVersions = [
"-s",
"-H",
"Accept: application/vnd.npm.install-v1+json",
`https://registry.npmjs.org/${searchTerm.slice(0, -1)}`,
];
// If the end of our token is '@', then we want to generate version suggestions
// Otherwise, we want packages
const out = (query: string) =>
executeShellCommand({
command: "curl",
args: query[query.length - 1] === "@" ? queryVersions : queryPackages,
});
// If our token starts with '@', then a 2nd '@' tells us we want
// versions.
// Otherwise, '@' anywhere else in the string will indicate the same.
const shouldGetVersion = searchTerm.startsWith("@")
? atsInStr(searchTerm) > 1
: searchTerm.includes("@");
// Query the API with the package name
const queryPackages = [
"-s",
"-H",
"Accept: application/json",
queryPackagesUrl,
];
// We need to remove the '@' at the end of the searchTerm before querying versions
const queryVersions = [
"-s",
"-H",
"Accept: application/vnd.npm.install-v1+json",
`https://registry.npmjs.org/${searchTerm.slice(0, -1)}`,
];
// If the end of our token is '@', then we want to generate version suggestions
// Otherwise, we want packages
const out = (query: string) =>
executeShellCommand({
command: "curl",
args: query[query.length - 1] === "@" ? queryVersions : queryPackages,
});
// If our token starts with '@', then a 2nd '@' tells us we want
// versions.
// Otherwise, '@' anywhere else in the string will indicate the same.
const shouldGetVersion = searchTerm.startsWith("@")
? atsInStr(searchTerm) > 1
: searchTerm.includes("@");
try {
const data = JSON.parse((await out(searchTerm)).stdout);
if (shouldGetVersion) {
// create dist tags suggestions
const versions = Object.entries(data["dist-tags"] || {}).map(
([key, value]) => ({
name: key,
description: value,
try {
const data = JSON.parse((await out(searchTerm)).stdout);
if (shouldGetVersion) {
// create dist tags suggestions
const versions = Object.entries(data["dist-tags"] || {}).map(
([key, value]) => ({
name: key,
description: value,
})
) as Fig.Suggestion[];
// create versions
versions.push(
...Object.keys(data.versions)
.map((version) => ({ name: version }) as Fig.Suggestion)
.reverse()
);
return versions;
}
const results = keywordParameter ? data.results : data;
return results.map(
(item: { package: { name: string; description: string } }) => ({
name: item.package.name,
description: item.package.description,
})
) as Fig.Suggestion[];
// create versions
versions.push(
...Object.keys(data.versions)
.map((version) => ({ name: version }) as Fig.Suggestion)
.reverse()
);
return versions;
} catch (error) {
console.error({ error });
return [];
}
const results = keywordParameter ? data.results : data;
return results.map(
(item: { package: { name: string; description: string } }) => ({
name: item.package.name,
description: item.package.description,
})
) as Fig.Suggestion[];
} catch (error) {
console.error({ error });
return [];
}
};
};
// GENERATORS
export const npmSearchGenerator: Fig.Generator = {
@@ -113,7 +113,6 @@ export const upstreamSpecs = [
// JavaScript / TypeScript
'node',
'npm',
'nvm',
'pnpm',
'yarn',
@@ -16,6 +16,7 @@ import codeTunnelInsidersCompletionSpec from './completions/code-tunnel-insiders
import copilotSpec from './completions/copilot';
import gitCompletionSpec from './completions/git';
import ghCompletionSpec from './completions/gh';
import npmCompletionSpec from './completions/npm';
import npxCompletionSpec from './completions/npx';
import setLocationSpec from './completions/set-location';
import { upstreamSpecs } from './constants';
@@ -69,6 +70,7 @@ export const availableSpecs: Fig.Spec[] = [
copilotSpec,
gitCompletionSpec,
ghCompletionSpec,
npmCompletionSpec,
npxCompletionSpec,
setLocationSpec,
];