Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@oclif/plugin-search

Package Overview
Dependencies
Maintainers
0
Versions
76
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@oclif/plugin-search - npm Package Compare versions

Comparing version 1.2.12-dev.0 to 1.2.12

4

dist/commands/search.d.ts
import { Command } from '@oclif/core';
export default class Search extends Command {
static description: string;
static readonly flags: {
action: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
};
static readonly strict = false;
static summary: string;
run(): Promise<unknown>;
}

@@ -7,32 +7,11 @@ /*

*/
import search from '@inquirer/search';
import { Command, Flags, loadHelpClass, toConfiguredId, toStandardizedId, ux } from '@oclif/core';
import { bold } from 'ansis';
import clipboard from 'clipboardy';
import fuzzysort from 'fuzzysort';
import { got } from 'got';
import { Command, loadHelpClass, toConfiguredId, toStandardizedId, ux } from '@oclif/core';
import ansiEscapes from 'ansi-escapes';
import autocomplete from 'inquirer-autocomplete-standalone';
import readline from 'node:readline';
import open from 'open';
export default class Search extends Command {
static description = 'Once you select a command, hit enter and it will show the help for that command.';
static flags = {
action: Flags.string({
char: 'a',
options: ['help', 'copy', 'doctor', 'source', 'npm'],
summary: 'Action to take on the selected command',
}),
};
static strict = false;
static summary = 'Search for a command.';
async run() {
const { argv, flags } = await this.parse(Search);
// Join the args together into a string so you can pass something like 'dep sta' to fuzzy search
const args = argv.join(' ');
const theme = {
helpMode: 'never',
prefix: ux.colorize('cyan', `Use ${ux.colorize('bold', '↑')} and ${ux.colorize('bold', '↓')} keys or type to search for a command.\nPress ${ux.colorize('bold', 'ENTER')} to view help. Press ${ux.colorize('bold', 'ESC')} to exit.\n\n`),
style: {
description: (desc) => `\n${ux.colorize('cyan', desc)}`, // Give the description a little extra padding
},
};
this.log(ux.colorize('cyan', `Use ${ux.colorize('bold', '↑')} and ${ux.colorize('bold', '↓')} keys or type to search for a command.\nPress ${ux.colorize('bold', 'ENTER')} to view help. Press ${ux.colorize('bold', 'ESC')} to exit.\n`));
const commandChoices = this.config.commands

@@ -50,33 +29,22 @@ .filter((c) => !c.hidden && !c.aliases.includes(c.id))

const pageSize = Math.floor(process.stdout.rows < 20 ? process.stdout.rows / 2 : 10);
const commandPromise = search({
const commandPromise = autocomplete({
emptyText: 'Nothing found!',
message: 'Search for a command',
pageSize,
async source(input) {
// TODO: There is a bug here somewhere:
// - pass an arg
// - hit down arrow
// - hit any other character with clear the input
// - hitting delete will clear input, but keep the fuzzy results
if (input === undefined && args)
input = args;
const results = fuzzysort.go(input, commandChoices, { all: true, key: 'name' });
return results.map((r) => ({
description: r.obj.description,
name: r.highlight(bold.open, bold.close),
value: r.obj.value,
}));
return input ? commandChoices.filter((c) => c.name.includes(input)) : commandChoices;
},
// @ts-expect-error Not sure why this is complaining about the helpMode type
theme,
}, { clearPromptOnDone: true });
});
function cancel() {
commandPromise.cancel();
// erase the list of commands
process.stdout.write(ansiEscapes.eraseLines(pageSize + 3));
}
readline.emitKeypressEvents(process.stdin);
process.stdin.setRawMode(true);
// If args were passed in, we "replay" the key presses to populate the search
if (args)
process.stdin.emit('data', args);
// Allow the user to exit the search with the escape key or with ctrl+c
process.stdin.on('keypress', (_, key) => {
if ((key.name === 'escape' || (key.name === 'c' && key.ctrl)) && commandPromise) {
commandPromise.cancel();
}
if (key.name === 'escape')
cancel();
if (key.name === 'c' && key.ctrl)
cancel();
});

@@ -92,118 +60,6 @@ const command = await commandPromise

return;
// eslint-disable-next-line unicorn/consistent-function-scoping
const getPluginDetails = (command) => {
const commandId = toStandardizedId(command, this.config);
const commandConfig = this.config.findCommand(commandId);
const pluginName = commandConfig?.pluginName;
if (!pluginName)
this.error('Key `pluginName` not found in the config for this command.');
const commandPjson = this.config.plugins.get(pluginName)?.pjson;
const homepage = commandPjson?.homepage;
// TODO: add a check for homepage
const commandVersion = commandPjson?.version;
return { commandConfig, commandId, commandPjson, commandVersion, homepage, pluginName };
};
const getSourceUrl = async (homepage, commandId, commandVersion) => {
if (!homepage)
return;
const commandToPath = `${commandId.replaceAll(':', '/')}.ts`;
// TODO: do we need to take into account directory level index.ts command files?
// TODO: talk to Mike about dynamically built command paths
const urls = [
`/blob/${commandVersion}/src/commands/${commandToPath}`,
`/blob/v${commandVersion}/src/commands/${commandToPath}`,
`/blob/-/src/commands/${commandToPath}`,
`/blob/main/src/commands/${commandToPath}`,
`/blob/master/src/commands/${commandToPath}`,
];
const responses = await Promise.all(urls.map((url) => got(`${homepage}${url}`, { throwHttpErrors: false })));
return responses.find((r) => r.statusCode === 200)?.url ?? undefined;
};
const { commandId, commandVersion, homepage, pluginName } = getPluginDetails(command);
const sourceUrl = await getSourceUrl(homepage, commandId, commandVersion);
let actionPrompt;
if (!flags.action) {
const actions = [
{
description: 'Show the help text for this command',
name: 'Show help',
value: 'help',
},
{
description: 'Copy the command to your clipboard',
name: 'Copy command',
value: 'copy',
},
{
description: 'Copy the command to your clipboard for use with the doctor command',
name: 'Copy command for doctor',
value: 'doctor',
},
{
description: 'Open the source code for this command on GitHub',
disabled: sourceUrl ? false : '(Unable to resolve source code URL)',
name: 'Go to source code',
value: 'source',
},
{
description: 'View the npm details for this package',
name: 'View package on npm',
value: 'npm',
},
];
const actionPromise = search({
message: `Select an action for: ${ux.colorize('dim', '$ sf ' + command)}`,
pageSize,
async source(input) {
const results = fuzzysort.go(input, actions, { all: true, key: 'name' });
return results.map((r) => ({
description: r.obj.description,
disabled: r.obj.disabled,
name: r.highlight(bold.open, bold.close),
value: r.obj.value,
}));
},
// @ts-expect-error Not sure why this is complaining about the helpMode type
theme,
}, { clearPromptOnDone: true });
// Allow the user to exit the search with the escape key or with ctrl+c
process.stdin.on('keypress', (_, key) => {
if ((key.name === 'escape' || (key.name === 'c' && key.ctrl)) && actionPromise) {
actionPromise.cancel();
}
});
actionPrompt = await actionPromise
.catch((error) => {
if (error.message === 'Prompt was canceled')
return;
throw error;
})
.then((result) => result);
}
switch (flags.action ?? actionPrompt) {
case 'help': {
const Help = await loadHelpClass(this.config);
const help = new Help(this.config, this.config.pjson.oclif.helpOptions ?? this.config.pjson.helpOptions);
return help.showHelp([toStandardizedId(command, this.config)]);
}
case 'copy': {
clipboard.writeSync(`sf ${command} `);
this.log(ux.colorize('green', 'Command copied to clipboard!'));
break;
}
case 'doctor': {
clipboard.writeSync(`sf doctor --command "${command}"`);
this.log(ux.colorize('green', 'Command copied to clipboard!'));
break;
}
case 'npm': {
open(`https://www.npmjs.com/package/${pluginName}/v/${commandVersion}`);
break;
}
case 'source': {
open(sourceUrl);
break;
}
}
const Help = await loadHelpClass(this.config);
const help = new Help(this.config, this.config.pjson.oclif.helpOptions ?? this.config.pjson.helpOptions);
return help.showHelp([toStandardizedId(command, this.config)]);
}
}

@@ -7,19 +7,3 @@ {

"description": "Once you select a command, hit enter and it will show the help for that command.",
"flags": {
"action": {
"char": "a",
"name": "action",
"summary": "Action to take on the selected command",
"hasDynamicHelp": false,
"multiple": false,
"options": [
"help",
"copy",
"doctor",
"source",
"npm"
],
"type": "option"
}
},
"flags": {},
"hasDynamicHelp": false,

@@ -31,3 +15,3 @@ "hiddenAliases": [],

"pluginType": "core",
"strict": false,
"strict": true,
"summary": "Search for a command.",

@@ -47,3 +31,3 @@ "enableJsonFlag": false,

},
"version": "1.2.12-dev.0"
"version": "1.2.12"
}

16

package.json
{
"name": "@oclif/plugin-search",
"version": "1.2.12-dev.0",
"version": "1.2.12",
"description": "A command for searching commands",

@@ -8,9 +8,5 @@ "author": "Salesforce",

"dependencies": {
"@inquirer/search": "^2.0.1",
"@oclif/core": "^4",
"ansis": "^3.3.2",
"clipboardy": "^4.0.0",
"fuzzysort": "^3.0.2",
"got": "^13.0.0",
"open": "^10.1.0"
"ansi-escapes": "^7.0.0",
"inquirer-autocomplete-standalone": "^0.8.1"
},

@@ -24,3 +20,3 @@ "devDependencies": {

"@types/inquirer": "^8.2.10",
"@types/mocha": "^10.0.8",
"@types/mocha": "^10.0.9",
"@types/node": "^18",

@@ -31,3 +27,3 @@ "chai": "^4",

"eslint-config-oclif": "^5.2.1",
"eslint-config-oclif-typescript": "^3.1.11",
"eslint-config-oclif-typescript": "^3.1.12",
"eslint-config-prettier": "^9.1.0",

@@ -37,3 +33,3 @@ "husky": "^9.1.6",

"mocha": "^10.7.3",
"oclif": "^4.15.3",
"oclif": "^4.15.6",
"prettier": "^3.3.3",

@@ -40,0 +36,0 @@ "shx": "^0.3.3",

@@ -25,3 +25,3 @@ # @oclif/plugin-search

$ @oclif/plugin-search (--version)
@oclif/plugin-search/1.2.12-dev.0 linux-x64 node-v20.17.0
@oclif/plugin-search/1.2.12 linux-x64 node-v20.17.0
$ @oclif/plugin-search --help [COMMAND]

@@ -45,8 +45,4 @@ USAGE

USAGE
$ @oclif/plugin-search search [-a help|copy|doctor|source|npm]
$ @oclif/plugin-search search
FLAGS
-a, --action=<option> Action to take on the selected command
<options: help|copy|doctor|source|npm>
DESCRIPTION

@@ -58,3 +54,3 @@ Search for a command.

_See code: [src/commands/search.ts](https://github.com/oclif/plugin-search/blob/v1.2.12-dev.0/src/commands/search.ts)_
_See code: [src/commands/search.ts](https://github.com/oclif/plugin-search/blob/v1.2.12/src/commands/search.ts)_
<!-- commandsstop -->

@@ -61,0 +57,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc