@robinmordasiewicz/f5xc-xcsh 6.35.0 → 6.37.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/completions/_xcsh +1 -2
- package/completions/xcsh.bash +1 -1
- package/completions/xcsh.fish +1 -2
- package/dist/index.js +682 -651
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -44530,9 +44530,9 @@ var generatedDomains = /* @__PURE__ */ new Map([
|
|
|
44530
44530
|
["observability", {
|
|
44531
44531
|
name: "observability",
|
|
44532
44532
|
displayName: "Observability",
|
|
44533
|
-
description: "
|
|
44533
|
+
description: "Set up synthetic monitoring for DNS resolution and HTTP services across AWS regions. Generate health reports with historical trends and summary dashboards. Monitor certificate validity, track response times, and aggregate results by namespace for capacity planning.",
|
|
44534
44534
|
descriptionShort: "Configure synthetic monitors and health checks",
|
|
44535
|
-
descriptionMedium: "
|
|
44535
|
+
descriptionMedium: "Define DNS and HTTP monitors with regional testing. Track certificate expiration and service availability across zones.",
|
|
44536
44536
|
aliases: ["obs", "monitoring", "synth"],
|
|
44537
44537
|
complexity: "advanced",
|
|
44538
44538
|
isPreview: false,
|
|
@@ -44600,9 +44600,9 @@ var generatedDomains = /* @__PURE__ */ new Map([
|
|
|
44600
44600
|
["sites", {
|
|
44601
44601
|
name: "sites",
|
|
44602
44602
|
displayName: "Sites",
|
|
44603
|
-
description: "
|
|
44604
|
-
descriptionShort: "Deploy
|
|
44605
|
-
descriptionMedium: "Configure
|
|
44603
|
+
description: "Deploy edge nodes across AWS, Azure, and GCP with automated provisioning. Configure VPC peering, transit gateway attachments, and VPN tunnel settings. Define virtual groupings with label selectors for policy targeting. Manage Kubernetes cluster integrations and secure mesh deployments. Monitor node health, validate configurations, and set IP prefix allocations.",
|
|
44604
|
+
descriptionShort: "Deploy edge nodes across cloud providers",
|
|
44605
|
+
descriptionMedium: "Configure AWS, Azure, GCP deployments with VPC integration. Manage transit gateways and VPN tunnels.",
|
|
44606
44606
|
aliases: ["site", "deployment"],
|
|
44607
44607
|
complexity: "advanced",
|
|
44608
44608
|
isPreview: false,
|
|
@@ -45354,8 +45354,8 @@ function getLogoModeFromEnv(envPrefix) {
|
|
|
45354
45354
|
var CLI_NAME = "xcsh";
|
|
45355
45355
|
var CLI_FULL_NAME = "F5 Distributed Cloud Shell";
|
|
45356
45356
|
function getVersion() {
|
|
45357
|
-
if ("6.
|
|
45358
|
-
return "6.
|
|
45357
|
+
if ("6.37.0") {
|
|
45358
|
+
return "6.37.0";
|
|
45359
45359
|
}
|
|
45360
45360
|
if (process.env.XCSH_VERSION) {
|
|
45361
45361
|
return process.env.XCSH_VERSION;
|
|
@@ -46843,6 +46843,450 @@ function useHistory(options) {
|
|
|
46843
46843
|
// src/repl/hooks/useCompletion.ts
|
|
46844
46844
|
var import_react27 = __toESM(require_react(), 1);
|
|
46845
46845
|
|
|
46846
|
+
// src/config/envvars.ts
|
|
46847
|
+
var EnvVarRegistry = [
|
|
46848
|
+
{
|
|
46849
|
+
name: `${ENV_PREFIX}_API_URL`,
|
|
46850
|
+
description: "API endpoint URL",
|
|
46851
|
+
relatedFlag: "",
|
|
46852
|
+
required: true
|
|
46853
|
+
},
|
|
46854
|
+
{
|
|
46855
|
+
name: `${ENV_PREFIX}_API_TOKEN`,
|
|
46856
|
+
description: "API authentication token",
|
|
46857
|
+
relatedFlag: "",
|
|
46858
|
+
required: true
|
|
46859
|
+
},
|
|
46860
|
+
{
|
|
46861
|
+
name: `${ENV_PREFIX}_NAMESPACE`,
|
|
46862
|
+
description: "Default namespace",
|
|
46863
|
+
relatedFlag: "-ns"
|
|
46864
|
+
},
|
|
46865
|
+
{
|
|
46866
|
+
name: `${ENV_PREFIX}_OUTPUT_FORMAT`,
|
|
46867
|
+
description: "Output format (json, yaml, table)",
|
|
46868
|
+
relatedFlag: "-o"
|
|
46869
|
+
},
|
|
46870
|
+
{
|
|
46871
|
+
name: `${ENV_PREFIX}_LOGO`,
|
|
46872
|
+
description: "Logo display mode (auto, image, ascii, both, none)",
|
|
46873
|
+
relatedFlag: "--logo"
|
|
46874
|
+
},
|
|
46875
|
+
{
|
|
46876
|
+
name: "NO_COLOR",
|
|
46877
|
+
description: "Disable color output",
|
|
46878
|
+
relatedFlag: "--no-color"
|
|
46879
|
+
}
|
|
46880
|
+
];
|
|
46881
|
+
function formatEnvVarsSection() {
|
|
46882
|
+
const maxLen = Math.max(...EnvVarRegistry.map((e) => e.name.length));
|
|
46883
|
+
const lines = ["ENVIRONMENT VARIABLES"];
|
|
46884
|
+
for (const env3 of EnvVarRegistry) {
|
|
46885
|
+
const padding = " ".repeat(maxLen - env3.name.length + 3);
|
|
46886
|
+
const flagNote = env3.relatedFlag ? ` [${env3.relatedFlag}]` : "";
|
|
46887
|
+
lines.push(` ${env3.name}${padding}${env3.description}${flagNote}`);
|
|
46888
|
+
}
|
|
46889
|
+
return lines;
|
|
46890
|
+
}
|
|
46891
|
+
function formatConfigSection() {
|
|
46892
|
+
return [
|
|
46893
|
+
"CONFIGURATION",
|
|
46894
|
+
` Config file: ~/${CONFIG_FILE_NAME}`,
|
|
46895
|
+
" Priority: CLI flags > environment variables > config file > defaults",
|
|
46896
|
+
"",
|
|
46897
|
+
"DOCUMENTATION",
|
|
46898
|
+
` ${DOCS_URL}`
|
|
46899
|
+
];
|
|
46900
|
+
}
|
|
46901
|
+
|
|
46902
|
+
// src/repl/help.ts
|
|
46903
|
+
function wrapText2(text, width, indent) {
|
|
46904
|
+
const prefix = " ".repeat(indent);
|
|
46905
|
+
const words = text.split(/\s+/);
|
|
46906
|
+
const lines = [];
|
|
46907
|
+
let currentLine = prefix;
|
|
46908
|
+
for (const word of words) {
|
|
46909
|
+
if (currentLine.length + word.length + 1 > width && currentLine !== prefix) {
|
|
46910
|
+
lines.push(currentLine);
|
|
46911
|
+
currentLine = prefix + word;
|
|
46912
|
+
} else {
|
|
46913
|
+
currentLine += (currentLine === prefix ? "" : " ") + word;
|
|
46914
|
+
}
|
|
46915
|
+
}
|
|
46916
|
+
if (currentLine.trim()) {
|
|
46917
|
+
lines.push(currentLine);
|
|
46918
|
+
}
|
|
46919
|
+
return lines;
|
|
46920
|
+
}
|
|
46921
|
+
function formatRootHelp() {
|
|
46922
|
+
return [
|
|
46923
|
+
"",
|
|
46924
|
+
colorBoldWhite(`${CLI_NAME} - ${CLI_FULL_NAME} v${CLI_VERSION}`),
|
|
46925
|
+
"",
|
|
46926
|
+
"DESCRIPTION",
|
|
46927
|
+
...wrapText2(CLI_DESCRIPTION_LONG, 80, 2),
|
|
46928
|
+
"",
|
|
46929
|
+
"USAGE",
|
|
46930
|
+
` ${CLI_NAME} Enter interactive REPL mode`,
|
|
46931
|
+
` ${CLI_NAME} <domain> <action> Execute command non-interactively`,
|
|
46932
|
+
` ${CLI_NAME} help [topic] Show help for a topic`,
|
|
46933
|
+
"",
|
|
46934
|
+
"EXAMPLES",
|
|
46935
|
+
` ${CLI_NAME} tenant_and_identity list namespace List all namespaces`,
|
|
46936
|
+
` ${CLI_NAME} virtual get http_loadbalancer Get a specific load balancer`,
|
|
46937
|
+
` ${CLI_NAME} dns list List DNS zones`,
|
|
46938
|
+
` ${CLI_NAME} waf list -ns prod List WAF policies in prod`,
|
|
46939
|
+
"",
|
|
46940
|
+
...formatDomainsSection(),
|
|
46941
|
+
"",
|
|
46942
|
+
...formatGlobalFlags(),
|
|
46943
|
+
"",
|
|
46944
|
+
...formatEnvVarsSection(),
|
|
46945
|
+
"",
|
|
46946
|
+
...formatConfigSection(),
|
|
46947
|
+
"",
|
|
46948
|
+
"NAVIGATION (Interactive Mode)",
|
|
46949
|
+
" <domain> Navigate into a domain (e.g., 'dns', 'lb')",
|
|
46950
|
+
" /domain Navigate directly to domain from anywhere",
|
|
46951
|
+
" .. Go up one level",
|
|
46952
|
+
" / Return to root",
|
|
46953
|
+
" context Show current navigation context",
|
|
46954
|
+
"",
|
|
46955
|
+
"BUILTINS",
|
|
46956
|
+
" help Show this help",
|
|
46957
|
+
" domains List all available domains",
|
|
46958
|
+
" clear Clear the screen",
|
|
46959
|
+
" history Show command history",
|
|
46960
|
+
" quit, exit Exit the shell",
|
|
46961
|
+
""
|
|
46962
|
+
];
|
|
46963
|
+
}
|
|
46964
|
+
function formatGlobalFlags() {
|
|
46965
|
+
return [
|
|
46966
|
+
"GLOBAL FLAGS",
|
|
46967
|
+
" -v, --version Show version number",
|
|
46968
|
+
" -h, --help Show this help",
|
|
46969
|
+
" --no-color Disable color output",
|
|
46970
|
+
" -o, --output <fmt> Output format (json, yaml, table)",
|
|
46971
|
+
" -ns, --namespace <ns> Target namespace"
|
|
46972
|
+
];
|
|
46973
|
+
}
|
|
46974
|
+
function formatEnvironmentVariables() {
|
|
46975
|
+
return formatEnvVarsSection();
|
|
46976
|
+
}
|
|
46977
|
+
function formatDomainHelp(domain) {
|
|
46978
|
+
const output = ["", colorBoldWhite(`${domain.displayName}`), ""];
|
|
46979
|
+
output.push(` ${domain.description}`);
|
|
46980
|
+
output.push("");
|
|
46981
|
+
if (domain.category || domain.complexity) {
|
|
46982
|
+
const meta = [];
|
|
46983
|
+
if (domain.category) meta.push(`Category: ${domain.category}`);
|
|
46984
|
+
if (domain.complexity) meta.push(`Complexity: ${domain.complexity}`);
|
|
46985
|
+
output.push(colorDim(` ${meta.join(" | ")}`));
|
|
46986
|
+
output.push("");
|
|
46987
|
+
}
|
|
46988
|
+
output.push("USAGE");
|
|
46989
|
+
output.push(` ${CLI_NAME} ${domain.name} <action> [options]`);
|
|
46990
|
+
output.push("");
|
|
46991
|
+
output.push("ACTIONS");
|
|
46992
|
+
const actionDescriptions2 = {
|
|
46993
|
+
list: "List resources",
|
|
46994
|
+
get: "Get a specific resource by name",
|
|
46995
|
+
create: "Create a new resource",
|
|
46996
|
+
delete: "Delete a resource",
|
|
46997
|
+
replace: "Replace a resource configuration",
|
|
46998
|
+
apply: "Apply configuration from file",
|
|
46999
|
+
status: "Get resource status",
|
|
47000
|
+
patch: "Patch a resource",
|
|
47001
|
+
"add-labels": "Add labels to a resource",
|
|
47002
|
+
"remove-labels": "Remove labels from a resource"
|
|
47003
|
+
};
|
|
47004
|
+
for (const action of validActions) {
|
|
47005
|
+
const desc = actionDescriptions2[action] ?? action;
|
|
47006
|
+
output.push(` ${action.padEnd(16)} ${desc}`);
|
|
47007
|
+
}
|
|
47008
|
+
output.push("");
|
|
47009
|
+
output.push("EXAMPLES");
|
|
47010
|
+
output.push(` ${CLI_NAME} ${domain.name} list`);
|
|
47011
|
+
output.push(` ${CLI_NAME} ${domain.name} get my-resource`);
|
|
47012
|
+
output.push(
|
|
47013
|
+
` ${CLI_NAME} ${domain.name} create my-resource -f config.yaml`
|
|
47014
|
+
);
|
|
47015
|
+
output.push(` ${CLI_NAME} ${domain.name} delete my-resource`);
|
|
47016
|
+
output.push("");
|
|
47017
|
+
if (domain.useCases && domain.useCases.length > 0) {
|
|
47018
|
+
output.push("USE CASES");
|
|
47019
|
+
for (const useCase of domain.useCases.slice(0, 5)) {
|
|
47020
|
+
output.push(` - ${useCase}`);
|
|
47021
|
+
}
|
|
47022
|
+
output.push("");
|
|
47023
|
+
}
|
|
47024
|
+
if (domain.relatedDomains && domain.relatedDomains.length > 0) {
|
|
47025
|
+
output.push("RELATED DOMAINS");
|
|
47026
|
+
output.push(` ${domain.relatedDomains.join(", ")}`);
|
|
47027
|
+
output.push("");
|
|
47028
|
+
}
|
|
47029
|
+
if (domain.aliases && domain.aliases.length > 0) {
|
|
47030
|
+
output.push("ALIASES");
|
|
47031
|
+
output.push(` ${domain.aliases.join(", ")}`);
|
|
47032
|
+
output.push("");
|
|
47033
|
+
}
|
|
47034
|
+
output.push(colorDim(`For global options, run: ${CLI_NAME} --help`));
|
|
47035
|
+
output.push("");
|
|
47036
|
+
return output;
|
|
47037
|
+
}
|
|
47038
|
+
function formatActionHelp(domainName, action) {
|
|
47039
|
+
const domain = getDomainInfo(domainName);
|
|
47040
|
+
const displayDomain = domain?.displayName ?? domainName;
|
|
47041
|
+
const actionDescriptions2 = {
|
|
47042
|
+
list: {
|
|
47043
|
+
desc: "List all resources in the namespace",
|
|
47044
|
+
usage: `${CLI_NAME} ${domainName} list [--limit N] [--label key=value]`
|
|
47045
|
+
},
|
|
47046
|
+
get: {
|
|
47047
|
+
desc: "Get a specific resource by name",
|
|
47048
|
+
usage: `${CLI_NAME} ${domainName} get <name> [-o json|yaml|table]`
|
|
47049
|
+
},
|
|
47050
|
+
create: {
|
|
47051
|
+
desc: "Create a new resource",
|
|
47052
|
+
usage: `${CLI_NAME} ${domainName} create <name> -f <file.yaml>`
|
|
47053
|
+
},
|
|
47054
|
+
delete: {
|
|
47055
|
+
desc: "Delete a resource by name",
|
|
47056
|
+
usage: `${CLI_NAME} ${domainName} delete <name>`
|
|
47057
|
+
},
|
|
47058
|
+
replace: {
|
|
47059
|
+
desc: "Replace an existing resource configuration",
|
|
47060
|
+
usage: `${CLI_NAME} ${domainName} replace <name> -f <file.yaml>`
|
|
47061
|
+
},
|
|
47062
|
+
apply: {
|
|
47063
|
+
desc: "Apply configuration from a file (create or update)",
|
|
47064
|
+
usage: `${CLI_NAME} ${domainName} apply -f <file.yaml>`
|
|
47065
|
+
},
|
|
47066
|
+
status: {
|
|
47067
|
+
desc: "Get the current status of a resource",
|
|
47068
|
+
usage: `${CLI_NAME} ${domainName} status <name>`
|
|
47069
|
+
},
|
|
47070
|
+
patch: {
|
|
47071
|
+
desc: "Patch specific fields of a resource",
|
|
47072
|
+
usage: `${CLI_NAME} ${domainName} patch <name> -f <patch.yaml>`
|
|
47073
|
+
},
|
|
47074
|
+
"add-labels": {
|
|
47075
|
+
desc: "Add labels to a resource",
|
|
47076
|
+
usage: `${CLI_NAME} ${domainName} add-labels <name> key=value`
|
|
47077
|
+
},
|
|
47078
|
+
"remove-labels": {
|
|
47079
|
+
desc: "Remove labels from a resource",
|
|
47080
|
+
usage: `${CLI_NAME} ${domainName} remove-labels <name> key`
|
|
47081
|
+
}
|
|
47082
|
+
};
|
|
47083
|
+
const actionInfo = actionDescriptions2[action] ?? {
|
|
47084
|
+
desc: `Execute ${action} operation`,
|
|
47085
|
+
usage: `${CLI_NAME} ${domainName} ${action} [options]`
|
|
47086
|
+
};
|
|
47087
|
+
return [
|
|
47088
|
+
"",
|
|
47089
|
+
colorBoldWhite(`${displayDomain} - ${action}`),
|
|
47090
|
+
"",
|
|
47091
|
+
` ${actionInfo.desc}`,
|
|
47092
|
+
"",
|
|
47093
|
+
"USAGE",
|
|
47094
|
+
` ${actionInfo.usage}`,
|
|
47095
|
+
"",
|
|
47096
|
+
"OPTIONS",
|
|
47097
|
+
" -n, --name <name> Resource name",
|
|
47098
|
+
" -ns, --namespace <ns> Target namespace",
|
|
47099
|
+
" -o, --output <fmt> Output format (json, yaml, table)",
|
|
47100
|
+
" -f, --file <path> Configuration file",
|
|
47101
|
+
"",
|
|
47102
|
+
colorDim(`For domain help, run: ${CLI_NAME} ${domainName} --help`),
|
|
47103
|
+
""
|
|
47104
|
+
];
|
|
47105
|
+
}
|
|
47106
|
+
function formatTopicHelp(topic) {
|
|
47107
|
+
const lowerTopic = topic.toLowerCase();
|
|
47108
|
+
const domainInfo = getDomainInfo(lowerTopic);
|
|
47109
|
+
if (domainInfo) {
|
|
47110
|
+
return formatDomainHelp(domainInfo);
|
|
47111
|
+
}
|
|
47112
|
+
switch (lowerTopic) {
|
|
47113
|
+
case "domains":
|
|
47114
|
+
return formatDomainsHelp();
|
|
47115
|
+
case "actions":
|
|
47116
|
+
return formatActionsHelp();
|
|
47117
|
+
case "navigation":
|
|
47118
|
+
case "nav":
|
|
47119
|
+
return formatNavigationHelp();
|
|
47120
|
+
case "env":
|
|
47121
|
+
case "environment":
|
|
47122
|
+
return ["", ...formatEnvironmentVariables(), ""];
|
|
47123
|
+
case "flags":
|
|
47124
|
+
return ["", ...formatGlobalFlags(), ""];
|
|
47125
|
+
default:
|
|
47126
|
+
return [
|
|
47127
|
+
"",
|
|
47128
|
+
`Unknown help topic: ${topic}`,
|
|
47129
|
+
"",
|
|
47130
|
+
"Available topics:",
|
|
47131
|
+
" domains List all available domains",
|
|
47132
|
+
" actions List available actions",
|
|
47133
|
+
" navigation Navigation commands",
|
|
47134
|
+
" env Environment variables",
|
|
47135
|
+
" flags Global flags",
|
|
47136
|
+
" <domain> Help for a specific domain (e.g., 'help dns')",
|
|
47137
|
+
""
|
|
47138
|
+
];
|
|
47139
|
+
}
|
|
47140
|
+
}
|
|
47141
|
+
function formatDomainsHelp() {
|
|
47142
|
+
const output = ["", colorBoldWhite("Available Domains"), ""];
|
|
47143
|
+
const categories = /* @__PURE__ */ new Map();
|
|
47144
|
+
for (const domain of domainRegistry.values()) {
|
|
47145
|
+
const category = domain.category ?? "Other";
|
|
47146
|
+
if (!categories.has(category)) {
|
|
47147
|
+
categories.set(category, []);
|
|
47148
|
+
}
|
|
47149
|
+
categories.get(category)?.push(domain);
|
|
47150
|
+
}
|
|
47151
|
+
const sortedCategories = Array.from(categories.keys()).sort();
|
|
47152
|
+
for (const category of sortedCategories) {
|
|
47153
|
+
const domains = categories.get(category) ?? [];
|
|
47154
|
+
output.push(colorBoldWhite(` ${category}`));
|
|
47155
|
+
for (const domain of domains.sort(
|
|
47156
|
+
(a, b) => a.name.localeCompare(b.name)
|
|
47157
|
+
)) {
|
|
47158
|
+
const aliases = domain.aliases.length > 0 ? colorDim(` (${domain.aliases.join(", ")})`) : "";
|
|
47159
|
+
output.push(
|
|
47160
|
+
` ${domain.name.padEnd(24)} ${domain.descriptionShort}`
|
|
47161
|
+
);
|
|
47162
|
+
if (aliases) {
|
|
47163
|
+
output.push(` ${"".padEnd(24)} Aliases:${aliases}`);
|
|
47164
|
+
}
|
|
47165
|
+
}
|
|
47166
|
+
output.push("");
|
|
47167
|
+
}
|
|
47168
|
+
return output;
|
|
47169
|
+
}
|
|
47170
|
+
function formatActionsHelp() {
|
|
47171
|
+
return [
|
|
47172
|
+
"",
|
|
47173
|
+
colorBoldWhite("Available Actions"),
|
|
47174
|
+
"",
|
|
47175
|
+
" list List all resources in the namespace",
|
|
47176
|
+
" get Get a specific resource by name",
|
|
47177
|
+
" create Create a new resource from a file",
|
|
47178
|
+
" delete Delete a resource by name",
|
|
47179
|
+
" replace Replace a resource configuration",
|
|
47180
|
+
" apply Apply configuration (create or update)",
|
|
47181
|
+
" status Get resource status",
|
|
47182
|
+
" patch Patch specific fields of a resource",
|
|
47183
|
+
" add-labels Add labels to a resource",
|
|
47184
|
+
" remove-labels Remove labels from a resource",
|
|
47185
|
+
"",
|
|
47186
|
+
"USAGE",
|
|
47187
|
+
` ${CLI_NAME} <domain> <action> [options]`,
|
|
47188
|
+
"",
|
|
47189
|
+
"EXAMPLES",
|
|
47190
|
+
` ${CLI_NAME} dns list`,
|
|
47191
|
+
` ${CLI_NAME} lb get my-loadbalancer`,
|
|
47192
|
+
` ${CLI_NAME} waf create my-policy -f policy.yaml`,
|
|
47193
|
+
""
|
|
47194
|
+
];
|
|
47195
|
+
}
|
|
47196
|
+
function formatNavigationHelp() {
|
|
47197
|
+
return [
|
|
47198
|
+
"",
|
|
47199
|
+
colorBoldWhite("Navigation Commands"),
|
|
47200
|
+
"",
|
|
47201
|
+
" <domain> Navigate into a domain context",
|
|
47202
|
+
" /<domain> Navigate directly to domain from anywhere",
|
|
47203
|
+
" .. Go up one level in context",
|
|
47204
|
+
" / Return to root context",
|
|
47205
|
+
" back Go up one level (same as ..)",
|
|
47206
|
+
" root Return to root (same as /)",
|
|
47207
|
+
"",
|
|
47208
|
+
"CONTEXT DISPLAY",
|
|
47209
|
+
" context Show current navigation context",
|
|
47210
|
+
" ctx Alias for context",
|
|
47211
|
+
"",
|
|
47212
|
+
"EXAMPLES",
|
|
47213
|
+
" xcsh> dns # Enter dns domain",
|
|
47214
|
+
" dns> list # Execute list in dns context",
|
|
47215
|
+
" dns> .. # Return to root",
|
|
47216
|
+
" xcsh> /waf # Jump directly to waf",
|
|
47217
|
+
" waf> /dns # Jump from waf to dns",
|
|
47218
|
+
""
|
|
47219
|
+
];
|
|
47220
|
+
}
|
|
47221
|
+
function formatDomainsSection() {
|
|
47222
|
+
const output = ["DOMAINS"];
|
|
47223
|
+
const domains = Array.from(domainRegistry.values()).sort(
|
|
47224
|
+
(a, b) => a.name.localeCompare(b.name)
|
|
47225
|
+
);
|
|
47226
|
+
const maxNameLen = Math.max(...domains.map((d) => d.name.length));
|
|
47227
|
+
for (const domain of domains) {
|
|
47228
|
+
const padding = " ".repeat(maxNameLen - domain.name.length + 2);
|
|
47229
|
+
output.push(` ${domain.name}${padding}${domain.descriptionShort}`);
|
|
47230
|
+
}
|
|
47231
|
+
return output;
|
|
47232
|
+
}
|
|
47233
|
+
function formatCustomDomainHelp(domain) {
|
|
47234
|
+
const output = ["", colorBoldWhite(domain.name), ""];
|
|
47235
|
+
output.push("DESCRIPTION");
|
|
47236
|
+
output.push(...wrapText2(domain.description, 80, 2));
|
|
47237
|
+
output.push("");
|
|
47238
|
+
output.push("USAGE");
|
|
47239
|
+
output.push(` ${CLI_NAME} ${domain.name} <command> [options]`);
|
|
47240
|
+
output.push("");
|
|
47241
|
+
if (domain.subcommands.size > 0) {
|
|
47242
|
+
output.push("SUBCOMMANDS");
|
|
47243
|
+
for (const [name, group] of domain.subcommands) {
|
|
47244
|
+
output.push(` ${name.padEnd(16)} ${group.descriptionShort}`);
|
|
47245
|
+
}
|
|
47246
|
+
output.push("");
|
|
47247
|
+
}
|
|
47248
|
+
if (domain.commands.size > 0) {
|
|
47249
|
+
output.push("COMMANDS");
|
|
47250
|
+
for (const [name, cmd] of domain.commands) {
|
|
47251
|
+
output.push(` ${name.padEnd(16)} ${cmd.descriptionShort}`);
|
|
47252
|
+
}
|
|
47253
|
+
output.push("");
|
|
47254
|
+
}
|
|
47255
|
+
output.push(colorDim(`For global options, run: ${CLI_NAME} --help`));
|
|
47256
|
+
output.push("");
|
|
47257
|
+
return output;
|
|
47258
|
+
}
|
|
47259
|
+
function formatSubcommandHelp(domainName, subcommand) {
|
|
47260
|
+
const output = [
|
|
47261
|
+
"",
|
|
47262
|
+
colorBoldWhite(`${domainName} ${subcommand.name}`),
|
|
47263
|
+
""
|
|
47264
|
+
];
|
|
47265
|
+
output.push("DESCRIPTION");
|
|
47266
|
+
output.push(...wrapText2(subcommand.description, 80, 2));
|
|
47267
|
+
output.push("");
|
|
47268
|
+
output.push("USAGE");
|
|
47269
|
+
output.push(
|
|
47270
|
+
` ${CLI_NAME} ${domainName} ${subcommand.name} <command> [options]`
|
|
47271
|
+
);
|
|
47272
|
+
output.push("");
|
|
47273
|
+
if (subcommand.commands.size > 0) {
|
|
47274
|
+
output.push("COMMANDS");
|
|
47275
|
+
for (const [name, cmd] of subcommand.commands) {
|
|
47276
|
+
const usage = cmd.usage ? ` ${cmd.usage}` : "";
|
|
47277
|
+
output.push(
|
|
47278
|
+
` ${name}${usage.padEnd(16 - name.length)} ${cmd.descriptionShort}`
|
|
47279
|
+
);
|
|
47280
|
+
}
|
|
47281
|
+
output.push("");
|
|
47282
|
+
}
|
|
47283
|
+
output.push(
|
|
47284
|
+
colorDim(`For domain help, run: ${CLI_NAME} ${domainName} --help`)
|
|
47285
|
+
);
|
|
47286
|
+
output.push("");
|
|
47287
|
+
return output;
|
|
47288
|
+
}
|
|
47289
|
+
|
|
46846
47290
|
// src/domains/registry.ts
|
|
46847
47291
|
var DomainRegistry = class {
|
|
46848
47292
|
domains = /* @__PURE__ */ new Map();
|
|
@@ -47024,45 +47468,24 @@ var DomainRegistry = class {
|
|
|
47024
47468
|
return suggestions;
|
|
47025
47469
|
}
|
|
47026
47470
|
/**
|
|
47027
|
-
* Show help for a domain
|
|
47471
|
+
* Show help for a domain using the unified help formatter.
|
|
47472
|
+
* This ensures consistent professional formatting across all domains.
|
|
47028
47473
|
*/
|
|
47029
47474
|
showDomainHelp(domain) {
|
|
47030
|
-
const output = [`${domain.name} - ${domain.description}`, ``];
|
|
47031
|
-
if (domain.subcommands.size > 0) {
|
|
47032
|
-
output.push(`Subcommands:`);
|
|
47033
|
-
for (const [name, group] of domain.subcommands) {
|
|
47034
|
-
output.push(` ${name} ${group.description}`);
|
|
47035
|
-
}
|
|
47036
|
-
output.push(``);
|
|
47037
|
-
}
|
|
47038
|
-
if (domain.commands.size > 0) {
|
|
47039
|
-
output.push(`Commands:`);
|
|
47040
|
-
for (const [name, cmd] of domain.commands) {
|
|
47041
|
-
output.push(` ${name} ${cmd.description}`);
|
|
47042
|
-
}
|
|
47043
|
-
}
|
|
47044
47475
|
return {
|
|
47045
|
-
output,
|
|
47476
|
+
output: formatCustomDomainHelp(domain),
|
|
47046
47477
|
shouldExit: false,
|
|
47047
47478
|
shouldClear: false,
|
|
47048
47479
|
contextChanged: false
|
|
47049
47480
|
};
|
|
47050
47481
|
}
|
|
47051
47482
|
/**
|
|
47052
|
-
* Show help for a subcommand group
|
|
47483
|
+
* Show help for a subcommand group using the unified help formatter.
|
|
47484
|
+
* This ensures consistent professional formatting across all subcommands.
|
|
47053
47485
|
*/
|
|
47054
47486
|
showSubcommandHelp(domain, subgroup) {
|
|
47055
|
-
const output = [
|
|
47056
|
-
`${domain.name} ${subgroup.name} - ${subgroup.description}`,
|
|
47057
|
-
``,
|
|
47058
|
-
`Commands:`
|
|
47059
|
-
];
|
|
47060
|
-
for (const [name, cmd] of subgroup.commands) {
|
|
47061
|
-
const usage = cmd.usage ? ` ${cmd.usage}` : "";
|
|
47062
|
-
output.push(` ${name}${usage} ${cmd.description}`);
|
|
47063
|
-
}
|
|
47064
47487
|
return {
|
|
47065
|
-
output,
|
|
47488
|
+
output: formatSubcommandHelp(domain.name, subgroup),
|
|
47066
47489
|
shouldExit: false,
|
|
47067
47490
|
shouldClear: false,
|
|
47068
47491
|
contextChanged: false
|
|
@@ -47545,74 +47968,18 @@ var listCommand2 = {
|
|
|
47545
47968
|
return errorResult(`Failed to list namespaces: ${message}`);
|
|
47546
47969
|
}
|
|
47547
47970
|
}
|
|
47548
|
-
};
|
|
47549
|
-
var contextSubcommands = {
|
|
47550
|
-
name: "context",
|
|
47551
|
-
description: "Manage default namespace context for scoping operations. Set, display, and list namespaces to control which namespace is used when no explicit namespace is specified in commands.",
|
|
47552
|
-
descriptionShort: "Manage default namespace context",
|
|
47553
|
-
descriptionMedium: "Set, display, and list namespaces for scoping operations without explicit namespace flags.",
|
|
47554
|
-
commands: /* @__PURE__ */ new Map([
|
|
47555
|
-
["show", showCommand2],
|
|
47556
|
-
["set", setCommand],
|
|
47557
|
-
["list", listCommand2]
|
|
47558
|
-
])
|
|
47559
|
-
};
|
|
47560
|
-
|
|
47561
|
-
// src/config/envvars.ts
|
|
47562
|
-
var EnvVarRegistry = [
|
|
47563
|
-
{
|
|
47564
|
-
name: `${ENV_PREFIX}_API_URL`,
|
|
47565
|
-
description: "API endpoint URL",
|
|
47566
|
-
relatedFlag: "",
|
|
47567
|
-
required: true
|
|
47568
|
-
},
|
|
47569
|
-
{
|
|
47570
|
-
name: `${ENV_PREFIX}_API_TOKEN`,
|
|
47571
|
-
description: "API authentication token",
|
|
47572
|
-
relatedFlag: "",
|
|
47573
|
-
required: true
|
|
47574
|
-
},
|
|
47575
|
-
{
|
|
47576
|
-
name: `${ENV_PREFIX}_NAMESPACE`,
|
|
47577
|
-
description: "Default namespace",
|
|
47578
|
-
relatedFlag: "-ns"
|
|
47579
|
-
},
|
|
47580
|
-
{
|
|
47581
|
-
name: `${ENV_PREFIX}_OUTPUT_FORMAT`,
|
|
47582
|
-
description: "Output format (json, yaml, table)",
|
|
47583
|
-
relatedFlag: "-o"
|
|
47584
|
-
},
|
|
47585
|
-
{
|
|
47586
|
-
name: `${ENV_PREFIX}_LOGO`,
|
|
47587
|
-
description: "Logo display mode (auto, image, ascii, both, none)",
|
|
47588
|
-
relatedFlag: "--logo"
|
|
47589
|
-
},
|
|
47590
|
-
{
|
|
47591
|
-
name: "NO_COLOR",
|
|
47592
|
-
description: "Disable color output",
|
|
47593
|
-
relatedFlag: "--no-color"
|
|
47594
|
-
}
|
|
47595
|
-
];
|
|
47596
|
-
function formatEnvVarsSection() {
|
|
47597
|
-
const maxLen = Math.max(...EnvVarRegistry.map((e) => e.name.length));
|
|
47598
|
-
const lines = ["ENVIRONMENT VARIABLES"];
|
|
47599
|
-
for (const env3 of EnvVarRegistry) {
|
|
47600
|
-
const padding = " ".repeat(maxLen - env3.name.length + 3);
|
|
47601
|
-
const flagNote = env3.relatedFlag ? ` [${env3.relatedFlag}]` : "";
|
|
47602
|
-
lines.push(` ${env3.name}${padding}${env3.description}${flagNote}`);
|
|
47603
|
-
}
|
|
47604
|
-
return lines;
|
|
47605
|
-
}
|
|
47606
|
-
function formatConfigSection() {
|
|
47607
|
-
return [
|
|
47608
|
-
"CONFIGURATION",
|
|
47609
|
-
` Config file: ~/${CONFIG_FILE_NAME}`,
|
|
47610
|
-
" Priority: CLI flags > environment variables > config file > defaults",
|
|
47611
|
-
"",
|
|
47612
|
-
"DOCUMENTATION",
|
|
47613
|
-
` ${DOCS_URL}`
|
|
47614
|
-
];
|
|
47615
|
-
}
|
|
47971
|
+
};
|
|
47972
|
+
var contextSubcommands = {
|
|
47973
|
+
name: "context",
|
|
47974
|
+
description: "Manage default namespace context for scoping operations. Set, display, and list namespaces to control which namespace is used when no explicit namespace is specified in commands.",
|
|
47975
|
+
descriptionShort: "Manage default namespace context",
|
|
47976
|
+
descriptionMedium: "Set, display, and list namespaces for scoping operations without explicit namespace flags.",
|
|
47977
|
+
commands: /* @__PURE__ */ new Map([
|
|
47978
|
+
["show", showCommand2],
|
|
47979
|
+
["set", setCommand],
|
|
47980
|
+
["list", listCommand2]
|
|
47981
|
+
])
|
|
47982
|
+
};
|
|
47616
47983
|
|
|
47617
47984
|
// src/config/settings.ts
|
|
47618
47985
|
var import_yaml2 = __toESM(require_dist(), 1);
|
|
@@ -49165,7 +49532,7 @@ _xcsh_completions() {
|
|
|
49165
49532
|
local commands="${domainNames} ${allAliases.join(" ")} help quit exit clear history"
|
|
49166
49533
|
local actions="${actions}"
|
|
49167
49534
|
local builtins="help quit exit clear history context ctx"
|
|
49168
|
-
local global_flags="--help -h --version -v --
|
|
49535
|
+
local global_flags="--help -h --version -v --no-color --output -o --namespace -ns"
|
|
49169
49536
|
|
|
49170
49537
|
# Handle completion based on position
|
|
49171
49538
|
case \${cword} in
|
|
@@ -49247,7 +49614,6 @@ _xcsh() {
|
|
|
49247
49614
|
global_opts=(
|
|
49248
49615
|
'(-h --help)'{-h,--help}'[Show help information]'
|
|
49249
49616
|
'(-v --version)'{-v,--version}'[Show version number]'
|
|
49250
|
-
'(-i --interactive)'{-i,--interactive}'[Force interactive mode]'
|
|
49251
49617
|
'--no-color[Disable color output]'
|
|
49252
49618
|
'(-o --output)'{-o,--output}'[Output format]:format:(json yaml table)'
|
|
49253
49619
|
'(-ns --namespace)'{-ns,--namespace}'[Namespace]:namespace:_xcsh_namespaces'
|
|
@@ -49361,7 +49727,6 @@ complete -c xcsh -f
|
|
|
49361
49727
|
# Global options
|
|
49362
49728
|
complete -c xcsh -s h -l help -d 'Show help information'
|
|
49363
49729
|
complete -c xcsh -s v -l version -d 'Show version number'
|
|
49364
|
-
complete -c xcsh -s i -l interactive -d 'Force interactive mode'
|
|
49365
49730
|
complete -c xcsh -l no-color -d 'Disable color output'
|
|
49366
49731
|
complete -c xcsh -s o -l output -d 'Output format' -xa 'json yaml table'
|
|
49367
49732
|
complete -c xcsh -l namespace -s ns -d 'Namespace' -xa 'default system shared'
|
|
@@ -50537,574 +50902,240 @@ function useCompletion(options) {
|
|
|
50537
50902
|
}, [isShowing, suggestions.length]);
|
|
50538
50903
|
const navigateDown = (0, import_react27.useCallback)(() => {
|
|
50539
50904
|
if (!isShowing || suggestions.length === 0) return;
|
|
50540
|
-
setSelectedIndex(
|
|
50541
|
-
(current) => current < suggestions.length - 1 ? current + 1 : 0
|
|
50542
|
-
);
|
|
50543
|
-
}, [isShowing, suggestions.length]);
|
|
50544
|
-
const selectCurrent = (0, import_react27.useCallback)(() => {
|
|
50545
|
-
if (!isShowing || suggestions.length === 0) return null;
|
|
50546
|
-
const selected = suggestions.at(selectedIndex);
|
|
50547
|
-
hide();
|
|
50548
|
-
return selected ?? null;
|
|
50549
|
-
}, [isShowing, suggestions, selectedIndex, hide]);
|
|
50550
|
-
return {
|
|
50551
|
-
suggestions,
|
|
50552
|
-
selectedIndex,
|
|
50553
|
-
isShowing,
|
|
50554
|
-
triggerCompletion,
|
|
50555
|
-
navigateUp,
|
|
50556
|
-
navigateDown,
|
|
50557
|
-
selectCurrent,
|
|
50558
|
-
hide,
|
|
50559
|
-
filterSuggestions
|
|
50560
|
-
};
|
|
50561
|
-
}
|
|
50562
|
-
|
|
50563
|
-
// src/output/formatter.ts
|
|
50564
|
-
var import_yaml3 = __toESM(require_dist(), 1);
|
|
50565
|
-
function formatOutput(data, format = "yaml") {
|
|
50566
|
-
if (format === "none") {
|
|
50567
|
-
return "";
|
|
50568
|
-
}
|
|
50569
|
-
switch (format) {
|
|
50570
|
-
case "json":
|
|
50571
|
-
return formatJSON(data);
|
|
50572
|
-
case "yaml":
|
|
50573
|
-
return formatYAML(data);
|
|
50574
|
-
case "table":
|
|
50575
|
-
case "text":
|
|
50576
|
-
return formatTable(data);
|
|
50577
|
-
case "tsv":
|
|
50578
|
-
return formatTSV(data);
|
|
50579
|
-
default:
|
|
50580
|
-
return formatYAML(data);
|
|
50581
|
-
}
|
|
50582
|
-
}
|
|
50583
|
-
function formatJSON(data) {
|
|
50584
|
-
return JSON.stringify(data, null, 2);
|
|
50585
|
-
}
|
|
50586
|
-
function formatYAML(data) {
|
|
50587
|
-
return import_yaml3.default.stringify(data, { indent: 2 });
|
|
50588
|
-
}
|
|
50589
|
-
function extractItems(data) {
|
|
50590
|
-
if (data && typeof data === "object" && "items" in data) {
|
|
50591
|
-
const items = data.items;
|
|
50592
|
-
if (Array.isArray(items)) {
|
|
50593
|
-
return items.filter(
|
|
50594
|
-
(item) => item !== null && typeof item === "object"
|
|
50595
|
-
);
|
|
50596
|
-
}
|
|
50597
|
-
}
|
|
50598
|
-
if (Array.isArray(data)) {
|
|
50599
|
-
return data.filter(
|
|
50600
|
-
(item) => item !== null && typeof item === "object"
|
|
50601
|
-
);
|
|
50602
|
-
}
|
|
50603
|
-
if (data && typeof data === "object") {
|
|
50604
|
-
return [data];
|
|
50605
|
-
}
|
|
50606
|
-
return [];
|
|
50607
|
-
}
|
|
50608
|
-
function getStringField(obj, key) {
|
|
50609
|
-
const value = obj[key];
|
|
50610
|
-
if (typeof value === "string") {
|
|
50611
|
-
return value;
|
|
50612
|
-
}
|
|
50613
|
-
if (value !== null && value !== void 0) {
|
|
50614
|
-
return String(value);
|
|
50615
|
-
}
|
|
50616
|
-
return "";
|
|
50617
|
-
}
|
|
50618
|
-
function formatLabels(obj) {
|
|
50619
|
-
const labels = obj["labels"];
|
|
50620
|
-
if (!labels || typeof labels !== "object") {
|
|
50621
|
-
return "";
|
|
50622
|
-
}
|
|
50623
|
-
const labelMap = labels;
|
|
50624
|
-
const entries = Object.entries(labelMap).sort(([a], [b]) => a.localeCompare(b)).map(([k, v]) => `${k}:${v}`);
|
|
50625
|
-
if (entries.length === 0) {
|
|
50626
|
-
return "";
|
|
50627
|
-
}
|
|
50628
|
-
return `map[${entries.join(" ")}]`;
|
|
50629
|
-
}
|
|
50630
|
-
function wrapText2(text, maxWidth) {
|
|
50631
|
-
if (text.length <= maxWidth) {
|
|
50632
|
-
return [text];
|
|
50633
|
-
}
|
|
50634
|
-
const lines = [];
|
|
50635
|
-
let remaining = text;
|
|
50636
|
-
while (remaining.length > 0) {
|
|
50637
|
-
if (remaining.length <= maxWidth) {
|
|
50638
|
-
lines.push(remaining);
|
|
50639
|
-
break;
|
|
50640
|
-
}
|
|
50641
|
-
let breakPoint = maxWidth;
|
|
50642
|
-
for (let i = maxWidth - 1; i > 0; i--) {
|
|
50643
|
-
if (remaining[i] === " ") {
|
|
50644
|
-
breakPoint = i;
|
|
50645
|
-
break;
|
|
50646
|
-
}
|
|
50647
|
-
}
|
|
50648
|
-
lines.push(remaining.slice(0, breakPoint));
|
|
50649
|
-
remaining = remaining.slice(breakPoint).trimStart();
|
|
50650
|
-
}
|
|
50651
|
-
return lines;
|
|
50652
|
-
}
|
|
50653
|
-
function formatTable(data) {
|
|
50654
|
-
const items = extractItems(data);
|
|
50655
|
-
if (items.length === 0) {
|
|
50656
|
-
return "";
|
|
50657
|
-
}
|
|
50658
|
-
const headers = ["NAMESPACE", "NAME", "LABELS"];
|
|
50659
|
-
const widths = [9, 27, 30];
|
|
50660
|
-
const rows = [];
|
|
50661
|
-
for (const item of items) {
|
|
50662
|
-
const row = [
|
|
50663
|
-
getStringField(item, "namespace") || "<None>",
|
|
50664
|
-
getStringField(item, "name") || "<None>",
|
|
50665
|
-
formatLabels(item) || "<None>"
|
|
50666
|
-
];
|
|
50667
|
-
const wrappedCells = row.map((cell, i) => wrapText2(cell, widths[i]));
|
|
50668
|
-
const maxLines = Math.max(...wrappedCells.map((c) => c.length));
|
|
50669
|
-
const wrappedRows = [];
|
|
50670
|
-
for (let line = 0; line < maxLines; line++) {
|
|
50671
|
-
wrappedRows.push(wrappedCells.map((c) => c[line] ?? ""));
|
|
50672
|
-
}
|
|
50673
|
-
rows.push(wrappedRows);
|
|
50674
|
-
}
|
|
50675
|
-
const lines = [];
|
|
50676
|
-
const boxLine = "+" + widths.map((w) => "-".repeat(w + 2)).join("+") + "+";
|
|
50677
|
-
lines.push(boxLine);
|
|
50678
|
-
lines.push(
|
|
50679
|
-
"|" + headers.map((h, i) => {
|
|
50680
|
-
const padding = widths[i] - h.length;
|
|
50681
|
-
const leftPad = Math.floor(padding / 2);
|
|
50682
|
-
const rightPad = padding - leftPad;
|
|
50683
|
-
return " " + " ".repeat(leftPad) + h + " ".repeat(rightPad) + " ";
|
|
50684
|
-
}).join("|") + "|"
|
|
50685
|
-
);
|
|
50686
|
-
lines.push(boxLine);
|
|
50687
|
-
for (const wrappedRows of rows) {
|
|
50688
|
-
for (const row of wrappedRows) {
|
|
50689
|
-
lines.push(
|
|
50690
|
-
"|" + row.map((cell, i) => {
|
|
50691
|
-
const padding = widths[i] - cell.length;
|
|
50692
|
-
return " " + cell + " ".repeat(padding) + " ";
|
|
50693
|
-
}).join("|") + "|"
|
|
50694
|
-
);
|
|
50695
|
-
}
|
|
50696
|
-
lines.push(boxLine);
|
|
50697
|
-
}
|
|
50698
|
-
return lines.join("\n");
|
|
50699
|
-
}
|
|
50700
|
-
function formatTSV(data) {
|
|
50701
|
-
const items = extractItems(data);
|
|
50702
|
-
if (items.length === 0) {
|
|
50703
|
-
return "";
|
|
50704
|
-
}
|
|
50705
|
-
const allKeys = /* @__PURE__ */ new Set();
|
|
50706
|
-
for (const item of items) {
|
|
50707
|
-
Object.keys(item).forEach((k) => allKeys.add(k));
|
|
50708
|
-
}
|
|
50709
|
-
const priority = ["name", "namespace", "status", "created", "modified"];
|
|
50710
|
-
const headers = [
|
|
50711
|
-
...priority.filter((p) => allKeys.has(p)),
|
|
50712
|
-
...[...allKeys].filter((k) => !priority.includes(k)).sort()
|
|
50713
|
-
];
|
|
50714
|
-
const lines = [];
|
|
50715
|
-
for (const item of items) {
|
|
50716
|
-
const values = headers.map((h) => {
|
|
50717
|
-
const val = item[h];
|
|
50718
|
-
if (val === null || val === void 0) return "";
|
|
50719
|
-
if (typeof val === "object") return JSON.stringify(val);
|
|
50720
|
-
return String(val);
|
|
50721
|
-
});
|
|
50722
|
-
lines.push(values.join(" "));
|
|
50723
|
-
}
|
|
50724
|
-
return lines.join("\n");
|
|
50725
|
-
}
|
|
50726
|
-
function formatAPIError(statusCode, body, operation) {
|
|
50727
|
-
const lines = [];
|
|
50728
|
-
lines.push(`ERROR: ${operation} failed (HTTP ${statusCode})`);
|
|
50729
|
-
if (body && typeof body === "object") {
|
|
50730
|
-
const errResp = body;
|
|
50731
|
-
if (errResp.message) {
|
|
50732
|
-
lines.push(` Message: ${errResp.message}`);
|
|
50733
|
-
}
|
|
50734
|
-
if (errResp.code) {
|
|
50735
|
-
lines.push(` Code: ${errResp.code}`);
|
|
50736
|
-
}
|
|
50737
|
-
if (errResp.details) {
|
|
50738
|
-
lines.push(` Details: ${errResp.details}`);
|
|
50739
|
-
}
|
|
50740
|
-
}
|
|
50741
|
-
switch (statusCode) {
|
|
50742
|
-
case 401:
|
|
50743
|
-
lines.push(
|
|
50744
|
-
"\nHint: Authentication failed. Check your credentials with 'login profile show'"
|
|
50745
|
-
);
|
|
50746
|
-
break;
|
|
50747
|
-
case 403:
|
|
50748
|
-
lines.push(
|
|
50749
|
-
"\nHint: Permission denied. You may not have access to this resource."
|
|
50750
|
-
);
|
|
50751
|
-
break;
|
|
50752
|
-
case 404:
|
|
50753
|
-
lines.push(
|
|
50754
|
-
"\nHint: Resource not found. Verify the name and namespace are correct."
|
|
50755
|
-
);
|
|
50756
|
-
break;
|
|
50757
|
-
case 409:
|
|
50758
|
-
lines.push(
|
|
50759
|
-
"\nHint: Conflict - resource may already exist or be in a conflicting state."
|
|
50760
|
-
);
|
|
50761
|
-
break;
|
|
50762
|
-
case 429:
|
|
50763
|
-
lines.push("\nHint: Rate limited. Please wait and try again.");
|
|
50764
|
-
break;
|
|
50765
|
-
case 500:
|
|
50766
|
-
case 502:
|
|
50767
|
-
case 503:
|
|
50768
|
-
lines.push(
|
|
50769
|
-
"\nHint: Server error. Please try again later or contact support."
|
|
50770
|
-
);
|
|
50771
|
-
break;
|
|
50772
|
-
}
|
|
50773
|
-
return lines.join("\n");
|
|
50905
|
+
setSelectedIndex(
|
|
50906
|
+
(current) => current < suggestions.length - 1 ? current + 1 : 0
|
|
50907
|
+
);
|
|
50908
|
+
}, [isShowing, suggestions.length]);
|
|
50909
|
+
const selectCurrent = (0, import_react27.useCallback)(() => {
|
|
50910
|
+
if (!isShowing || suggestions.length === 0) return null;
|
|
50911
|
+
const selected = suggestions.at(selectedIndex);
|
|
50912
|
+
hide();
|
|
50913
|
+
return selected ?? null;
|
|
50914
|
+
}, [isShowing, suggestions, selectedIndex, hide]);
|
|
50915
|
+
return {
|
|
50916
|
+
suggestions,
|
|
50917
|
+
selectedIndex,
|
|
50918
|
+
isShowing,
|
|
50919
|
+
triggerCompletion,
|
|
50920
|
+
navigateUp,
|
|
50921
|
+
navigateDown,
|
|
50922
|
+
selectCurrent,
|
|
50923
|
+
hide,
|
|
50924
|
+
filterSuggestions
|
|
50925
|
+
};
|
|
50774
50926
|
}
|
|
50775
50927
|
|
|
50776
|
-
// src/
|
|
50777
|
-
|
|
50778
|
-
|
|
50779
|
-
|
|
50780
|
-
|
|
50781
|
-
let currentLine = prefix;
|
|
50782
|
-
for (const word of words) {
|
|
50783
|
-
if (currentLine.length + word.length + 1 > width && currentLine !== prefix) {
|
|
50784
|
-
lines.push(currentLine);
|
|
50785
|
-
currentLine = prefix + word;
|
|
50786
|
-
} else {
|
|
50787
|
-
currentLine += (currentLine === prefix ? "" : " ") + word;
|
|
50788
|
-
}
|
|
50928
|
+
// src/output/formatter.ts
|
|
50929
|
+
var import_yaml3 = __toESM(require_dist(), 1);
|
|
50930
|
+
function formatOutput(data, format = "yaml") {
|
|
50931
|
+
if (format === "none") {
|
|
50932
|
+
return "";
|
|
50789
50933
|
}
|
|
50790
|
-
|
|
50791
|
-
|
|
50934
|
+
switch (format) {
|
|
50935
|
+
case "json":
|
|
50936
|
+
return formatJSON(data);
|
|
50937
|
+
case "yaml":
|
|
50938
|
+
return formatYAML(data);
|
|
50939
|
+
case "table":
|
|
50940
|
+
case "text":
|
|
50941
|
+
return formatTable(data);
|
|
50942
|
+
case "tsv":
|
|
50943
|
+
return formatTSV(data);
|
|
50944
|
+
default:
|
|
50945
|
+
return formatYAML(data);
|
|
50792
50946
|
}
|
|
50793
|
-
return lines;
|
|
50794
|
-
}
|
|
50795
|
-
function formatRootHelp() {
|
|
50796
|
-
return [
|
|
50797
|
-
"",
|
|
50798
|
-
colorBoldWhite(`${CLI_NAME} - ${CLI_FULL_NAME} v${CLI_VERSION}`),
|
|
50799
|
-
"",
|
|
50800
|
-
"DESCRIPTION",
|
|
50801
|
-
...wrapText3(CLI_DESCRIPTION_LONG, 80, 2),
|
|
50802
|
-
"",
|
|
50803
|
-
"USAGE",
|
|
50804
|
-
` ${CLI_NAME} Enter interactive REPL mode`,
|
|
50805
|
-
` ${CLI_NAME} <domain> <action> Execute command non-interactively`,
|
|
50806
|
-
` ${CLI_NAME} help [topic] Show help for a topic`,
|
|
50807
|
-
"",
|
|
50808
|
-
"EXAMPLES",
|
|
50809
|
-
` ${CLI_NAME} tenant_and_identity list namespace List all namespaces`,
|
|
50810
|
-
` ${CLI_NAME} virtual get http_loadbalancer Get a specific load balancer`,
|
|
50811
|
-
` ${CLI_NAME} dns list List DNS zones`,
|
|
50812
|
-
` ${CLI_NAME} waf list -ns prod List WAF policies in prod`,
|
|
50813
|
-
` ${CLI_NAME} --interactive Force interactive REPL mode`,
|
|
50814
|
-
"",
|
|
50815
|
-
...formatDomainsSection(),
|
|
50816
|
-
"",
|
|
50817
|
-
...formatGlobalFlags(),
|
|
50818
|
-
"",
|
|
50819
|
-
...formatEnvVarsSection(),
|
|
50820
|
-
"",
|
|
50821
|
-
...formatConfigSection(),
|
|
50822
|
-
"",
|
|
50823
|
-
"NAVIGATION (Interactive Mode)",
|
|
50824
|
-
" <domain> Navigate into a domain (e.g., 'dns', 'lb')",
|
|
50825
|
-
" /domain Navigate directly to domain from anywhere",
|
|
50826
|
-
" .. Go up one level",
|
|
50827
|
-
" / Return to root",
|
|
50828
|
-
" context Show current navigation context",
|
|
50829
|
-
"",
|
|
50830
|
-
"BUILTINS",
|
|
50831
|
-
" help Show this help",
|
|
50832
|
-
" domains List all available domains",
|
|
50833
|
-
" clear Clear the screen",
|
|
50834
|
-
" history Show command history",
|
|
50835
|
-
" quit, exit Exit the shell",
|
|
50836
|
-
""
|
|
50837
|
-
];
|
|
50838
50947
|
}
|
|
50839
|
-
function
|
|
50840
|
-
return
|
|
50841
|
-
"GLOBAL FLAGS",
|
|
50842
|
-
" -v, --version Show version number",
|
|
50843
|
-
" -h, --help Show this help",
|
|
50844
|
-
" -i, --interactive Force interactive mode",
|
|
50845
|
-
" --no-color Disable color output",
|
|
50846
|
-
" -o, --output <fmt> Output format (json, yaml, table)",
|
|
50847
|
-
" -ns, --namespace <ns> Target namespace"
|
|
50848
|
-
];
|
|
50948
|
+
function formatJSON(data) {
|
|
50949
|
+
return JSON.stringify(data, null, 2);
|
|
50849
50950
|
}
|
|
50850
|
-
function
|
|
50851
|
-
return
|
|
50951
|
+
function formatYAML(data) {
|
|
50952
|
+
return import_yaml3.default.stringify(data, { indent: 2 });
|
|
50852
50953
|
}
|
|
50853
|
-
function
|
|
50854
|
-
|
|
50855
|
-
|
|
50856
|
-
|
|
50857
|
-
|
|
50858
|
-
|
|
50859
|
-
|
|
50860
|
-
if (domain.complexity) meta.push(`Complexity: ${domain.complexity}`);
|
|
50861
|
-
output.push(colorDim(` ${meta.join(" | ")}`));
|
|
50862
|
-
output.push("");
|
|
50863
|
-
}
|
|
50864
|
-
output.push("USAGE");
|
|
50865
|
-
output.push(` ${CLI_NAME} ${domain.name} <action> [options]`);
|
|
50866
|
-
output.push("");
|
|
50867
|
-
output.push("ACTIONS");
|
|
50868
|
-
const actionDescriptions2 = {
|
|
50869
|
-
list: "List resources",
|
|
50870
|
-
get: "Get a specific resource by name",
|
|
50871
|
-
create: "Create a new resource",
|
|
50872
|
-
delete: "Delete a resource",
|
|
50873
|
-
replace: "Replace a resource configuration",
|
|
50874
|
-
apply: "Apply configuration from file",
|
|
50875
|
-
status: "Get resource status",
|
|
50876
|
-
patch: "Patch a resource",
|
|
50877
|
-
"add-labels": "Add labels to a resource",
|
|
50878
|
-
"remove-labels": "Remove labels from a resource"
|
|
50879
|
-
};
|
|
50880
|
-
for (const action of validActions) {
|
|
50881
|
-
const desc = actionDescriptions2[action] ?? action;
|
|
50882
|
-
output.push(` ${action.padEnd(16)} ${desc}`);
|
|
50883
|
-
}
|
|
50884
|
-
output.push("");
|
|
50885
|
-
output.push("EXAMPLES");
|
|
50886
|
-
output.push(` ${CLI_NAME} ${domain.name} list`);
|
|
50887
|
-
output.push(` ${CLI_NAME} ${domain.name} get my-resource`);
|
|
50888
|
-
output.push(
|
|
50889
|
-
` ${CLI_NAME} ${domain.name} create my-resource -f config.yaml`
|
|
50890
|
-
);
|
|
50891
|
-
output.push(` ${CLI_NAME} ${domain.name} delete my-resource`);
|
|
50892
|
-
output.push("");
|
|
50893
|
-
if (domain.useCases && domain.useCases.length > 0) {
|
|
50894
|
-
output.push("USE CASES");
|
|
50895
|
-
for (const useCase of domain.useCases.slice(0, 5)) {
|
|
50896
|
-
output.push(` - ${useCase}`);
|
|
50954
|
+
function extractItems(data) {
|
|
50955
|
+
if (data && typeof data === "object" && "items" in data) {
|
|
50956
|
+
const items = data.items;
|
|
50957
|
+
if (Array.isArray(items)) {
|
|
50958
|
+
return items.filter(
|
|
50959
|
+
(item) => item !== null && typeof item === "object"
|
|
50960
|
+
);
|
|
50897
50961
|
}
|
|
50898
|
-
output.push("");
|
|
50899
50962
|
}
|
|
50900
|
-
if (
|
|
50901
|
-
|
|
50902
|
-
|
|
50903
|
-
|
|
50963
|
+
if (Array.isArray(data)) {
|
|
50964
|
+
return data.filter(
|
|
50965
|
+
(item) => item !== null && typeof item === "object"
|
|
50966
|
+
);
|
|
50904
50967
|
}
|
|
50905
|
-
if (
|
|
50906
|
-
|
|
50907
|
-
output.push(` ${domain.aliases.join(", ")}`);
|
|
50908
|
-
output.push("");
|
|
50968
|
+
if (data && typeof data === "object") {
|
|
50969
|
+
return [data];
|
|
50909
50970
|
}
|
|
50910
|
-
|
|
50911
|
-
output.push("");
|
|
50912
|
-
return output;
|
|
50971
|
+
return [];
|
|
50913
50972
|
}
|
|
50914
|
-
function
|
|
50915
|
-
const
|
|
50916
|
-
|
|
50917
|
-
|
|
50918
|
-
|
|
50919
|
-
|
|
50920
|
-
|
|
50921
|
-
|
|
50922
|
-
|
|
50923
|
-
desc: "Get a specific resource by name",
|
|
50924
|
-
usage: `${CLI_NAME} ${domainName} get <name> [-o json|yaml|table]`
|
|
50925
|
-
},
|
|
50926
|
-
create: {
|
|
50927
|
-
desc: "Create a new resource",
|
|
50928
|
-
usage: `${CLI_NAME} ${domainName} create <name> -f <file.yaml>`
|
|
50929
|
-
},
|
|
50930
|
-
delete: {
|
|
50931
|
-
desc: "Delete a resource by name",
|
|
50932
|
-
usage: `${CLI_NAME} ${domainName} delete <name>`
|
|
50933
|
-
},
|
|
50934
|
-
replace: {
|
|
50935
|
-
desc: "Replace an existing resource configuration",
|
|
50936
|
-
usage: `${CLI_NAME} ${domainName} replace <name> -f <file.yaml>`
|
|
50937
|
-
},
|
|
50938
|
-
apply: {
|
|
50939
|
-
desc: "Apply configuration from a file (create or update)",
|
|
50940
|
-
usage: `${CLI_NAME} ${domainName} apply -f <file.yaml>`
|
|
50941
|
-
},
|
|
50942
|
-
status: {
|
|
50943
|
-
desc: "Get the current status of a resource",
|
|
50944
|
-
usage: `${CLI_NAME} ${domainName} status <name>`
|
|
50945
|
-
},
|
|
50946
|
-
patch: {
|
|
50947
|
-
desc: "Patch specific fields of a resource",
|
|
50948
|
-
usage: `${CLI_NAME} ${domainName} patch <name> -f <patch.yaml>`
|
|
50949
|
-
},
|
|
50950
|
-
"add-labels": {
|
|
50951
|
-
desc: "Add labels to a resource",
|
|
50952
|
-
usage: `${CLI_NAME} ${domainName} add-labels <name> key=value`
|
|
50953
|
-
},
|
|
50954
|
-
"remove-labels": {
|
|
50955
|
-
desc: "Remove labels from a resource",
|
|
50956
|
-
usage: `${CLI_NAME} ${domainName} remove-labels <name> key`
|
|
50957
|
-
}
|
|
50958
|
-
};
|
|
50959
|
-
const actionInfo = actionDescriptions2[action] ?? {
|
|
50960
|
-
desc: `Execute ${action} operation`,
|
|
50961
|
-
usage: `${CLI_NAME} ${domainName} ${action} [options]`
|
|
50962
|
-
};
|
|
50963
|
-
return [
|
|
50964
|
-
"",
|
|
50965
|
-
colorBoldWhite(`${displayDomain} - ${action}`),
|
|
50966
|
-
"",
|
|
50967
|
-
` ${actionInfo.desc}`,
|
|
50968
|
-
"",
|
|
50969
|
-
"USAGE",
|
|
50970
|
-
` ${actionInfo.usage}`,
|
|
50971
|
-
"",
|
|
50972
|
-
"OPTIONS",
|
|
50973
|
-
" -n, --name <name> Resource name",
|
|
50974
|
-
" -ns, --namespace <ns> Target namespace",
|
|
50975
|
-
" -o, --output <fmt> Output format (json, yaml, table)",
|
|
50976
|
-
" -f, --file <path> Configuration file",
|
|
50977
|
-
"",
|
|
50978
|
-
colorDim(`For domain help, run: ${CLI_NAME} ${domainName} --help`),
|
|
50979
|
-
""
|
|
50980
|
-
];
|
|
50973
|
+
function getStringField(obj, key) {
|
|
50974
|
+
const value = obj[key];
|
|
50975
|
+
if (typeof value === "string") {
|
|
50976
|
+
return value;
|
|
50977
|
+
}
|
|
50978
|
+
if (value !== null && value !== void 0) {
|
|
50979
|
+
return String(value);
|
|
50980
|
+
}
|
|
50981
|
+
return "";
|
|
50981
50982
|
}
|
|
50982
|
-
function
|
|
50983
|
-
const
|
|
50984
|
-
|
|
50985
|
-
|
|
50986
|
-
return formatDomainHelp(domainInfo);
|
|
50983
|
+
function formatLabels(obj) {
|
|
50984
|
+
const labels = obj["labels"];
|
|
50985
|
+
if (!labels || typeof labels !== "object") {
|
|
50986
|
+
return "";
|
|
50987
50987
|
}
|
|
50988
|
-
|
|
50989
|
-
|
|
50990
|
-
|
|
50991
|
-
|
|
50992
|
-
return formatActionsHelp();
|
|
50993
|
-
case "navigation":
|
|
50994
|
-
case "nav":
|
|
50995
|
-
return formatNavigationHelp();
|
|
50996
|
-
case "env":
|
|
50997
|
-
case "environment":
|
|
50998
|
-
return ["", ...formatEnvironmentVariables(), ""];
|
|
50999
|
-
case "flags":
|
|
51000
|
-
return ["", ...formatGlobalFlags(), ""];
|
|
51001
|
-
default:
|
|
51002
|
-
return [
|
|
51003
|
-
"",
|
|
51004
|
-
`Unknown help topic: ${topic}`,
|
|
51005
|
-
"",
|
|
51006
|
-
"Available topics:",
|
|
51007
|
-
" domains List all available domains",
|
|
51008
|
-
" actions List available actions",
|
|
51009
|
-
" navigation Navigation commands",
|
|
51010
|
-
" env Environment variables",
|
|
51011
|
-
" flags Global flags",
|
|
51012
|
-
" <domain> Help for a specific domain (e.g., 'help dns')",
|
|
51013
|
-
""
|
|
51014
|
-
];
|
|
50988
|
+
const labelMap = labels;
|
|
50989
|
+
const entries = Object.entries(labelMap).sort(([a], [b]) => a.localeCompare(b)).map(([k, v]) => `${k}:${v}`);
|
|
50990
|
+
if (entries.length === 0) {
|
|
50991
|
+
return "";
|
|
51015
50992
|
}
|
|
50993
|
+
return `map[${entries.join(" ")}]`;
|
|
51016
50994
|
}
|
|
51017
|
-
function
|
|
51018
|
-
|
|
51019
|
-
|
|
51020
|
-
for (const domain of domainRegistry.values()) {
|
|
51021
|
-
const category = domain.category ?? "Other";
|
|
51022
|
-
if (!categories.has(category)) {
|
|
51023
|
-
categories.set(category, []);
|
|
51024
|
-
}
|
|
51025
|
-
categories.get(category)?.push(domain);
|
|
50995
|
+
function wrapText3(text, maxWidth) {
|
|
50996
|
+
if (text.length <= maxWidth) {
|
|
50997
|
+
return [text];
|
|
51026
50998
|
}
|
|
51027
|
-
const
|
|
51028
|
-
|
|
51029
|
-
|
|
51030
|
-
|
|
51031
|
-
|
|
51032
|
-
|
|
51033
|
-
|
|
51034
|
-
|
|
51035
|
-
|
|
51036
|
-
|
|
51037
|
-
|
|
51038
|
-
|
|
51039
|
-
output.push(` ${"".padEnd(24)} Aliases:${aliases}`);
|
|
50999
|
+
const lines = [];
|
|
51000
|
+
let remaining = text;
|
|
51001
|
+
while (remaining.length > 0) {
|
|
51002
|
+
if (remaining.length <= maxWidth) {
|
|
51003
|
+
lines.push(remaining);
|
|
51004
|
+
break;
|
|
51005
|
+
}
|
|
51006
|
+
let breakPoint = maxWidth;
|
|
51007
|
+
for (let i = maxWidth - 1; i > 0; i--) {
|
|
51008
|
+
if (remaining[i] === " ") {
|
|
51009
|
+
breakPoint = i;
|
|
51010
|
+
break;
|
|
51040
51011
|
}
|
|
51041
51012
|
}
|
|
51042
|
-
|
|
51013
|
+
lines.push(remaining.slice(0, breakPoint));
|
|
51014
|
+
remaining = remaining.slice(breakPoint).trimStart();
|
|
51043
51015
|
}
|
|
51044
|
-
return
|
|
51016
|
+
return lines;
|
|
51045
51017
|
}
|
|
51046
|
-
function
|
|
51047
|
-
|
|
51048
|
-
|
|
51049
|
-
|
|
51050
|
-
|
|
51051
|
-
|
|
51052
|
-
|
|
51053
|
-
|
|
51054
|
-
|
|
51055
|
-
|
|
51056
|
-
|
|
51057
|
-
|
|
51058
|
-
|
|
51059
|
-
|
|
51060
|
-
|
|
51061
|
-
|
|
51062
|
-
|
|
51063
|
-
|
|
51064
|
-
|
|
51065
|
-
|
|
51066
|
-
|
|
51067
|
-
|
|
51068
|
-
|
|
51069
|
-
|
|
51070
|
-
|
|
51018
|
+
function formatTable(data) {
|
|
51019
|
+
const items = extractItems(data);
|
|
51020
|
+
if (items.length === 0) {
|
|
51021
|
+
return "";
|
|
51022
|
+
}
|
|
51023
|
+
const headers = ["NAMESPACE", "NAME", "LABELS"];
|
|
51024
|
+
const widths = [9, 27, 30];
|
|
51025
|
+
const rows = [];
|
|
51026
|
+
for (const item of items) {
|
|
51027
|
+
const row = [
|
|
51028
|
+
getStringField(item, "namespace") || "<None>",
|
|
51029
|
+
getStringField(item, "name") || "<None>",
|
|
51030
|
+
formatLabels(item) || "<None>"
|
|
51031
|
+
];
|
|
51032
|
+
const wrappedCells = row.map((cell, i) => wrapText3(cell, widths[i]));
|
|
51033
|
+
const maxLines = Math.max(...wrappedCells.map((c) => c.length));
|
|
51034
|
+
const wrappedRows = [];
|
|
51035
|
+
for (let line = 0; line < maxLines; line++) {
|
|
51036
|
+
wrappedRows.push(wrappedCells.map((c) => c[line] ?? ""));
|
|
51037
|
+
}
|
|
51038
|
+
rows.push(wrappedRows);
|
|
51039
|
+
}
|
|
51040
|
+
const lines = [];
|
|
51041
|
+
const boxLine = "+" + widths.map((w) => "-".repeat(w + 2)).join("+") + "+";
|
|
51042
|
+
lines.push(boxLine);
|
|
51043
|
+
lines.push(
|
|
51044
|
+
"|" + headers.map((h, i) => {
|
|
51045
|
+
const padding = widths[i] - h.length;
|
|
51046
|
+
const leftPad = Math.floor(padding / 2);
|
|
51047
|
+
const rightPad = padding - leftPad;
|
|
51048
|
+
return " " + " ".repeat(leftPad) + h + " ".repeat(rightPad) + " ";
|
|
51049
|
+
}).join("|") + "|"
|
|
51050
|
+
);
|
|
51051
|
+
lines.push(boxLine);
|
|
51052
|
+
for (const wrappedRows of rows) {
|
|
51053
|
+
for (const row of wrappedRows) {
|
|
51054
|
+
lines.push(
|
|
51055
|
+
"|" + row.map((cell, i) => {
|
|
51056
|
+
const padding = widths[i] - cell.length;
|
|
51057
|
+
return " " + cell + " ".repeat(padding) + " ";
|
|
51058
|
+
}).join("|") + "|"
|
|
51059
|
+
);
|
|
51060
|
+
}
|
|
51061
|
+
lines.push(boxLine);
|
|
51062
|
+
}
|
|
51063
|
+
return lines.join("\n");
|
|
51071
51064
|
}
|
|
51072
|
-
function
|
|
51073
|
-
|
|
51074
|
-
|
|
51075
|
-
|
|
51076
|
-
|
|
51077
|
-
|
|
51078
|
-
|
|
51079
|
-
|
|
51080
|
-
|
|
51081
|
-
|
|
51082
|
-
|
|
51083
|
-
|
|
51084
|
-
|
|
51085
|
-
" context Show current navigation context",
|
|
51086
|
-
" ctx Alias for context",
|
|
51087
|
-
"",
|
|
51088
|
-
"EXAMPLES",
|
|
51089
|
-
" xcsh> dns # Enter dns domain",
|
|
51090
|
-
" dns> list # Execute list in dns context",
|
|
51091
|
-
" dns> .. # Return to root",
|
|
51092
|
-
" xcsh> /waf # Jump directly to waf",
|
|
51093
|
-
" waf> /dns # Jump from waf to dns",
|
|
51094
|
-
""
|
|
51065
|
+
function formatTSV(data) {
|
|
51066
|
+
const items = extractItems(data);
|
|
51067
|
+
if (items.length === 0) {
|
|
51068
|
+
return "";
|
|
51069
|
+
}
|
|
51070
|
+
const allKeys = /* @__PURE__ */ new Set();
|
|
51071
|
+
for (const item of items) {
|
|
51072
|
+
Object.keys(item).forEach((k) => allKeys.add(k));
|
|
51073
|
+
}
|
|
51074
|
+
const priority = ["name", "namespace", "status", "created", "modified"];
|
|
51075
|
+
const headers = [
|
|
51076
|
+
...priority.filter((p) => allKeys.has(p)),
|
|
51077
|
+
...[...allKeys].filter((k) => !priority.includes(k)).sort()
|
|
51095
51078
|
];
|
|
51079
|
+
const lines = [];
|
|
51080
|
+
for (const item of items) {
|
|
51081
|
+
const values = headers.map((h) => {
|
|
51082
|
+
const val = item[h];
|
|
51083
|
+
if (val === null || val === void 0) return "";
|
|
51084
|
+
if (typeof val === "object") return JSON.stringify(val);
|
|
51085
|
+
return String(val);
|
|
51086
|
+
});
|
|
51087
|
+
lines.push(values.join(" "));
|
|
51088
|
+
}
|
|
51089
|
+
return lines.join("\n");
|
|
51096
51090
|
}
|
|
51097
|
-
function
|
|
51098
|
-
const
|
|
51099
|
-
|
|
51100
|
-
|
|
51101
|
-
|
|
51102
|
-
|
|
51103
|
-
|
|
51104
|
-
|
|
51105
|
-
|
|
51091
|
+
function formatAPIError(statusCode, body, operation) {
|
|
51092
|
+
const lines = [];
|
|
51093
|
+
lines.push(`ERROR: ${operation} failed (HTTP ${statusCode})`);
|
|
51094
|
+
if (body && typeof body === "object") {
|
|
51095
|
+
const errResp = body;
|
|
51096
|
+
if (errResp.message) {
|
|
51097
|
+
lines.push(` Message: ${errResp.message}`);
|
|
51098
|
+
}
|
|
51099
|
+
if (errResp.code) {
|
|
51100
|
+
lines.push(` Code: ${errResp.code}`);
|
|
51101
|
+
}
|
|
51102
|
+
if (errResp.details) {
|
|
51103
|
+
lines.push(` Details: ${errResp.details}`);
|
|
51104
|
+
}
|
|
51106
51105
|
}
|
|
51107
|
-
|
|
51106
|
+
switch (statusCode) {
|
|
51107
|
+
case 401:
|
|
51108
|
+
lines.push(
|
|
51109
|
+
"\nHint: Authentication failed. Check your credentials with 'login profile show'"
|
|
51110
|
+
);
|
|
51111
|
+
break;
|
|
51112
|
+
case 403:
|
|
51113
|
+
lines.push(
|
|
51114
|
+
"\nHint: Permission denied. You may not have access to this resource."
|
|
51115
|
+
);
|
|
51116
|
+
break;
|
|
51117
|
+
case 404:
|
|
51118
|
+
lines.push(
|
|
51119
|
+
"\nHint: Resource not found. Verify the name and namespace are correct."
|
|
51120
|
+
);
|
|
51121
|
+
break;
|
|
51122
|
+
case 409:
|
|
51123
|
+
lines.push(
|
|
51124
|
+
"\nHint: Conflict - resource may already exist or be in a conflicting state."
|
|
51125
|
+
);
|
|
51126
|
+
break;
|
|
51127
|
+
case 429:
|
|
51128
|
+
lines.push("\nHint: Rate limited. Please wait and try again.");
|
|
51129
|
+
break;
|
|
51130
|
+
case 500:
|
|
51131
|
+
case 502:
|
|
51132
|
+
case 503:
|
|
51133
|
+
lines.push(
|
|
51134
|
+
"\nHint: Server error. Please try again later or contact support."
|
|
51135
|
+
);
|
|
51136
|
+
break;
|
|
51137
|
+
}
|
|
51138
|
+
return lines.join("\n");
|
|
51108
51139
|
}
|
|
51109
51140
|
|
|
51110
51141
|
// src/repl/executor.ts
|
|
@@ -52210,7 +52241,7 @@ var program2 = new Command();
|
|
|
52210
52241
|
program2.configureHelp({
|
|
52211
52242
|
formatHelp: () => formatRootHelp().join("\n")
|
|
52212
52243
|
});
|
|
52213
|
-
program2.name(CLI_NAME).description("F5 Distributed Cloud Shell - Interactive CLI for F5 XC").version(CLI_VERSION, "-v, --version", "Show version number").option("
|
|
52244
|
+
program2.name(CLI_NAME).description("F5 Distributed Cloud Shell - Interactive CLI for F5 XC").version(CLI_VERSION, "-v, --version", "Show version number").option("--no-color", "Disable color output").option("--logo <mode>", "Logo display mode: image, ascii, none").option("-h, --help", "Show help").argument("[command...]", "Command to execute non-interactively").allowUnknownOption(true).helpOption(false).action(
|
|
52214
52245
|
async (commandArgs, options) => {
|
|
52215
52246
|
if (options.help && commandArgs.length === 0) {
|
|
52216
52247
|
formatRootHelp().forEach((line) => console.log(line));
|
|
@@ -52222,8 +52253,8 @@ program2.name(CLI_NAME).description("F5 Distributed Cloud Shell - Interactive CL
|
|
|
52222
52253
|
if (options.logo && commandArgs.length > 0) {
|
|
52223
52254
|
commandArgs.push("--logo", options.logo);
|
|
52224
52255
|
}
|
|
52225
|
-
if (commandArgs.length === 0
|
|
52226
|
-
if (!process.stdin.isTTY
|
|
52256
|
+
if (commandArgs.length === 0) {
|
|
52257
|
+
if (!process.stdin.isTTY) {
|
|
52227
52258
|
console.error(
|
|
52228
52259
|
"Error: Interactive mode requires a terminal (TTY)."
|
|
52229
52260
|
);
|