nx 23.0.0-beta.16 → 23.0.0-beta.18
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/dist/bin/init-local.js +11 -20
- package/dist/bin/nx.js +25 -2
- package/dist/src/command-line/add/completion.d.ts +1 -0
- package/dist/src/command-line/add/completion.js +15 -0
- package/dist/src/command-line/affected/completion.d.ts +1 -0
- package/dist/src/command-line/affected/completion.js +15 -0
- package/dist/src/command-line/completion/argv-layout.d.ts +6 -0
- package/dist/src/command-line/completion/argv-layout.js +19 -0
- package/dist/src/command-line/completion/command-completions.d.ts +19 -0
- package/dist/src/command-line/completion/command-completions.js +120 -0
- package/dist/src/command-line/completion/command-handlers.d.ts +30 -0
- package/dist/src/command-line/completion/command-handlers.js +69 -0
- package/dist/src/command-line/completion/command-object.d.ts +10 -0
- package/dist/src/command-line/completion/command-object.js +95 -0
- package/dist/src/command-line/completion/completion-providers.d.ts +21 -0
- package/dist/src/command-line/completion/completion-providers.js +194 -0
- package/dist/src/command-line/completion/infix-targets.d.ts +1 -0
- package/dist/src/command-line/completion/infix-targets.js +48 -0
- package/dist/src/command-line/completion/metadata.d.ts +22 -0
- package/dist/src/command-line/completion/metadata.js +71 -0
- package/dist/src/command-line/completion/registrations.d.ts +9 -0
- package/dist/src/command-line/completion/registrations.js +16 -0
- package/dist/src/command-line/completion/scripts/bash.sh +51 -0
- package/dist/src/command-line/completion/scripts/fish.fish +47 -0
- package/dist/src/command-line/completion/scripts/powershell.ps1 +52 -0
- package/dist/src/command-line/completion/scripts/zsh.zsh +69 -0
- package/dist/src/command-line/completion/scripts.d.ts +18 -0
- package/dist/src/command-line/completion/scripts.js +140 -0
- package/dist/src/command-line/completion/trigger.d.ts +3 -0
- package/dist/src/command-line/completion/trigger.js +21 -0
- package/dist/src/command-line/completion/value-completions.d.ts +3 -0
- package/dist/src/command-line/completion/value-completions.js +21 -0
- package/dist/src/command-line/format/format.js +15 -5
- package/dist/src/command-line/generate/completion.d.ts +1 -0
- package/dist/src/command-line/generate/completion.js +9 -0
- package/dist/src/command-line/graph/completion.d.ts +1 -0
- package/dist/src/command-line/graph/completion.js +13 -0
- package/dist/src/command-line/migrate/migrate.js +2 -1
- package/dist/src/command-line/migrate/prompt-files.js +2 -2
- package/dist/src/command-line/nx-commands.js +9 -0
- package/dist/src/command-line/report/report.js +2 -2
- package/dist/src/command-line/run/completion.d.ts +1 -0
- package/dist/src/command-line/run/completion.js +7 -0
- package/dist/src/command-line/run-many/completion.d.ts +1 -0
- package/dist/src/command-line/run-many/completion.js +13 -0
- package/dist/src/command-line/show/completion.d.ts +1 -0
- package/dist/src/command-line/show/completion.js +27 -0
- package/dist/src/command-line/watch/completion.d.ts +1 -0
- package/dist/src/command-line/watch/completion.js +10 -0
- package/dist/src/config/schema-utils.js +2 -1
- package/dist/src/core/graph/main.js +1 -1
- package/dist/src/migrations/update-17-0-0/move-cache-directory.md +31 -0
- package/dist/src/migrations/update-20-0-0/move-use-daemon-process.md +27 -0
- package/dist/src/migrations/update-20-0-1/use-legacy-cache.md +24 -0
- package/dist/src/migrations/update-21-0-0/release-changelog-config-changes.md +49 -0
- package/dist/src/migrations/update-21-0-0/release-version-config-changes.md +54 -0
- package/dist/src/migrations/update-21-0-0/remove-custom-tasks-runner.md +28 -0
- package/dist/src/migrations/update-21-0-0/remove-legacy-cache.md +22 -0
- package/dist/src/migrations/update-22-2-0/add-self-healing-to-gitignore.md +11 -0
- package/dist/src/migrations/update-23-0-0/convert-target-defaults-to-array.md +66 -0
- package/dist/src/native/nx.wasm32-wasi.debug.wasm +0 -0
- package/dist/src/native/nx.wasm32-wasi.wasm +0 -0
- package/dist/src/plugins/js/utils/register.d.ts +4 -28
- package/dist/src/plugins/js/utils/register.js +10 -19
- package/dist/src/plugins/js/utils/typescript.d.ts +7 -0
- package/dist/src/plugins/js/utils/typescript.js +39 -0
- package/dist/src/project-graph/plugins/resolve-plugin.d.ts +7 -4
- package/dist/src/project-graph/plugins/resolve-plugin.js +152 -33
- package/dist/src/tasks-runner/tasks-schedule.js +3 -3
- package/dist/src/utils/fileutils.d.ts +0 -8
- package/dist/src/utils/fileutils.js +0 -40
- package/dist/src/utils/nx-package-group.d.ts +8 -0
- package/dist/src/utils/nx-package-group.js +15 -0
- package/dist/src/utils/plugins/local-plugins.d.ts +18 -0
- package/dist/src/utils/plugins/local-plugins.js +30 -0
- package/dist/src/utils/tar.d.ts +8 -0
- package/dist/src/utils/tar.js +44 -0
- package/package.json +11 -11
- package/dist/src/plugins/js/project-graph/build-dependencies/strip-source-code.d.ts +0 -7
- package/dist/src/plugins/js/project-graph/build-dependencies/strip-source-code.js +0 -155
- package/dist/src/plugins/js/project-graph/build-dependencies/typescript-import-locator.d.ts +0 -16
- package/dist/src/plugins/js/project-graph/build-dependencies/typescript-import-locator.js +0 -121
package/dist/bin/init-local.js
CHANGED
|
@@ -30,13 +30,18 @@ async function initLocal(workspace) {
|
|
|
30
30
|
handleAngularCLIFallbacks(workspace);
|
|
31
31
|
return;
|
|
32
32
|
}
|
|
33
|
-
//
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
// Skip per-TAB shell completion calls — those must not spawn the daemon.
|
|
34
|
+
if (!process.env.NX_COMPLETE) {
|
|
35
|
+
try {
|
|
36
|
+
await ensureNxConsoleInstalledViaDaemon();
|
|
37
|
+
}
|
|
38
|
+
catch { }
|
|
36
39
|
}
|
|
37
|
-
catch { }
|
|
38
40
|
const command = process.argv[2];
|
|
39
|
-
if (command === '
|
|
41
|
+
if (command === 'completion' ||
|
|
42
|
+
command === 'run' ||
|
|
43
|
+
command === 'g' ||
|
|
44
|
+
command === 'generate') {
|
|
40
45
|
nx_commands_1.commandsObject.parse(process.argv.slice(2));
|
|
41
46
|
}
|
|
42
47
|
else if (isKnownCommand(command)) {
|
|
@@ -110,14 +115,7 @@ function isKnownCommand(command) {
|
|
|
110
115
|
}
|
|
111
116
|
function shouldDelegateToAngularCLI() {
|
|
112
117
|
const command = process.argv[2];
|
|
113
|
-
const commands = [
|
|
114
|
-
'analytics',
|
|
115
|
-
'cache',
|
|
116
|
-
'completion',
|
|
117
|
-
'config',
|
|
118
|
-
'doc',
|
|
119
|
-
'update',
|
|
120
|
-
];
|
|
118
|
+
const commands = ['analytics', 'cache', 'config', 'doc', 'update'];
|
|
121
119
|
return commands.indexOf(command) > -1;
|
|
122
120
|
}
|
|
123
121
|
async function ensureNxConsoleInstalledViaDaemon() {
|
|
@@ -169,13 +167,6 @@ function handleAngularCLIFallbacks(workspace) {
|
|
|
169
167
|
console.log(`Running "ng update" can still be useful in some dev workflows, so we aren't planning to remove it.`);
|
|
170
168
|
console.log(`If you need to use it, run "FORCE_NG_UPDATE=true ng update".`);
|
|
171
169
|
}
|
|
172
|
-
else if (process.argv[2] === 'completion') {
|
|
173
|
-
if (!process.argv[3]) {
|
|
174
|
-
console.log(`"ng completion" is not natively supported by Nx.
|
|
175
|
-
Instead, you could try an Nx Editor Plugin for a visual tool to run Nx commands. If you're using VSCode, you can use the Nx Console plugin, or if you're using WebStorm, you could use one of the available community plugins.
|
|
176
|
-
For more information, see https://nx.dev/getting-started/editor-setup`);
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
170
|
else if (process.argv[2] === 'cache') {
|
|
180
171
|
console.log(`"ng cache" is not natively supported by Nx.
|
|
181
172
|
To clear the cache, you can delete the ".angular/cache" directory (or the directory configured by "cli.cache.path" in the "nx.json" file).
|
package/dist/bin/nx.js
CHANGED
|
@@ -29,10 +29,32 @@ require("../src/utils/perf-logging");
|
|
|
29
29
|
const isTsExt = (0, path_1.extname)(__filename).endsWith('.ts');
|
|
30
30
|
const pathToPkgJson = isTsExt ? '../package.json' : '../../package.json';
|
|
31
31
|
async function main() {
|
|
32
|
+
// Tab-completion fast path. Bare env-var read so nothing runs before
|
|
33
|
+
// the try/catch — a throw here would splice a stack trace into the
|
|
34
|
+
// user's command line.
|
|
35
|
+
if (process.env.NX_COMPLETE) {
|
|
36
|
+
try {
|
|
37
|
+
perf_hooks_1.performance.mark('init-local');
|
|
38
|
+
const { tryValueCompletion } = await import('nx/src/command-line/completion/value-completions');
|
|
39
|
+
if (tryValueCompletion())
|
|
40
|
+
return;
|
|
41
|
+
const { tryCommandSurfaceCompletion } = await import('nx/src/command-line/completion/command-completions');
|
|
42
|
+
tryCommandSurfaceCompletion();
|
|
43
|
+
}
|
|
44
|
+
catch (e) {
|
|
45
|
+
// Swallow: a broken completion must produce no suggestions, not a
|
|
46
|
+
// stack trace. NX_VERBOSE_LOGGING surfaces the cause to stderr.
|
|
47
|
+
if (process.env.NX_VERBOSE_LOGGING) {
|
|
48
|
+
console.error(e);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
32
53
|
if (process.argv[2] !== 'report' &&
|
|
33
54
|
process.argv[2] !== '--version' &&
|
|
34
55
|
process.argv[2] !== '--help' &&
|
|
35
|
-
process.argv[2] !== 'reset'
|
|
56
|
+
process.argv[2] !== 'reset' &&
|
|
57
|
+
process.argv[2] !== 'completion') {
|
|
36
58
|
const { assertSupportedPlatform } = await import('../src/native/assert-supported-platform.js');
|
|
37
59
|
assertSupportedPlatform();
|
|
38
60
|
}
|
|
@@ -55,6 +77,7 @@ async function main() {
|
|
|
55
77
|
process.argv[2] === 'init' ||
|
|
56
78
|
process.argv[2] === 'configure-ai-agents' ||
|
|
57
79
|
process.argv[2] === 'mcp' ||
|
|
80
|
+
process.argv[2] === 'completion' ||
|
|
58
81
|
(process.argv[2] === 'graph' && !workspace)) {
|
|
59
82
|
process.env.NX_DAEMON = 'false';
|
|
60
83
|
(await import('nx/src/command-line/nx-commands')).commandsObject.argv;
|
|
@@ -213,7 +236,7 @@ function handleMissingLocalInstallation(detectedWorkspaceRoot) {
|
|
|
213
236
|
* Warns if out of date by 1 major version or more.
|
|
214
237
|
*/
|
|
215
238
|
function warnIfUsingOutdatedGlobalInstall(globalNxVersion, localNxVersion) {
|
|
216
|
-
//
|
|
239
|
+
// Skip when Nx is recursively invoking itself.
|
|
217
240
|
if (process.env.NX_CLI_SET) {
|
|
218
241
|
return;
|
|
219
242
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const metadata_1 = require("../completion/metadata");
|
|
4
|
+
const nx_package_group_1 = require("../../utils/nx-package-group");
|
|
5
|
+
// Same list `nx report` uses. Filter to first-party plugins and sort.
|
|
6
|
+
const FIRST_PARTY_PLUGINS = (0, nx_package_group_1.readNxPackageGroup)()
|
|
7
|
+
.filter((p) => p.startsWith('@nx/'))
|
|
8
|
+
.sort();
|
|
9
|
+
(0, metadata_1.registerCompletion)('add', {
|
|
10
|
+
positionals: [
|
|
11
|
+
{
|
|
12
|
+
complete: (current) => FIRST_PARTY_PLUGINS.filter((p) => p.startsWith(current)),
|
|
13
|
+
},
|
|
14
|
+
],
|
|
15
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const metadata_1 = require("../completion/metadata");
|
|
4
|
+
const completion_providers_1 = require("../completion/completion-providers");
|
|
5
|
+
// Aliases are written out; the fast path runs before yargs can resolve them.
|
|
6
|
+
(0, metadata_1.registerCompletion)('affected', {
|
|
7
|
+
flags: {
|
|
8
|
+
projects: completion_providers_1.getProjectNameCompletions,
|
|
9
|
+
p: completion_providers_1.getProjectNameCompletions,
|
|
10
|
+
exclude: completion_providers_1.getProjectNameCompletions,
|
|
11
|
+
targets: completion_providers_1.getTargetNameCompletions,
|
|
12
|
+
target: completion_providers_1.getTargetNameCompletions,
|
|
13
|
+
t: completion_providers_1.getTargetNameCompletions,
|
|
14
|
+
},
|
|
15
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Wrappers must invoke nx with argv: [node, nx-bin, ...tokens, currentPartial].
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.parseCompletionArgs = parseCompletionArgs;
|
|
5
|
+
function parseCompletionArgs(argv = process.argv) {
|
|
6
|
+
const tail = argv.slice(2);
|
|
7
|
+
// Wrappers usually prepend the literal 'nx' (from COMP_WORDS /
|
|
8
|
+
// commandline -cop / etc.). They sometimes don't — most notably the
|
|
9
|
+
// `.nx/installation` wrapper invokes the real bin directly without the
|
|
10
|
+
// 'nx' token, and manual invocations like `NX_COMPLETE=fish nx show
|
|
11
|
+
// target in` for dev testing skip it too. Strip when present, otherwise
|
|
12
|
+
// take the args as-is.
|
|
13
|
+
const tokens = tail[0] === 'nx' ? tail.slice(1) : tail;
|
|
14
|
+
if (tokens.length === 0)
|
|
15
|
+
return null;
|
|
16
|
+
const current = tokens[tokens.length - 1] ?? '';
|
|
17
|
+
const previousToken = tokens.length >= 2 ? tokens[tokens.length - 2] : '';
|
|
18
|
+
return { tokens, current, previousToken };
|
|
19
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/** Slow-path entry point. Returns true if anything was emitted. */
|
|
2
|
+
export declare function tryCommandSurfaceCompletion(argv?: readonly string[]): boolean;
|
|
3
|
+
/** Top-level command names. Unions yargs handlers with the completion
|
|
4
|
+
* registry's single-token paths (infix targets). */
|
|
5
|
+
export declare function getTopLevelCommands(current: string, withDesc: boolean): string[] | null;
|
|
6
|
+
/**
|
|
7
|
+
* Enumerates subcommands + options of a matched top-level command. Returns
|
|
8
|
+
* null when no top-level command name is matched in `args`.
|
|
9
|
+
*/
|
|
10
|
+
export declare function getCommandCompletions(current: string, args: string[]): string[] | null;
|
|
11
|
+
/** value\tdescription separator. TAB because completion values can contain
|
|
12
|
+
* colons (`my-app:build`); descriptions get TABs collapsed. */
|
|
13
|
+
export declare const DESC_SEPARATOR = "\t";
|
|
14
|
+
/** Strip the y18n marker yargs prepends to its built-in --help / --version
|
|
15
|
+
* descriptions, and collapse stray TABs so they can't forge the
|
|
16
|
+
* value/description separator. */
|
|
17
|
+
export declare function formatDescription(raw: string | undefined): string;
|
|
18
|
+
/** zsh (compadd -d) and fish (complete -a) parse `value\tdescription`. */
|
|
19
|
+
export declare function shellRendersDescriptions(): boolean;
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Slow-path completion: command/subcommand/flag names. Runs after
|
|
3
|
+
// tryValueCompletion has nothing to offer.
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.DESC_SEPARATOR = void 0;
|
|
6
|
+
exports.tryCommandSurfaceCompletion = tryCommandSurfaceCompletion;
|
|
7
|
+
exports.getTopLevelCommands = getTopLevelCommands;
|
|
8
|
+
exports.getCommandCompletions = getCommandCompletions;
|
|
9
|
+
exports.formatDescription = formatDescription;
|
|
10
|
+
exports.shellRendersDescriptions = shellRendersDescriptions;
|
|
11
|
+
const trigger_1 = require("./trigger");
|
|
12
|
+
const argv_layout_1 = require("./argv-layout");
|
|
13
|
+
const metadata_1 = require("./metadata");
|
|
14
|
+
const command_handlers_1 = require("./command-handlers");
|
|
15
|
+
/** Slow-path entry point. Returns true if anything was emitted. */
|
|
16
|
+
function tryCommandSurfaceCompletion(argv = process.argv) {
|
|
17
|
+
const parsed = (0, argv_layout_1.parseCompletionArgs)(argv);
|
|
18
|
+
if (parsed === null)
|
|
19
|
+
return false;
|
|
20
|
+
const matched = getCommandCompletions(parsed.current, parsed.tokens);
|
|
21
|
+
const completions = matched !== null
|
|
22
|
+
? matched
|
|
23
|
+
: getTopLevelCommands(parsed.current, shellRendersDescriptions());
|
|
24
|
+
if (completions === null || completions.length === 0)
|
|
25
|
+
return false;
|
|
26
|
+
for (const line of completions) {
|
|
27
|
+
console.log(line);
|
|
28
|
+
}
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
/** Top-level command names. Unions yargs handlers with the completion
|
|
32
|
+
* registry's single-token paths (infix targets). */
|
|
33
|
+
function getTopLevelCommands(current, withDesc) {
|
|
34
|
+
const handlers = (0, command_handlers_1.getNxCommandHandlers)();
|
|
35
|
+
const seen = new Set();
|
|
36
|
+
const completions = [];
|
|
37
|
+
for (const name of Object.keys(handlers)) {
|
|
38
|
+
if (name === '$0' || name.startsWith('_'))
|
|
39
|
+
continue;
|
|
40
|
+
if (current && !name.startsWith(current))
|
|
41
|
+
continue;
|
|
42
|
+
const handler = handlers[name];
|
|
43
|
+
if (handler?.description === false)
|
|
44
|
+
continue; // hidden
|
|
45
|
+
seen.add(name);
|
|
46
|
+
const desc = withDesc ? formatDescription(handler?.description) : '';
|
|
47
|
+
completions.push(desc ? `${name}${exports.DESC_SEPARATOR}${desc}` : name);
|
|
48
|
+
}
|
|
49
|
+
// Infix targets + any other top-level completion-only paths.
|
|
50
|
+
for (const name of (0, metadata_1.getRegisteredTopLevelPaths)()) {
|
|
51
|
+
if (seen.has(name))
|
|
52
|
+
continue;
|
|
53
|
+
if (current && !name.startsWith(current))
|
|
54
|
+
continue;
|
|
55
|
+
seen.add(name);
|
|
56
|
+
completions.push(name);
|
|
57
|
+
}
|
|
58
|
+
return completions;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Enumerates subcommands + options of a matched top-level command. Returns
|
|
62
|
+
* null when no top-level command name is matched in `args`.
|
|
63
|
+
*/
|
|
64
|
+
function getCommandCompletions(current, args) {
|
|
65
|
+
const handlers = (0, command_handlers_1.getNxCommandHandlers)();
|
|
66
|
+
const cmdName = args.find((a) => handlers[a]);
|
|
67
|
+
if (!cmdName) {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
const handler = handlers[cmdName];
|
|
71
|
+
// Once we recognize a top-level command in `args`, we own the slot —
|
|
72
|
+
// return [] (not null) for the "found a command but can't enumerate its
|
|
73
|
+
// surface" case so the caller doesn't fall back to top-level commands
|
|
74
|
+
// (which would mis-offer e.g. `exec` for `nx g c ex`).
|
|
75
|
+
if (typeof handler.builder !== 'function') {
|
|
76
|
+
return [];
|
|
77
|
+
}
|
|
78
|
+
const intro = (0, command_handlers_1.introspectBuilder)(handler.builder);
|
|
79
|
+
if (!intro)
|
|
80
|
+
return [];
|
|
81
|
+
const completions = [];
|
|
82
|
+
const isFlagPrefix = current.startsWith('-');
|
|
83
|
+
const withDesc = shellRendersDescriptions();
|
|
84
|
+
if (!isFlagPrefix) {
|
|
85
|
+
for (const [name, desc] of intro.subcommands) {
|
|
86
|
+
const formatted = withDesc ? formatDescription(desc) : '';
|
|
87
|
+
completions.push(formatted ? `${name}${exports.DESC_SEPARATOR}${formatted}` : name);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
for (const [name, desc] of intro.options) {
|
|
91
|
+
const formatted = withDesc ? formatDescription(desc) : '';
|
|
92
|
+
completions.push(formatted ? `--${name}${exports.DESC_SEPARATOR}${formatted}` : `--${name}`);
|
|
93
|
+
}
|
|
94
|
+
if (!current) {
|
|
95
|
+
return completions;
|
|
96
|
+
}
|
|
97
|
+
const flagName = current.replace(/^-+/, '');
|
|
98
|
+
return completions.filter((c) => {
|
|
99
|
+
if (isFlagPrefix) {
|
|
100
|
+
return c.startsWith(`--${flagName}`);
|
|
101
|
+
}
|
|
102
|
+
return c.startsWith(current);
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
/** value\tdescription separator. TAB because completion values can contain
|
|
106
|
+
* colons (`my-app:build`); descriptions get TABs collapsed. */
|
|
107
|
+
exports.DESC_SEPARATOR = '\t';
|
|
108
|
+
/** Strip the y18n marker yargs prepends to its built-in --help / --version
|
|
109
|
+
* descriptions, and collapse stray TABs so they can't forge the
|
|
110
|
+
* value/description separator. */
|
|
111
|
+
function formatDescription(raw) {
|
|
112
|
+
if (!raw)
|
|
113
|
+
return '';
|
|
114
|
+
return raw.replace(/^__yargsString__:/, '').replace(/\t/g, ' ');
|
|
115
|
+
}
|
|
116
|
+
/** zsh (compadd -d) and fish (complete -a) parse `value\tdescription`. */
|
|
117
|
+
function shellRendersDescriptions() {
|
|
118
|
+
const shell = (0, trigger_1.getCompletionShell)();
|
|
119
|
+
return shell === 'zsh' || shell === 'fish';
|
|
120
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/** A single entry from yargs' `getCommandHandlers()`. */
|
|
2
|
+
export interface CommandHandler {
|
|
3
|
+
description?: string | false;
|
|
4
|
+
builder?: (yargs: any) => any;
|
|
5
|
+
}
|
|
6
|
+
export type CommandHandlers = Record<string, CommandHandler>;
|
|
7
|
+
/**
|
|
8
|
+
* Reach into the yargs commandsObject to enumerate registered command
|
|
9
|
+
* handlers. Lazy-required: nx-commands pulls in the full command tree
|
|
10
|
+
* and is only needed on the slow path.
|
|
11
|
+
*
|
|
12
|
+
* Yargs only keys handlers by canonical name. We mirror each alias to its
|
|
13
|
+
* canonical handler reference so lookups like `handlers['g']` resolve to
|
|
14
|
+
* the same entry as `handlers['generate']`.
|
|
15
|
+
*/
|
|
16
|
+
export declare function getNxCommandHandlers(): CommandHandlers;
|
|
17
|
+
/** Subcommand name → description, visible-option name → description, and
|
|
18
|
+
* canonical option name → its yargs-declared aliases (e.g. projects → [p]). */
|
|
19
|
+
export interface BuilderIntrospection {
|
|
20
|
+
subcommands: Map<string, string | undefined>;
|
|
21
|
+
options: Map<string, string | undefined>;
|
|
22
|
+
aliases: Map<string, string[]>;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Run a yargs builder against a throwaway instance and return its declared
|
|
26
|
+
* subcommands, visible options, and option-alias groups. Returns null if
|
|
27
|
+
* the builder throws. Does NOT call `.argv` — would trigger parse and the
|
|
28
|
+
* help-printing path we're avoiding.
|
|
29
|
+
*/
|
|
30
|
+
export declare function introspectBuilder(builder: (yargs: any) => any): BuilderIntrospection | null;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getNxCommandHandlers = getNxCommandHandlers;
|
|
4
|
+
exports.introspectBuilder = introspectBuilder;
|
|
5
|
+
/**
|
|
6
|
+
* Reach into the yargs commandsObject to enumerate registered command
|
|
7
|
+
* handlers. Lazy-required: nx-commands pulls in the full command tree
|
|
8
|
+
* and is only needed on the slow path.
|
|
9
|
+
*
|
|
10
|
+
* Yargs only keys handlers by canonical name. We mirror each alias to its
|
|
11
|
+
* canonical handler reference so lookups like `handlers['g']` resolve to
|
|
12
|
+
* the same entry as `handlers['generate']`.
|
|
13
|
+
*/
|
|
14
|
+
function getNxCommandHandlers() {
|
|
15
|
+
const { commandsObject } = require('../nx-commands');
|
|
16
|
+
const internal = commandsObject.getInternalMethods();
|
|
17
|
+
const handlers = { ...internal.getCommandInstance().getCommandHandlers() };
|
|
18
|
+
for (const row of internal.getUsageInstance().getCommands()) {
|
|
19
|
+
// usage.getCommands() rows: [usagePattern, description, isDefault, aliases, deprecated]
|
|
20
|
+
const usagePattern = String(row[0] ?? '');
|
|
21
|
+
const aliases = Array.isArray(row[3]) ? row[3] : [];
|
|
22
|
+
const canonical = usagePattern.split(/\s+/)[0];
|
|
23
|
+
const handler = handlers[canonical];
|
|
24
|
+
if (!handler)
|
|
25
|
+
continue;
|
|
26
|
+
for (const alias of aliases) {
|
|
27
|
+
if (!handlers[alias])
|
|
28
|
+
handlers[alias] = handler;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return handlers;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Run a yargs builder against a throwaway instance and return its declared
|
|
35
|
+
* subcommands, visible options, and option-alias groups. Returns null if
|
|
36
|
+
* the builder throws. Does NOT call `.argv` — would trigger parse and the
|
|
37
|
+
* help-printing path we're avoiding.
|
|
38
|
+
*/
|
|
39
|
+
function introspectBuilder(builder) {
|
|
40
|
+
const yargs = require('yargs');
|
|
41
|
+
const temp = yargs();
|
|
42
|
+
try {
|
|
43
|
+
builder(temp);
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
const usage = temp.getInternalMethods().getUsageInstance();
|
|
49
|
+
const subcommands = new Map();
|
|
50
|
+
for (const [usagePattern, desc] of usage.getCommands()) {
|
|
51
|
+
const name = String(usagePattern).split(/\s+/)[0];
|
|
52
|
+
if (name === '$0')
|
|
53
|
+
continue;
|
|
54
|
+
subcommands.set(name, desc);
|
|
55
|
+
}
|
|
56
|
+
const opts = temp.getOptions();
|
|
57
|
+
const descriptions = usage.getDescriptions();
|
|
58
|
+
const options = new Map();
|
|
59
|
+
for (const k of Object.keys(opts.key ?? {})) {
|
|
60
|
+
if ((opts.hiddenOptions ?? []).includes(k))
|
|
61
|
+
continue;
|
|
62
|
+
options.set(k, descriptions[k]);
|
|
63
|
+
}
|
|
64
|
+
const aliases = new Map();
|
|
65
|
+
for (const [canonical, list] of Object.entries(opts.alias ?? {})) {
|
|
66
|
+
aliases.set(canonical, list);
|
|
67
|
+
}
|
|
68
|
+
return { subcommands, options, aliases };
|
|
69
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { CommandModule } from 'yargs';
|
|
2
|
+
declare const SHELL_CHOICES: readonly ["bash", "zsh", "fish", "powershell"];
|
|
3
|
+
type Shell = (typeof SHELL_CHOICES)[number];
|
|
4
|
+
interface CompletionArgs {
|
|
5
|
+
shell?: Shell;
|
|
6
|
+
force?: boolean;
|
|
7
|
+
stdout?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare const yargsCompletionCommand: CommandModule<{}, CompletionArgs>;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.yargsCompletionCommand = void 0;
|
|
4
|
+
const enquirer_1 = require("enquirer");
|
|
5
|
+
const fs_1 = require("fs");
|
|
6
|
+
const os_1 = require("os");
|
|
7
|
+
const path_1 = require("path");
|
|
8
|
+
const handle_import_1 = require("../../utils/handle-import");
|
|
9
|
+
const SHELL_CHOICES = ['bash', 'zsh', 'fish', 'powershell'];
|
|
10
|
+
exports.yargsCompletionCommand = {
|
|
11
|
+
command: 'completion [shell]',
|
|
12
|
+
describe: 'Install shell completion for bash, zsh, fish, or powershell. Omit the shell to pick interactively.',
|
|
13
|
+
builder: (yargs) => yargs
|
|
14
|
+
.positional('shell', {
|
|
15
|
+
type: 'string',
|
|
16
|
+
choices: SHELL_CHOICES,
|
|
17
|
+
describe: 'Shell to install completion for.',
|
|
18
|
+
})
|
|
19
|
+
.option('force', {
|
|
20
|
+
type: 'boolean',
|
|
21
|
+
default: false,
|
|
22
|
+
describe: 'Install the completion script even if `nx` is not found on PATH.',
|
|
23
|
+
})
|
|
24
|
+
.option('stdout', {
|
|
25
|
+
type: 'boolean',
|
|
26
|
+
default: false,
|
|
27
|
+
describe: 'Print the completion script to stdout instead of writing to the shell rc file.',
|
|
28
|
+
})
|
|
29
|
+
.example('$0 completion bash', 'Install bash completion to ~/.bashrc')
|
|
30
|
+
.example('$0 completion', 'Pick shells interactively and install completion for each')
|
|
31
|
+
.example('$0 completion bash --stdout >> ~/.bash_profile', 'Print to stdout for a custom rc location'),
|
|
32
|
+
handler: async (args) => {
|
|
33
|
+
const scripts = await (0, handle_import_1.handleImport)('./scripts.js', __dirname);
|
|
34
|
+
const shells = args.shell ? [args.shell] : await pickShellsInteractively();
|
|
35
|
+
if (shells.length === 0) {
|
|
36
|
+
console.warn('nx: no shells selected — nothing installed.');
|
|
37
|
+
process.exit(0);
|
|
38
|
+
}
|
|
39
|
+
if (args.stdout && shells.length > 1) {
|
|
40
|
+
console.warn('nx: --stdout only makes sense with one shell — concatenating two wrapper scripts to stdout is never useful.');
|
|
41
|
+
process.exit(1);
|
|
42
|
+
}
|
|
43
|
+
const emit = args.stdout
|
|
44
|
+
? scripts.printCompletionScript
|
|
45
|
+
: scripts.installCompletionScript;
|
|
46
|
+
// Fire the PATH-advisory once, before any per-shell emit.
|
|
47
|
+
if (!args.force)
|
|
48
|
+
scripts.maybeWarnNxNotOnPath();
|
|
49
|
+
for (const shell of shells)
|
|
50
|
+
emit(shell);
|
|
51
|
+
process.exit(0);
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
async function pickShellsInteractively() {
|
|
55
|
+
if (!process.stdin.isTTY || !process.stderr.isTTY) {
|
|
56
|
+
console.warn('nx: please specify a shell — `nx completion <bash|zsh|fish|powershell>`.');
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
59
|
+
const detected = detectAvailableShells();
|
|
60
|
+
const answer = (await (0, enquirer_1.prompt)({
|
|
61
|
+
type: 'multiselect',
|
|
62
|
+
name: 'shells',
|
|
63
|
+
message: 'Install nx completion for which shell(s)?',
|
|
64
|
+
choices: SHELL_CHOICES.map((name) => ({
|
|
65
|
+
name,
|
|
66
|
+
value: name,
|
|
67
|
+
// Pre-check shells we can detect on this machine.
|
|
68
|
+
enabled: detected.has(name),
|
|
69
|
+
})),
|
|
70
|
+
}));
|
|
71
|
+
return answer.shells ?? [];
|
|
72
|
+
}
|
|
73
|
+
/** Best-effort detect-which-shells-the-user-has. Pre-checks the multiselect.
|
|
74
|
+
* Signals: $SHELL basename, presence of conventional rc files, $PSModulePath
|
|
75
|
+
* for PowerShell. False positives are fine — the user can uncheck. */
|
|
76
|
+
function detectAvailableShells() {
|
|
77
|
+
const found = new Set();
|
|
78
|
+
const home = (0, os_1.homedir)();
|
|
79
|
+
const shellEnv = (process.env.SHELL ?? '').replace(/\\/g, '/');
|
|
80
|
+
const shellName = shellEnv.split('/').pop() ?? '';
|
|
81
|
+
if (shellName === 'bash' || (0, fs_1.existsSync)((0, path_1.join)(home, '.bashrc'))) {
|
|
82
|
+
found.add('bash');
|
|
83
|
+
}
|
|
84
|
+
if (shellName === 'zsh' || (0, fs_1.existsSync)((0, path_1.join)(home, '.zshrc'))) {
|
|
85
|
+
found.add('zsh');
|
|
86
|
+
}
|
|
87
|
+
if (shellName === 'fish' ||
|
|
88
|
+
(0, fs_1.existsSync)((0, path_1.join)(home, '.config', 'fish', 'config.fish'))) {
|
|
89
|
+
found.add('fish');
|
|
90
|
+
}
|
|
91
|
+
if (process.env.PSModulePath || process.platform === 'win32') {
|
|
92
|
+
found.add('powershell');
|
|
93
|
+
}
|
|
94
|
+
return found;
|
|
95
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** Project names matching `current`. */
|
|
2
|
+
export declare function getProjectNameCompletions(current: string): string[];
|
|
3
|
+
/** Projects that declare `targetName`, matching `current`. */
|
|
4
|
+
export declare function getProjectNamesWithTarget(current: string, targetName: string): string[];
|
|
5
|
+
/** Two-stage `project[:target]` — stage 1 emits `project:` (nospace), stage 2 emits `project:target`. */
|
|
6
|
+
export declare function completeProjectTarget(current: string): string[];
|
|
7
|
+
/** Generator completion. Stage 1 (`nx g <TAB>`) emits plugin names (with `:`)
|
|
8
|
+
* and bare generator names (for `nx g application`); stage 2 emits
|
|
9
|
+
* `plugin:generator`. */
|
|
10
|
+
export declare function completeGenerator(current: string): string[];
|
|
11
|
+
/** Plugin names matching `current` — installed npm plugins + workspace-local
|
|
12
|
+
* plugin projects, only those declaring a generator collection. */
|
|
13
|
+
export declare function getGeneratorPluginCompletions(current: string): string[];
|
|
14
|
+
/** Generator names in a single plugin, matching `current`. */
|
|
15
|
+
export declare function getGeneratorsForPlugin(pluginName: string, current: string): string[];
|
|
16
|
+
/** Unique target names across the workspace, matching `current`. */
|
|
17
|
+
export declare function getTargetNameCompletions(current: string): string[];
|
|
18
|
+
/** Target names for a single project, matching `current`. Falls back to
|
|
19
|
+
* workspace-wide if the project isn't in the graph — covers the
|
|
20
|
+
* `project:t<TAB>` case where the user is still typing the project name. */
|
|
21
|
+
export declare function getTargetNamesForProject(current: string, projectName: string): string[];
|