@oclif/plugin-search 1.2.12-dev.0 → 1.2.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -7
- package/dist/commands/search.d.ts +0 -4
- package/dist/commands/search.js +20 -164
- package/oclif.manifest.json +3 -19
- package/package.json +6 -10
package/README.md
CHANGED
|
@@ -22,7 +22,7 @@ $ npm install -g @oclif/plugin-search
|
|
|
22
22
|
$ @oclif/plugin-search COMMAND
|
|
23
23
|
running command...
|
|
24
24
|
$ @oclif/plugin-search (--version)
|
|
25
|
-
@oclif/plugin-search/1.2.12
|
|
25
|
+
@oclif/plugin-search/1.2.12 linux-x64 node-v20.17.0
|
|
26
26
|
$ @oclif/plugin-search --help [COMMAND]
|
|
27
27
|
USAGE
|
|
28
28
|
$ @oclif/plugin-search COMMAND
|
|
@@ -41,11 +41,7 @@ Search for a command.
|
|
|
41
41
|
|
|
42
42
|
```
|
|
43
43
|
USAGE
|
|
44
|
-
$ @oclif/plugin-search search
|
|
45
|
-
|
|
46
|
-
FLAGS
|
|
47
|
-
-a, --action=<option> Action to take on the selected command
|
|
48
|
-
<options: help|copy|doctor|source|npm>
|
|
44
|
+
$ @oclif/plugin-search search
|
|
49
45
|
|
|
50
46
|
DESCRIPTION
|
|
51
47
|
Search for a command.
|
|
@@ -53,7 +49,7 @@ DESCRIPTION
|
|
|
53
49
|
Once you select a command, hit enter and it will show the help for that command.
|
|
54
50
|
```
|
|
55
51
|
|
|
56
|
-
_See code: [src/commands/search.ts](https://github.com/oclif/plugin-search/blob/v1.2.12
|
|
52
|
+
_See code: [src/commands/search.ts](https://github.com/oclif/plugin-search/blob/v1.2.12/src/commands/search.ts)_
|
|
57
53
|
<!-- commandsstop -->
|
|
58
54
|
|
|
59
55
|
# Contributing
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
import { Command } from '@oclif/core';
|
|
2
2
|
export default class Search extends Command {
|
|
3
3
|
static description: string;
|
|
4
|
-
static readonly flags: {
|
|
5
|
-
action: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
6
|
-
};
|
|
7
|
-
static readonly strict = false;
|
|
8
4
|
static summary: string;
|
|
9
5
|
run(): Promise<unknown>;
|
|
10
6
|
}
|
package/dist/commands/search.js
CHANGED
|
@@ -4,36 +4,15 @@
|
|
|
4
4
|
* Licensed under the BSD 3-Clause license.
|
|
5
5
|
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
6
6
|
*/
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import
|
|
10
|
-
import clipboard from 'clipboardy';
|
|
11
|
-
import fuzzysort from 'fuzzysort';
|
|
12
|
-
import { got } from 'got';
|
|
7
|
+
import { Command, loadHelpClass, toConfiguredId, toStandardizedId, ux } from '@oclif/core';
|
|
8
|
+
import ansiEscapes from 'ansi-escapes';
|
|
9
|
+
import autocomplete from 'inquirer-autocomplete-standalone';
|
|
13
10
|
import readline from 'node:readline';
|
|
14
|
-
import open from 'open';
|
|
15
11
|
export default class Search extends Command {
|
|
16
12
|
static description = 'Once you select a command, hit enter and it will show the help for that command.';
|
|
17
|
-
static flags = {
|
|
18
|
-
action: Flags.string({
|
|
19
|
-
char: 'a',
|
|
20
|
-
options: ['help', 'copy', 'doctor', 'source', 'npm'],
|
|
21
|
-
summary: 'Action to take on the selected command',
|
|
22
|
-
}),
|
|
23
|
-
};
|
|
24
|
-
static strict = false;
|
|
25
13
|
static summary = 'Search for a command.';
|
|
26
14
|
async run() {
|
|
27
|
-
|
|
28
|
-
// Join the args together into a string so you can pass something like 'dep sta' to fuzzy search
|
|
29
|
-
const args = argv.join(' ');
|
|
30
|
-
const theme = {
|
|
31
|
-
helpMode: 'never',
|
|
32
|
-
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`),
|
|
33
|
-
style: {
|
|
34
|
-
description: (desc) => `\n${ux.colorize('cyan', desc)}`, // Give the description a little extra padding
|
|
35
|
-
},
|
|
36
|
-
};
|
|
15
|
+
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`));
|
|
37
16
|
const commandChoices = this.config.commands
|
|
38
17
|
.filter((c) => !c.hidden && !c.aliases.includes(c.id))
|
|
39
18
|
.sort((a, b) => a.id.localeCompare(b.id))
|
|
@@ -46,37 +25,26 @@ export default class Search extends Command {
|
|
|
46
25
|
};
|
|
47
26
|
});
|
|
48
27
|
const pageSize = Math.floor(process.stdout.rows < 20 ? process.stdout.rows / 2 : 10);
|
|
49
|
-
const commandPromise =
|
|
28
|
+
const commandPromise = autocomplete({
|
|
29
|
+
emptyText: 'Nothing found!',
|
|
50
30
|
message: 'Search for a command',
|
|
51
31
|
pageSize,
|
|
52
32
|
async source(input) {
|
|
53
|
-
|
|
54
|
-
// - pass an arg
|
|
55
|
-
// - hit down arrow
|
|
56
|
-
// - hit any other character with clear the input
|
|
57
|
-
// - hitting delete will clear input, but keep the fuzzy results
|
|
58
|
-
if (input === undefined && args)
|
|
59
|
-
input = args;
|
|
60
|
-
const results = fuzzysort.go(input, commandChoices, { all: true, key: 'name' });
|
|
61
|
-
return results.map((r) => ({
|
|
62
|
-
description: r.obj.description,
|
|
63
|
-
name: r.highlight(bold.open, bold.close),
|
|
64
|
-
value: r.obj.value,
|
|
65
|
-
}));
|
|
33
|
+
return input ? commandChoices.filter((c) => c.name.includes(input)) : commandChoices;
|
|
66
34
|
},
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
35
|
+
});
|
|
36
|
+
function cancel() {
|
|
37
|
+
commandPromise.cancel();
|
|
38
|
+
// erase the list of commands
|
|
39
|
+
process.stdout.write(ansiEscapes.eraseLines(pageSize + 3));
|
|
40
|
+
}
|
|
70
41
|
readline.emitKeypressEvents(process.stdin);
|
|
71
42
|
process.stdin.setRawMode(true);
|
|
72
|
-
// If args were passed in, we "replay" the key presses to populate the search
|
|
73
|
-
if (args)
|
|
74
|
-
process.stdin.emit('data', args);
|
|
75
|
-
// Allow the user to exit the search with the escape key or with ctrl+c
|
|
76
43
|
process.stdin.on('keypress', (_, key) => {
|
|
77
|
-
if (
|
|
78
|
-
|
|
79
|
-
|
|
44
|
+
if (key.name === 'escape')
|
|
45
|
+
cancel();
|
|
46
|
+
if (key.name === 'c' && key.ctrl)
|
|
47
|
+
cancel();
|
|
80
48
|
});
|
|
81
49
|
const command = await commandPromise
|
|
82
50
|
.catch((error) => {
|
|
@@ -87,120 +55,8 @@ export default class Search extends Command {
|
|
|
87
55
|
.then((result) => result);
|
|
88
56
|
if (!command)
|
|
89
57
|
return;
|
|
90
|
-
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
const commandConfig = this.config.findCommand(commandId);
|
|
94
|
-
const pluginName = commandConfig?.pluginName;
|
|
95
|
-
if (!pluginName)
|
|
96
|
-
this.error('Key `pluginName` not found in the config for this command.');
|
|
97
|
-
const commandPjson = this.config.plugins.get(pluginName)?.pjson;
|
|
98
|
-
const homepage = commandPjson?.homepage;
|
|
99
|
-
// TODO: add a check for homepage
|
|
100
|
-
const commandVersion = commandPjson?.version;
|
|
101
|
-
return { commandConfig, commandId, commandPjson, commandVersion, homepage, pluginName };
|
|
102
|
-
};
|
|
103
|
-
const getSourceUrl = async (homepage, commandId, commandVersion) => {
|
|
104
|
-
if (!homepage)
|
|
105
|
-
return;
|
|
106
|
-
const commandToPath = `${commandId.replaceAll(':', '/')}.ts`;
|
|
107
|
-
// TODO: do we need to take into account directory level index.ts command files?
|
|
108
|
-
// TODO: talk to Mike about dynamically built command paths
|
|
109
|
-
const urls = [
|
|
110
|
-
`/blob/${commandVersion}/src/commands/${commandToPath}`,
|
|
111
|
-
`/blob/v${commandVersion}/src/commands/${commandToPath}`,
|
|
112
|
-
`/blob/-/src/commands/${commandToPath}`,
|
|
113
|
-
`/blob/main/src/commands/${commandToPath}`,
|
|
114
|
-
`/blob/master/src/commands/${commandToPath}`,
|
|
115
|
-
];
|
|
116
|
-
const responses = await Promise.all(urls.map((url) => got(`${homepage}${url}`, { throwHttpErrors: false })));
|
|
117
|
-
return responses.find((r) => r.statusCode === 200)?.url ?? undefined;
|
|
118
|
-
};
|
|
119
|
-
const { commandId, commandVersion, homepage, pluginName } = getPluginDetails(command);
|
|
120
|
-
const sourceUrl = await getSourceUrl(homepage, commandId, commandVersion);
|
|
121
|
-
let actionPrompt;
|
|
122
|
-
if (!flags.action) {
|
|
123
|
-
const actions = [
|
|
124
|
-
{
|
|
125
|
-
description: 'Show the help text for this command',
|
|
126
|
-
name: 'Show help',
|
|
127
|
-
value: 'help',
|
|
128
|
-
},
|
|
129
|
-
{
|
|
130
|
-
description: 'Copy the command to your clipboard',
|
|
131
|
-
name: 'Copy command',
|
|
132
|
-
value: 'copy',
|
|
133
|
-
},
|
|
134
|
-
{
|
|
135
|
-
description: 'Copy the command to your clipboard for use with the doctor command',
|
|
136
|
-
name: 'Copy command for doctor',
|
|
137
|
-
value: 'doctor',
|
|
138
|
-
},
|
|
139
|
-
{
|
|
140
|
-
description: 'Open the source code for this command on GitHub',
|
|
141
|
-
disabled: sourceUrl ? false : '(Unable to resolve source code URL)',
|
|
142
|
-
name: 'Go to source code',
|
|
143
|
-
value: 'source',
|
|
144
|
-
},
|
|
145
|
-
{
|
|
146
|
-
description: 'View the npm details for this package',
|
|
147
|
-
name: 'View package on npm',
|
|
148
|
-
value: 'npm',
|
|
149
|
-
},
|
|
150
|
-
];
|
|
151
|
-
const actionPromise = search({
|
|
152
|
-
message: `Select an action for: ${ux.colorize('dim', '$ sf ' + command)}`,
|
|
153
|
-
pageSize,
|
|
154
|
-
async source(input) {
|
|
155
|
-
const results = fuzzysort.go(input, actions, { all: true, key: 'name' });
|
|
156
|
-
return results.map((r) => ({
|
|
157
|
-
description: r.obj.description,
|
|
158
|
-
disabled: r.obj.disabled,
|
|
159
|
-
name: r.highlight(bold.open, bold.close),
|
|
160
|
-
value: r.obj.value,
|
|
161
|
-
}));
|
|
162
|
-
},
|
|
163
|
-
// @ts-expect-error Not sure why this is complaining about the helpMode type
|
|
164
|
-
theme,
|
|
165
|
-
}, { clearPromptOnDone: true });
|
|
166
|
-
// Allow the user to exit the search with the escape key or with ctrl+c
|
|
167
|
-
process.stdin.on('keypress', (_, key) => {
|
|
168
|
-
if ((key.name === 'escape' || (key.name === 'c' && key.ctrl)) && actionPromise) {
|
|
169
|
-
actionPromise.cancel();
|
|
170
|
-
}
|
|
171
|
-
});
|
|
172
|
-
actionPrompt = await actionPromise
|
|
173
|
-
.catch((error) => {
|
|
174
|
-
if (error.message === 'Prompt was canceled')
|
|
175
|
-
return;
|
|
176
|
-
throw error;
|
|
177
|
-
})
|
|
178
|
-
.then((result) => result);
|
|
179
|
-
}
|
|
180
|
-
switch (flags.action ?? actionPrompt) {
|
|
181
|
-
case 'help': {
|
|
182
|
-
const Help = await loadHelpClass(this.config);
|
|
183
|
-
const help = new Help(this.config, this.config.pjson.oclif.helpOptions ?? this.config.pjson.helpOptions);
|
|
184
|
-
return help.showHelp([toStandardizedId(command, this.config)]);
|
|
185
|
-
}
|
|
186
|
-
case 'copy': {
|
|
187
|
-
clipboard.writeSync(`sf ${command} `);
|
|
188
|
-
this.log(ux.colorize('green', 'Command copied to clipboard!'));
|
|
189
|
-
break;
|
|
190
|
-
}
|
|
191
|
-
case 'doctor': {
|
|
192
|
-
clipboard.writeSync(`sf doctor --command "${command}"`);
|
|
193
|
-
this.log(ux.colorize('green', 'Command copied to clipboard!'));
|
|
194
|
-
break;
|
|
195
|
-
}
|
|
196
|
-
case 'npm': {
|
|
197
|
-
open(`https://www.npmjs.com/package/${pluginName}/v/${commandVersion}`);
|
|
198
|
-
break;
|
|
199
|
-
}
|
|
200
|
-
case 'source': {
|
|
201
|
-
open(sourceUrl);
|
|
202
|
-
break;
|
|
203
|
-
}
|
|
204
|
-
}
|
|
58
|
+
const Help = await loadHelpClass(this.config);
|
|
59
|
+
const help = new Help(this.config, this.config.pjson.oclif.helpOptions ?? this.config.pjson.helpOptions);
|
|
60
|
+
return help.showHelp([toStandardizedId(command, this.config)]);
|
|
205
61
|
}
|
|
206
62
|
}
|
package/oclif.manifest.json
CHANGED
|
@@ -4,30 +4,14 @@
|
|
|
4
4
|
"aliases": [],
|
|
5
5
|
"args": {},
|
|
6
6
|
"description": "Once you select a command, hit enter and it will show the help for that command.",
|
|
7
|
-
"flags": {
|
|
8
|
-
"action": {
|
|
9
|
-
"char": "a",
|
|
10
|
-
"name": "action",
|
|
11
|
-
"summary": "Action to take on the selected command",
|
|
12
|
-
"hasDynamicHelp": false,
|
|
13
|
-
"multiple": false,
|
|
14
|
-
"options": [
|
|
15
|
-
"help",
|
|
16
|
-
"copy",
|
|
17
|
-
"doctor",
|
|
18
|
-
"source",
|
|
19
|
-
"npm"
|
|
20
|
-
],
|
|
21
|
-
"type": "option"
|
|
22
|
-
}
|
|
23
|
-
},
|
|
7
|
+
"flags": {},
|
|
24
8
|
"hasDynamicHelp": false,
|
|
25
9
|
"hiddenAliases": [],
|
|
26
10
|
"id": "search",
|
|
27
11
|
"pluginAlias": "@oclif/plugin-search",
|
|
28
12
|
"pluginName": "@oclif/plugin-search",
|
|
29
13
|
"pluginType": "core",
|
|
30
|
-
"strict":
|
|
14
|
+
"strict": true,
|
|
31
15
|
"summary": "Search for a command.",
|
|
32
16
|
"enableJsonFlag": false,
|
|
33
17
|
"isESM": true,
|
|
@@ -42,5 +26,5 @@
|
|
|
42
26
|
]
|
|
43
27
|
}
|
|
44
28
|
},
|
|
45
|
-
"version": "1.2.12
|
|
29
|
+
"version": "1.2.12"
|
|
46
30
|
}
|
package/package.json
CHANGED
|
@@ -1,17 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oclif/plugin-search",
|
|
3
|
-
"version": "1.2.12
|
|
3
|
+
"version": "1.2.12",
|
|
4
4
|
"description": "A command for searching commands",
|
|
5
5
|
"author": "Salesforce",
|
|
6
6
|
"bugs": "https://github.com/oclif/plugin-search/issues",
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"@inquirer/search": "^2.0.1",
|
|
9
8
|
"@oclif/core": "^4",
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
"fuzzysort": "^3.0.2",
|
|
13
|
-
"got": "^13.0.0",
|
|
14
|
-
"open": "^10.1.0"
|
|
9
|
+
"ansi-escapes": "^7.0.0",
|
|
10
|
+
"inquirer-autocomplete-standalone": "^0.8.1"
|
|
15
11
|
},
|
|
16
12
|
"devDependencies": {
|
|
17
13
|
"@commitlint/config-conventional": "^19",
|
|
@@ -20,18 +16,18 @@
|
|
|
20
16
|
"@oclif/prettier-config": "^0.2.1",
|
|
21
17
|
"@types/chai": "^4",
|
|
22
18
|
"@types/inquirer": "^8.2.10",
|
|
23
|
-
"@types/mocha": "^10.0.
|
|
19
|
+
"@types/mocha": "^10.0.9",
|
|
24
20
|
"@types/node": "^18",
|
|
25
21
|
"chai": "^4",
|
|
26
22
|
"commitlint": "^19",
|
|
27
23
|
"eslint": "^8.57.1",
|
|
28
24
|
"eslint-config-oclif": "^5.2.1",
|
|
29
|
-
"eslint-config-oclif-typescript": "^3.1.
|
|
25
|
+
"eslint-config-oclif-typescript": "^3.1.12",
|
|
30
26
|
"eslint-config-prettier": "^9.1.0",
|
|
31
27
|
"husky": "^9.1.6",
|
|
32
28
|
"lint-staged": "^15",
|
|
33
29
|
"mocha": "^10.7.3",
|
|
34
|
-
"oclif": "^4.15.
|
|
30
|
+
"oclif": "^4.15.6",
|
|
35
31
|
"prettier": "^3.3.3",
|
|
36
32
|
"shx": "^0.3.3",
|
|
37
33
|
"ts-node": "^10.9.2",
|