@rudderjs/cli 4.15.0 → 4.17.0
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/commands/completion.d.ts +64 -0
- package/dist/commands/completion.d.ts.map +1 -0
- package/dist/commands/completion.js +412 -0
- package/dist/commands/completion.js.map +1 -0
- package/dist/commands/upgrade.d.ts +48 -0
- package/dist/commands/upgrade.d.ts.map +1 -1
- package/dist/commands/upgrade.js +340 -49
- package/dist/commands/upgrade.js.map +1 -1
- package/dist/index.js +17 -1
- package/dist/index.js.map +1 -1
- package/dist/suggest.d.ts +14 -0
- package/dist/suggest.d.ts.map +1 -0
- package/dist/suggest.js +53 -0
- package/dist/suggest.js.map +1 -0
- package/package.json +5 -5
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { Command } from 'commander';
|
|
2
|
+
export declare const SUPPORTED_SHELLS: readonly ["bash", "zsh", "fish"];
|
|
3
|
+
export type Shell = (typeof SUPPORTED_SHELLS)[number];
|
|
4
|
+
/**
|
|
5
|
+
* The static set of command names completed in v1. Built-in CLI commands plus
|
|
6
|
+
* the commands every framework package contributes. Keep roughly in sync with
|
|
7
|
+
* the ownership table in packages/cli/CLAUDE.md; drift here only costs a missing
|
|
8
|
+
* suggestion, never a broken command. Every name has at most one ':' — the bash
|
|
9
|
+
* script's colon handling relies on that.
|
|
10
|
+
*/
|
|
11
|
+
export declare const COMMAND_NAMES: readonly string[];
|
|
12
|
+
/**
|
|
13
|
+
* Commands whose first argument is conventionally an existing model name. When
|
|
14
|
+
* completing their argument, the shell calls back into `rudder completion args`
|
|
15
|
+
* to list the project's models. Routes/migrations have no arg-taking command to
|
|
16
|
+
* complete against yet, so models are the whole v1 surface.
|
|
17
|
+
*/
|
|
18
|
+
export declare const MODEL_ARG_COMMANDS: readonly string[];
|
|
19
|
+
/**
|
|
20
|
+
* Resolve dynamic argument candidates for `command`, rooted at `cwd`. v1 returns
|
|
21
|
+
* model names (the `app/Models` basenames) for the model-oriented make commands.
|
|
22
|
+
* Filesystem-only, no app boot. Returns [] when there is nothing to suggest
|
|
23
|
+
* (unknown command, not inside a project, empty dir).
|
|
24
|
+
*/
|
|
25
|
+
export declare function resolveArgCandidates(command: string, cwd?: string): string[];
|
|
26
|
+
/**
|
|
27
|
+
* Resolve flag candidates from a command's live commander definition: its long
|
|
28
|
+
* options plus `--help` (every command has it). For an unknown command (or the
|
|
29
|
+
* top-level `rudder`) we return the global flags. Reading the real definitions
|
|
30
|
+
* means the list never drifts from the actual options.
|
|
31
|
+
*/
|
|
32
|
+
export declare function resolveFlagCandidates(cmd: Command | undefined): string[];
|
|
33
|
+
/** Emit a self-contained completion script for the given shell. */
|
|
34
|
+
export declare function completionScript(shell: Shell): string;
|
|
35
|
+
interface InstallPlan {
|
|
36
|
+
/** Where the sourced completion script is written. */
|
|
37
|
+
scriptPath: string;
|
|
38
|
+
/** The rc file to add a source line to, or null when the shell autoloads (fish). */
|
|
39
|
+
rcFile: string | null;
|
|
40
|
+
/** The exact line that sources the script (bash/zsh). */
|
|
41
|
+
sourceLine: string;
|
|
42
|
+
}
|
|
43
|
+
/** Resolve the file locations for a shell, rooted at `home`. Pure — no I/O. */
|
|
44
|
+
export declare function installPlan(shell: Shell, home: string): InstallPlan;
|
|
45
|
+
/** Detect the user's shell from $SHELL. Returns null if it isn't one we support. */
|
|
46
|
+
export declare function detectShell(env?: NodeJS.ProcessEnv): Shell | null;
|
|
47
|
+
/** Idempotently add the source block to an rc file. Returns true if it changed. */
|
|
48
|
+
declare function addSourceBlock(rcFile: string, sourceLine: string): boolean;
|
|
49
|
+
/** Remove the source block from an rc file. Returns true if it changed. */
|
|
50
|
+
declare function removeSourceBlock(rcFile: string): boolean;
|
|
51
|
+
declare function runInstall(shell: Shell, home: string): void;
|
|
52
|
+
declare function runUninstall(shell: Shell, home: string): void;
|
|
53
|
+
/** Test surface — not part of the public API. */
|
|
54
|
+
export declare const _internal: {
|
|
55
|
+
addSourceBlock: typeof addSourceBlock;
|
|
56
|
+
removeSourceBlock: typeof removeSourceBlock;
|
|
57
|
+
runInstall: typeof runInstall;
|
|
58
|
+
runUninstall: typeof runUninstall;
|
|
59
|
+
BLOCK_START: string;
|
|
60
|
+
BLOCK_END: string;
|
|
61
|
+
};
|
|
62
|
+
export declare function completionCommand(program: Command): void;
|
|
63
|
+
export {};
|
|
64
|
+
//# sourceMappingURL=completion.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"completion.d.ts","sourceRoot":"","sources":["../../src/commands/completion.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAmCxC,eAAO,MAAM,gBAAgB,kCAAmC,CAAA;AAChE,MAAM,MAAM,KAAK,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAA;AAErD;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,EAAE,SAAS,MAAM,EA4B1C,CAAA;AAID;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,EAAE,SAAS,MAAM,EAE/C,CAAA;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,GAAE,MAAsB,GAAG,MAAM,EAAE,CAG3F;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,EAAE,CAMxE;AAqBD,mEAAmE;AACnE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,CAQrD;AA+HD,UAAU,WAAW;IACnB,sDAAsD;IACtD,UAAU,EAAE,MAAM,CAAA;IAClB,oFAAoF;IACpF,MAAM,EAAM,MAAM,GAAG,IAAI,CAAA;IACzB,yDAAyD;IACzD,UAAU,EAAE,MAAM,CAAA;CACnB;AAKD,+EAA+E;AAC/E,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,GAAG,WAAW,CAgBnE;AAED,oFAAoF;AACpF,wBAAgB,WAAW,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,KAAK,GAAG,IAAI,CAG9E;AA2BD,mFAAmF;AACnF,iBAAS,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAOnE;AAED,2EAA2E;AAC3E,iBAAS,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAOlD;AAMD,iBAAS,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAmBpD;AAED,iBAAS,YAAY,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAStD;AAID,iDAAiD;AACjD,eAAO,MAAM,SAAS;;;;;;;CAA0F,CAAA;AAEhH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAwDxD"}
|
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
import { mkdirSync, readFileSync, writeFileSync, rmSync, readdirSync } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import { CliError } from '../errors.js';
|
|
5
|
+
// Shell tab-completion for the `rudder` CLI. `rudder completion <shell>` prints a
|
|
6
|
+
// self-contained completion script to stdout; `rudder completion install` writes
|
|
7
|
+
// it to a stable location and wires it into the user's shell; `uninstall` undoes
|
|
8
|
+
// that cleanly.
|
|
9
|
+
//
|
|
10
|
+
// Command-name completion is STATIC: the script embeds the known framework
|
|
11
|
+
// command names below, so completing a command is instant (no CLI boot per
|
|
12
|
+
// <TAB>) and works even outside a project directory.
|
|
13
|
+
//
|
|
14
|
+
// Argument completion is DYNAMIC where it pays off: for the model-oriented make
|
|
15
|
+
// commands, the script calls back into `rudder completion args <command>`, which
|
|
16
|
+
// lists the project's models from app/Models (filesystem only, no app boot).
|
|
17
|
+
//
|
|
18
|
+
// Flag completion is also DYNAMIC: when the current word starts with '-', the
|
|
19
|
+
// script calls `rudder completion flags <command>`, which reads the command's
|
|
20
|
+
// live commander option definitions (so the flag list never drifts). Commands
|
|
21
|
+
// that parse flags by hand (allowUnknownOption) expose only --help; the make:*
|
|
22
|
+
// family registers real options, which is where flag completion matters most.
|
|
23
|
+
// Both resolvers live in TS (testable) and are structured so more sources can be
|
|
24
|
+
// added later. Unknown/top-level falls back to the global flags.
|
|
25
|
+
//
|
|
26
|
+
// No third-party dependency: hand-rolled scripts for bash / zsh / fish. tabtab
|
|
27
|
+
// was considered but its model is dynamic (a CLI round-trip per keystroke), which
|
|
28
|
+
// is the opposite of what static completion wants.
|
|
29
|
+
const C = {
|
|
30
|
+
green: (s) => `\x1b[32m${s}\x1b[0m`,
|
|
31
|
+
yellow: (s) => `\x1b[33m${s}\x1b[0m`,
|
|
32
|
+
dim: (s) => `\x1b[2m${s}\x1b[0m`,
|
|
33
|
+
bold: (s) => `\x1b[1m${s}\x1b[0m`,
|
|
34
|
+
};
|
|
35
|
+
export const SUPPORTED_SHELLS = ['bash', 'zsh', 'fish'];
|
|
36
|
+
/**
|
|
37
|
+
* The static set of command names completed in v1. Built-in CLI commands plus
|
|
38
|
+
* the commands every framework package contributes. Keep roughly in sync with
|
|
39
|
+
* the ownership table in packages/cli/CLAUDE.md; drift here only costs a missing
|
|
40
|
+
* suggestion, never a broken command. Every name has at most one ':' — the bash
|
|
41
|
+
* script's colon handling relies on that.
|
|
42
|
+
*/
|
|
43
|
+
export const COMMAND_NAMES = [
|
|
44
|
+
// CLI built-ins
|
|
45
|
+
'about', 'add', 'completion', 'doctor', 'down', 'fresh', 'optimize:clear',
|
|
46
|
+
'remove', 'test', 'tinker', 'up', 'upgrade', 'key:generate',
|
|
47
|
+
'command:list', 'module:make', 'module:publish', 'vendor:publish',
|
|
48
|
+
'providers:discover',
|
|
49
|
+
// make:* generators (CLI + packages)
|
|
50
|
+
'make:agent', 'make:cast', 'make:command', 'make:controller', 'make:event',
|
|
51
|
+
'make:exception', 'make:factory', 'make:job', 'make:listener', 'make:mail',
|
|
52
|
+
'make:mcp-prompt', 'make:mcp-resource', 'make:mcp-server', 'make:mcp-tool',
|
|
53
|
+
'make:middleware', 'make:migration', 'make:model', 'make:notification',
|
|
54
|
+
'make:observer', 'make:passport-client', 'make:policy', 'make:provider',
|
|
55
|
+
'make:request', 'make:resource', 'make:seeder', 'make:terminal', 'make:test',
|
|
56
|
+
// @rudderjs/orm
|
|
57
|
+
'migrate', 'migrate:fresh', 'migrate:refresh', 'migrate:rollback',
|
|
58
|
+
'migrate:status', 'schema:types', 'db:generate', 'db:push', 'db:seed',
|
|
59
|
+
'db:show', 'db:table', 'db:query', 'model:prune',
|
|
60
|
+
// @rudderjs/router + openapi + core
|
|
61
|
+
'route:list', 'openapi:generate', 'event:list', 'config:show',
|
|
62
|
+
// @rudderjs/queue + cache + schedule
|
|
63
|
+
'queue:work', 'queue:status', 'queue:clear', 'queue:failed', 'queue:retry',
|
|
64
|
+
'cache:clear', 'schedule:run', 'schedule:work', 'schedule:list',
|
|
65
|
+
// @rudderjs/storage + sync + broadcast + boost + passport + ai + mcp
|
|
66
|
+
'storage:link', 'sync:docs', 'sync:clear', 'sync:inspect',
|
|
67
|
+
'broadcast:connections', 'boost:install', 'boost:update', 'boost:mcp',
|
|
68
|
+
'passport:keys', 'passport:client', 'ai:eval', 'mcp:start', 'mcp:list',
|
|
69
|
+
// @rudderjs/vite sync commands
|
|
70
|
+
'view:sync', 'routes:sync', 'env:sync', 'config:sync',
|
|
71
|
+
];
|
|
72
|
+
// ─── Dynamic argument resolution ─────────────────────────────
|
|
73
|
+
/**
|
|
74
|
+
* Commands whose first argument is conventionally an existing model name. When
|
|
75
|
+
* completing their argument, the shell calls back into `rudder completion args`
|
|
76
|
+
* to list the project's models. Routes/migrations have no arg-taking command to
|
|
77
|
+
* complete against yet, so models are the whole v1 surface.
|
|
78
|
+
*/
|
|
79
|
+
export const MODEL_ARG_COMMANDS = [
|
|
80
|
+
'make:factory', 'make:seeder', 'make:policy', 'make:observer',
|
|
81
|
+
];
|
|
82
|
+
/**
|
|
83
|
+
* Resolve dynamic argument candidates for `command`, rooted at `cwd`. v1 returns
|
|
84
|
+
* model names (the `app/Models` basenames) for the model-oriented make commands.
|
|
85
|
+
* Filesystem-only, no app boot. Returns [] when there is nothing to suggest
|
|
86
|
+
* (unknown command, not inside a project, empty dir).
|
|
87
|
+
*/
|
|
88
|
+
export function resolveArgCandidates(command, cwd = process.cwd()) {
|
|
89
|
+
if (MODEL_ARG_COMMANDS.includes(command))
|
|
90
|
+
return listModels(cwd);
|
|
91
|
+
return [];
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Resolve flag candidates from a command's live commander definition: its long
|
|
95
|
+
* options plus `--help` (every command has it). For an unknown command (or the
|
|
96
|
+
* top-level `rudder`) we return the global flags. Reading the real definitions
|
|
97
|
+
* means the list never drifts from the actual options.
|
|
98
|
+
*/
|
|
99
|
+
export function resolveFlagCandidates(cmd) {
|
|
100
|
+
if (!cmd)
|
|
101
|
+
return ['--help', '--version'];
|
|
102
|
+
const longs = cmd.options
|
|
103
|
+
.map(o => o.long)
|
|
104
|
+
.filter((l) => Boolean(l));
|
|
105
|
+
return [...new Set([...longs, '--help'])].sort();
|
|
106
|
+
}
|
|
107
|
+
/** List model names from `app/Models` by filename, mirroring tinker's discovery. */
|
|
108
|
+
function listModels(cwd) {
|
|
109
|
+
const dir = path.join(cwd, 'app', 'Models');
|
|
110
|
+
let entries;
|
|
111
|
+
try {
|
|
112
|
+
entries = readdirSync(dir);
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
return []; // not a rudder project, or no models yet
|
|
116
|
+
}
|
|
117
|
+
const exts = new Set(['.ts', '.js', '.mts', '.mjs']);
|
|
118
|
+
const names = entries
|
|
119
|
+
.filter(f => exts.has(path.extname(f)))
|
|
120
|
+
.map(f => path.basename(f, path.extname(f)))
|
|
121
|
+
.filter(n => n !== 'index');
|
|
122
|
+
return [...new Set(names)].sort();
|
|
123
|
+
}
|
|
124
|
+
// ─── Script generation ───────────────────────────────────────
|
|
125
|
+
/** Emit a self-contained completion script for the given shell. */
|
|
126
|
+
export function completionScript(shell) {
|
|
127
|
+
const words = [...COMMAND_NAMES].sort().join(' ');
|
|
128
|
+
const argCmds = [...MODEL_ARG_COMMANDS].join(' ');
|
|
129
|
+
switch (shell) {
|
|
130
|
+
case 'bash': return bashScript(words, argCmds);
|
|
131
|
+
case 'zsh': return zshScript(words, argCmds);
|
|
132
|
+
case 'fish': return fishScript(words, argCmds);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
function bashScript(words, argCmds) {
|
|
136
|
+
// Commands contain a ':' which is in bash's default COMP_WORDBREAKS, so the
|
|
137
|
+
// word under the cursor is split. We reconstruct the colon-joined word and
|
|
138
|
+
// strip the already-typed "ns:" prefix from each match so bash appends only
|
|
139
|
+
// the suffix. Self-contained — no dependency on the bash-completion package.
|
|
140
|
+
return `# rudder bash completion. Source this file or use \`rudder completion install\`.
|
|
141
|
+
_rudder_complete() {
|
|
142
|
+
local cur cword cmd k
|
|
143
|
+
cword="\${COMP_CWORD}"
|
|
144
|
+
cur="\${COMP_WORDS[cword]}"
|
|
145
|
+
|
|
146
|
+
# Flag completion: the word starts with '-'. Extract the command as the
|
|
147
|
+
# colon-joined word beginning at index 1 (robust to intervening arguments), then list
|
|
148
|
+
# its flags. Unknown/top-level falls back to the global flags.
|
|
149
|
+
if [[ "\${cur}" == -* ]]; then
|
|
150
|
+
local fcmd="\${COMP_WORDS[1]}" j=2
|
|
151
|
+
while [ "\${COMP_WORDS[j]}" = ":" ] && [ -n "\${COMP_WORDS[j+1]}" ]; do
|
|
152
|
+
fcmd="\${fcmd}:\${COMP_WORDS[j+1]}"; j=$((j+2))
|
|
153
|
+
done
|
|
154
|
+
local fl="--help --version"
|
|
155
|
+
if [[ " ${words} " == *" \${fcmd} "* ]]; then
|
|
156
|
+
fl=$(rudder completion flags "\${fcmd}" 2>/dev/null)
|
|
157
|
+
fi
|
|
158
|
+
COMPREPLY=( $(compgen -W "\${fl}" -- "\${cur}") )
|
|
159
|
+
return 0
|
|
160
|
+
fi
|
|
161
|
+
|
|
162
|
+
# Reconstruct the command from the words between "rudder" and the current one.
|
|
163
|
+
# Colon-split elements ("make" ":" "factory") concatenate back to "make:factory".
|
|
164
|
+
# This equals a complete command name only once the command is fully typed and
|
|
165
|
+
# the cursor sits on its argument (a partial like "make:" never matches).
|
|
166
|
+
cmd=""
|
|
167
|
+
for ((k=1; k<cword; k++)); do cmd="\${cmd}\${COMP_WORDS[k]}"; done
|
|
168
|
+
if [[ " ${words} " == *" \${cmd} "* ]]; then
|
|
169
|
+
# The cursor is on the command's argument, not the command itself. Only the
|
|
170
|
+
# model-arg commands have dynamic candidates; others complete to nothing.
|
|
171
|
+
local cand=""
|
|
172
|
+
if [[ " ${argCmds} " == *" \${cmd} "* ]]; then
|
|
173
|
+
cand=$(rudder completion args "\${cmd}" 2>/dev/null)
|
|
174
|
+
fi
|
|
175
|
+
COMPREPLY=( $(compgen -W "\${cand}" -- "\${cur}") )
|
|
176
|
+
return 0
|
|
177
|
+
fi
|
|
178
|
+
|
|
179
|
+
# Glue a single-colon-split word back together under bash's default
|
|
180
|
+
# COMP_WORDBREAKS (which contains ':'). Two shapes occur:
|
|
181
|
+
# "make" ":" (cursor right after the colon) -> cur = "make:"
|
|
182
|
+
# "make" ":" "mo" (a suffix typed) -> cur = "make:mo"
|
|
183
|
+
if [ "\${cur}" = ":" ] && [ "\${cword}" -ge 1 ]; then
|
|
184
|
+
cur="\${COMP_WORDS[cword-1]}:"
|
|
185
|
+
elif [ "\${cword}" -ge 2 ] && [ "\${COMP_WORDS[cword-1]}" = ":" ]; then
|
|
186
|
+
cur="\${COMP_WORDS[cword-2]}:\${cur}"
|
|
187
|
+
fi
|
|
188
|
+
local matches
|
|
189
|
+
matches=$(compgen -W "${words}" -- "\${cur}")
|
|
190
|
+
COMPREPLY=()
|
|
191
|
+
if [[ "\${cur}" == *:* ]]; then
|
|
192
|
+
local prefix="\${cur%:*}:" m
|
|
193
|
+
for m in \${matches}; do COMPREPLY+=( "\${m#\${prefix}}" ); done
|
|
194
|
+
else
|
|
195
|
+
local m
|
|
196
|
+
for m in \${matches}; do COMPREPLY+=( "\${m}" ); done
|
|
197
|
+
fi
|
|
198
|
+
}
|
|
199
|
+
complete -F _rudder_complete rudder
|
|
200
|
+
`;
|
|
201
|
+
}
|
|
202
|
+
function zshScript(words, argCmds) {
|
|
203
|
+
// zsh treats ':' as an ordinary word character, so no colon gymnastics needed.
|
|
204
|
+
// Sourcing this file (rather than autoloading via fpath) means the #compdef tag
|
|
205
|
+
// is inert, so we register explicitly via compdef once compinit has defined it.
|
|
206
|
+
return `#compdef rudder
|
|
207
|
+
# rudder zsh completion. Source this file or use \`rudder completion install\`.
|
|
208
|
+
_rudder() {
|
|
209
|
+
# Flag completion: the word being completed starts with '-'. zsh arrays are
|
|
210
|
+
# 1-indexed, so $words[2] is the command token after 'rudder' (zsh does not
|
|
211
|
+
# split on ':'); unknown/top-level uses the global flags.
|
|
212
|
+
if [[ "\${words[CURRENT]}" == -* ]]; then
|
|
213
|
+
local cmd="\${words[2]}"
|
|
214
|
+
local -a fl
|
|
215
|
+
if [[ " ${words} " == *" \${cmd} "* ]]; then
|
|
216
|
+
fl=(\${(f)"$(rudder completion flags \${cmd} 2>/dev/null)"})
|
|
217
|
+
else
|
|
218
|
+
fl=(--help --version)
|
|
219
|
+
fi
|
|
220
|
+
compadd -a fl
|
|
221
|
+
return
|
|
222
|
+
fi
|
|
223
|
+
# Past the command word: complete its argument dynamically for the model-arg
|
|
224
|
+
# commands ($words[2] is the command).
|
|
225
|
+
if (( CURRENT >= 3 )); then
|
|
226
|
+
local cmd="\${words[2]}"
|
|
227
|
+
if [[ " ${argCmds} " == *" \${cmd} "* ]]; then
|
|
228
|
+
local -a cand
|
|
229
|
+
cand=(\${(f)"$(rudder completion args \${cmd} 2>/dev/null)"})
|
|
230
|
+
compadd -a cand
|
|
231
|
+
fi
|
|
232
|
+
return
|
|
233
|
+
fi
|
|
234
|
+
local -a cmds
|
|
235
|
+
cmds=(${words})
|
|
236
|
+
compadd -a cmds
|
|
237
|
+
}
|
|
238
|
+
if (( $+functions[compdef] )); then
|
|
239
|
+
compdef _rudder rudder
|
|
240
|
+
fi
|
|
241
|
+
`;
|
|
242
|
+
}
|
|
243
|
+
function fishScript(words, argCmds) {
|
|
244
|
+
// fish autoloads files in its completions dir, so install drops this there and
|
|
245
|
+
// no rc edit is needed. __fish_use_subcommand limits the command list to the
|
|
246
|
+
// first position; the model-arg rule fires once such a subcommand is present.
|
|
247
|
+
return `# rudder fish completion. Autoloaded from the fish completions dir, or use \`rudder completion install\`.
|
|
248
|
+
complete -c rudder -f -n '__fish_use_subcommand' -a '${words}'
|
|
249
|
+
complete -c rudder -f -n '__fish_seen_subcommand_from ${argCmds}' -a '(rudder completion args (commandline -opc)[2] 2>/dev/null)'
|
|
250
|
+
# Flag completion once a known subcommand is present; this condition matches the
|
|
251
|
+
# full known-command list (${words}). fish offers these when the token starts with '-'.
|
|
252
|
+
complete -c rudder -f -n '__fish_seen_subcommand_from ${words}' -a '(rudder completion flags (commandline -opc)[2] 2>/dev/null)'
|
|
253
|
+
`;
|
|
254
|
+
}
|
|
255
|
+
const BLOCK_START = '# >>> rudder completions >>>';
|
|
256
|
+
const BLOCK_END = '# <<< rudder completions <<<';
|
|
257
|
+
/** Resolve the file locations for a shell, rooted at `home`. Pure — no I/O. */
|
|
258
|
+
export function installPlan(shell, home) {
|
|
259
|
+
switch (shell) {
|
|
260
|
+
case 'bash': {
|
|
261
|
+
const scriptPath = path.join(home, '.rudder', 'completion.bash');
|
|
262
|
+
return { scriptPath, rcFile: path.join(home, '.bashrc'), sourceLine: `[ -f "${scriptPath}" ] && source "${scriptPath}"` };
|
|
263
|
+
}
|
|
264
|
+
case 'zsh': {
|
|
265
|
+
const scriptPath = path.join(home, '.rudder', 'completion.zsh');
|
|
266
|
+
return { scriptPath, rcFile: path.join(home, '.zshrc'), sourceLine: `[ -f "${scriptPath}" ] && source "${scriptPath}"` };
|
|
267
|
+
}
|
|
268
|
+
case 'fish': {
|
|
269
|
+
// fish autoloads any rudder.fish in its completions dir — no rc edit.
|
|
270
|
+
const scriptPath = path.join(home, '.config', 'fish', 'completions', 'rudder.fish');
|
|
271
|
+
return { scriptPath, rcFile: null, sourceLine: '' };
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
/** Detect the user's shell from $SHELL. Returns null if it isn't one we support. */
|
|
276
|
+
export function detectShell(env = process.env) {
|
|
277
|
+
const sh = path.basename(env['SHELL'] ?? '');
|
|
278
|
+
return SUPPORTED_SHELLS.includes(sh) ? sh : null;
|
|
279
|
+
}
|
|
280
|
+
function ensureDir(file) {
|
|
281
|
+
mkdirSync(path.dirname(file), { recursive: true });
|
|
282
|
+
}
|
|
283
|
+
/** Read a file, treating a missing one as empty. Avoids a check-then-read race. */
|
|
284
|
+
function readOrEmpty(file) {
|
|
285
|
+
try {
|
|
286
|
+
return readFileSync(file, 'utf8');
|
|
287
|
+
}
|
|
288
|
+
catch (err) {
|
|
289
|
+
if (err.code === 'ENOENT')
|
|
290
|
+
return '';
|
|
291
|
+
throw err;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
/** Remove a file if present, returning whether it existed. No check-then-use race. */
|
|
295
|
+
function rmIfExists(file) {
|
|
296
|
+
try {
|
|
297
|
+
rmSync(file);
|
|
298
|
+
return true;
|
|
299
|
+
}
|
|
300
|
+
catch (err) {
|
|
301
|
+
if (err.code === 'ENOENT')
|
|
302
|
+
return false;
|
|
303
|
+
throw err;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
/** Idempotently add the source block to an rc file. Returns true if it changed. */
|
|
307
|
+
function addSourceBlock(rcFile, sourceLine) {
|
|
308
|
+
const existing = readOrEmpty(rcFile);
|
|
309
|
+
if (existing.includes(BLOCK_START))
|
|
310
|
+
return false;
|
|
311
|
+
const block = `${BLOCK_START}\n${sourceLine}\n${BLOCK_END}\n`;
|
|
312
|
+
const sep = existing.length > 0 && !existing.endsWith('\n') ? '\n' : '';
|
|
313
|
+
writeFileSync(rcFile, existing + sep + block);
|
|
314
|
+
return true;
|
|
315
|
+
}
|
|
316
|
+
/** Remove the source block from an rc file. Returns true if it changed. */
|
|
317
|
+
function removeSourceBlock(rcFile) {
|
|
318
|
+
const existing = readOrEmpty(rcFile);
|
|
319
|
+
if (!existing.includes(BLOCK_START))
|
|
320
|
+
return false;
|
|
321
|
+
// Strip the marked block (and a single trailing newline left behind).
|
|
322
|
+
const pattern = new RegExp(`\\n?${escapeRe(BLOCK_START)}[\\s\\S]*?${escapeRe(BLOCK_END)}\\n?`, 'g');
|
|
323
|
+
writeFileSync(rcFile, existing.replace(pattern, '\n').replace(/\n{3,}/g, '\n\n'));
|
|
324
|
+
return true;
|
|
325
|
+
}
|
|
326
|
+
function escapeRe(s) {
|
|
327
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
328
|
+
}
|
|
329
|
+
function runInstall(shell, home) {
|
|
330
|
+
const plan = installPlan(shell, home);
|
|
331
|
+
ensureDir(plan.scriptPath);
|
|
332
|
+
writeFileSync(plan.scriptPath, completionScript(shell));
|
|
333
|
+
if (plan.rcFile) {
|
|
334
|
+
const changed = addSourceBlock(plan.rcFile, plan.sourceLine);
|
|
335
|
+
console.log(C.green('✓') + ` Installed ${shell} completions`);
|
|
336
|
+
console.log(` script: ${C.dim(plan.scriptPath)}`);
|
|
337
|
+
console.log(changed
|
|
338
|
+
? ` added a source line to ${C.dim(plan.rcFile)}`
|
|
339
|
+
: ` ${C.dim(plan.rcFile)} already sources it ${C.dim('(no change)')}`);
|
|
340
|
+
console.log(`\nOpen a new shell or run ${C.bold(`source ${plan.rcFile}`)} to start completing.`);
|
|
341
|
+
}
|
|
342
|
+
else {
|
|
343
|
+
// fish autoloads — nothing to source.
|
|
344
|
+
console.log(C.green('✓') + ` Installed fish completions`);
|
|
345
|
+
console.log(` script: ${C.dim(plan.scriptPath)}`);
|
|
346
|
+
console.log(`\nOpen a new shell to start completing.`);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
function runUninstall(shell, home) {
|
|
350
|
+
const plan = installPlan(shell, home);
|
|
351
|
+
// rmIfExists attempts the remove and reports existence from the result, so
|
|
352
|
+
// there is no check-then-remove race.
|
|
353
|
+
let removed = rmIfExists(plan.scriptPath);
|
|
354
|
+
if (plan.rcFile && removeSourceBlock(plan.rcFile))
|
|
355
|
+
removed = true;
|
|
356
|
+
console.log(removed
|
|
357
|
+
? C.green('✓') + ` Removed ${shell} completions`
|
|
358
|
+
: C.yellow('•') + ` No ${shell} completions were installed`);
|
|
359
|
+
}
|
|
360
|
+
// ─── Command registration ────────────────────────────────────
|
|
361
|
+
/** Test surface — not part of the public API. */
|
|
362
|
+
export const _internal = { addSourceBlock, removeSourceBlock, runInstall, runUninstall, BLOCK_START, BLOCK_END };
|
|
363
|
+
export function completionCommand(program) {
|
|
364
|
+
program
|
|
365
|
+
.command('completion')
|
|
366
|
+
.description('Shell tab-completion: print a script, or install/uninstall it')
|
|
367
|
+
.argument('[action]', 'bash | zsh | fish | install | uninstall')
|
|
368
|
+
.argument('[target]', 'internal: command name when action is "args"')
|
|
369
|
+
.action((action, target) => {
|
|
370
|
+
const home = os.homedir();
|
|
371
|
+
// Internal: the installed scripts call `rudder completion args <command>`
|
|
372
|
+
// to resolve dynamic argument candidates (e.g. model names). One per line.
|
|
373
|
+
if (action === 'args') {
|
|
374
|
+
if (target)
|
|
375
|
+
process.stdout.write(resolveArgCandidates(target).join('\n') + '\n');
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
// Internal: `rudder completion flags <command>` lists a command's option
|
|
379
|
+
// flags, read from its live commander definition. One per line.
|
|
380
|
+
if (action === 'flags') {
|
|
381
|
+
const cmd = target ? program.commands.find(c => c.name() === target) : undefined;
|
|
382
|
+
process.stdout.write(resolveFlagCandidates(cmd).join('\n') + '\n');
|
|
383
|
+
return;
|
|
384
|
+
}
|
|
385
|
+
// No arg, or an explicit shell name → print the script to stdout.
|
|
386
|
+
if (action === undefined || SUPPORTED_SHELLS.includes(action)) {
|
|
387
|
+
const shell = (action ?? detectShell());
|
|
388
|
+
if (!shell) {
|
|
389
|
+
throw new CliError('Could not detect your shell. Pass one explicitly:\n' +
|
|
390
|
+
' rudder completion bash | zsh | fish');
|
|
391
|
+
}
|
|
392
|
+
process.stdout.write(completionScript(shell));
|
|
393
|
+
return;
|
|
394
|
+
}
|
|
395
|
+
if (action === 'install' || action === 'uninstall') {
|
|
396
|
+
const shell = detectShell();
|
|
397
|
+
if (!shell) {
|
|
398
|
+
throw new CliError(`Could not detect a supported shell from $SHELL.\n` +
|
|
399
|
+
`Generate the script manually instead, e.g.:\n` +
|
|
400
|
+
` rudder completion zsh > ~/.zsh/completions/_rudder`);
|
|
401
|
+
}
|
|
402
|
+
if (action === 'install')
|
|
403
|
+
runInstall(shell, home);
|
|
404
|
+
else
|
|
405
|
+
runUninstall(shell, home);
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
throw new CliError(`Unknown completion action "${action}".\n` +
|
|
409
|
+
`Usage: rudder completion [bash|zsh|fish|install|uninstall]`);
|
|
410
|
+
});
|
|
411
|
+
}
|
|
412
|
+
//# sourceMappingURL=completion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"completion.js","sourceRoot":"","sources":["../../src/commands/completion.ts"],"names":[],"mappings":"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"}
|
|
@@ -58,6 +58,7 @@ type FetchManifestFn = (pkg: string, version: string) => Promise<NpmManifest | n
|
|
|
58
58
|
* manifests.
|
|
59
59
|
*/
|
|
60
60
|
export declare function collectPeerMismatches(rows: PlanRow[], consumer: Map<string, ConsumerPeer>, fetcher: FetchManifestFn): Promise<PeerMismatch[]>;
|
|
61
|
+
type UpgradeMode = 'latest' | 'minor' | 'patch';
|
|
61
62
|
interface DepEntry {
|
|
62
63
|
name: string;
|
|
63
64
|
range: string;
|
|
@@ -71,6 +72,53 @@ interface PlanRow {
|
|
|
71
72
|
target: ParsedVersion;
|
|
72
73
|
newRange: string;
|
|
73
74
|
}
|
|
75
|
+
type OverrideSource = 'pnpm-workspace.yaml' | 'pnpm.overrides' | 'resolutions';
|
|
76
|
+
interface OverridePin {
|
|
77
|
+
name: string;
|
|
78
|
+
value: string;
|
|
79
|
+
source: OverrideSource;
|
|
80
|
+
}
|
|
81
|
+
interface OverridePlanRow {
|
|
82
|
+
name: string;
|
|
83
|
+
source: OverrideSource;
|
|
84
|
+
current: ParsedVersion;
|
|
85
|
+
target: ParsedVersion;
|
|
86
|
+
oldValue: string;
|
|
87
|
+
newValue: string;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Parse the `@rudderjs/*` entries out of a `pnpm-workspace.yaml`'s top-level
|
|
91
|
+
* `overrides:` block. Deliberately text-scoped (not a full YAML parse) so the
|
|
92
|
+
* companion {@link replaceYamlOverride} can rewrite in place and preserve
|
|
93
|
+
* comments / formatting. Only simple `name: version` pins are read — pnpm's
|
|
94
|
+
* selector keys (`a>b`, `foo@1>bar`) never match a bare `@rudderjs/<name>`.
|
|
95
|
+
*/
|
|
96
|
+
export declare function parseYamlOverrides(yaml: string): Array<[string, string]>;
|
|
97
|
+
/**
|
|
98
|
+
* Rewrite one `@rudderjs/<name>` pin in a `pnpm-workspace.yaml` overrides block
|
|
99
|
+
* to `version`, preserving the original quoting, operator prefix, and any inline
|
|
100
|
+
* comment. Returns the new text and whether a line was replaced.
|
|
101
|
+
*/
|
|
102
|
+
export declare function replaceYamlOverride(yaml: string, name: string, version: string): {
|
|
103
|
+
text: string;
|
|
104
|
+
replaced: boolean;
|
|
105
|
+
};
|
|
106
|
+
/**
|
|
107
|
+
* Collect every `@rudderjs/*` override pin governing the run, from the root
|
|
108
|
+
* package.json (`pnpm.overrides`, `resolutions`) and `pnpm-workspace.yaml`.
|
|
109
|
+
*/
|
|
110
|
+
export declare function collectOverridePins(rootPkg: Record<string, unknown>, workspaceYaml: string | null): OverridePin[];
|
|
111
|
+
type FetchLatestFn = (pkg: string) => Promise<string | null>;
|
|
112
|
+
/**
|
|
113
|
+
* Build the override-bump plan: for each pinned `@rudderjs/*` package fetch the
|
|
114
|
+
* latest version, cap it by `mode`, and (when it's an upgrade) produce a row
|
|
115
|
+
* with the rewritten pin value (original operator prefix preserved). Latest is
|
|
116
|
+
* fetched once per distinct package name even when pinned in several sources.
|
|
117
|
+
*/
|
|
118
|
+
export declare function buildOverridePlan(pins: OverridePin[], mode: UpgradeMode, fetch: FetchLatestFn): Promise<{
|
|
119
|
+
rows: OverridePlanRow[];
|
|
120
|
+
skipped: string[];
|
|
121
|
+
}>;
|
|
74
122
|
type FetchChangelogFn = (pkg: string) => Promise<string | null>;
|
|
75
123
|
/**
|
|
76
124
|
* Walk the plan, fetch + parse each package's CHANGELOG in parallel, return a
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upgrade.d.ts","sourceRoot":"","sources":["../../src/commands/upgrade.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AA6BxC,UAAU,aAAa;IAAG,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE;AAyGvE,UAAU,WAAW;IACnB,OAAO,EAAE,MAAM,CAAA;IACf,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAC1C;AA8CD;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAG,MAAM,CAAA;IAChB,MAAM,EAAI,aAAa,CAAA;IACvB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAyBD;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,EAAE,EAAI,MAAM,EACZ,IAAI,EAAE,aAAa,EACnB,EAAE,EAAI,aAAa,GAClB,cAAc,EAAE,CAuBlB;AA2BD,UAAU,YAAY;IACpB,KAAK,EAAI,MAAM,CAAA;IACf,OAAO,EAAE,cAAc,GAAG,iBAAiB,GAAG,kBAAkB,CAAA;CACjE;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAUzF;AAED,UAAU,YAAY;IACpB,IAAI,EAAa,MAAM,CAAA;IACvB,QAAQ,EAAS,MAAM,CAAA;IACvB,aAAa,EAAI,MAAM,CAAA;IACvB,eAAe,EAAE,YAAY,CAAC,SAAS,CAAC,GAAG,IAAI,CAAA;IAC/C,aAAa,EAAI,MAAM,CAAA;IACvB,MAAM,EAAW,MAAM,CAAA;CACxB;AAED,KAAK,eAAe,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAA;AAEpF;;;;;;;;;GASG;AACH,wBAAsB,qBAAqB,CACzC,IAAI,EAAM,OAAO,EAAE,EACnB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,EACnC,OAAO,EAAG,eAAe,GACxB,OAAO,CAAC,YAAY,EAAE,CAAC,CA+BzB;
|
|
1
|
+
{"version":3,"file":"upgrade.d.ts","sourceRoot":"","sources":["../../src/commands/upgrade.ts"],"names":[],"mappings":"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"}
|