@kubernetesjs/cli 0.0.3 → 0.1.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.
Files changed (59) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +54 -55
  3. package/commands/apply.d.ts +4 -0
  4. package/commands/apply.js +171 -0
  5. package/commands/cluster-info.d.ts +4 -0
  6. package/commands/cluster-info.js +26 -0
  7. package/commands/config-handler.d.ts +11 -0
  8. package/commands/config-handler.js +81 -0
  9. package/commands/config.d.ts +4 -0
  10. package/commands/config.js +72 -0
  11. package/commands/delete.d.ts +4 -0
  12. package/commands/delete.js +256 -0
  13. package/commands/deploy.d.ts +6 -0
  14. package/commands/deploy.js +209 -0
  15. package/commands/describe.d.ts +4 -0
  16. package/commands/describe.js +216 -0
  17. package/commands/exec.d.ts +4 -0
  18. package/commands/exec.js +145 -0
  19. package/commands/get.d.ts +4 -0
  20. package/commands/get.js +164 -0
  21. package/commands/logs.d.ts +4 -0
  22. package/commands/logs.js +110 -0
  23. package/commands/port-forward.d.ts +4 -0
  24. package/commands/port-forward.js +143 -0
  25. package/commands.d.ts +3 -0
  26. package/commands.js +93 -0
  27. package/config.d.ts +22 -0
  28. package/config.js +113 -0
  29. package/esm/commands/apply.js +133 -0
  30. package/esm/commands/cluster-info.js +21 -0
  31. package/esm/commands/config-handler.js +43 -0
  32. package/esm/commands/config.js +67 -0
  33. package/esm/commands/delete.js +218 -0
  34. package/esm/commands/deploy.js +207 -0
  35. package/esm/commands/describe.js +211 -0
  36. package/esm/commands/exec.js +140 -0
  37. package/esm/commands/get.js +159 -0
  38. package/esm/commands/logs.js +105 -0
  39. package/esm/commands/port-forward.js +138 -0
  40. package/esm/commands.js +86 -0
  41. package/esm/config.js +74 -0
  42. package/esm/index.js +19 -0
  43. package/esm/package.js +26 -0
  44. package/esm/utils.js +49 -0
  45. package/index.d.ts +3 -0
  46. package/index.js +22 -0
  47. package/package.d.ts +1 -0
  48. package/package.js +29 -0
  49. package/package.json +37 -61
  50. package/utils.d.ts +11 -0
  51. package/utils.js +58 -0
  52. package/main/client.js +0 -156
  53. package/main/index.js +0 -2598
  54. package/module/client.js +0 -129
  55. package/module/index.js +0 -2594
  56. package/src/client.ts +0 -156
  57. package/src/index.ts +0 -14187
  58. package/types/client.d.ts +0 -31
  59. package/types/index.d.ts +0 -11331
package/config.d.ts ADDED
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Read and parse a YAML file
3
+ * @param filePath Path to the YAML file
4
+ * @returns Parsed YAML content
5
+ */
6
+ export declare function readYamlFile(filePath: string): any;
7
+ /**
8
+ * Infer the resource type from a Kubernetes YAML
9
+ * @param resource The parsed Kubernetes resource
10
+ * @returns The resource type (lowercase)
11
+ */
12
+ export declare function inferResourceType(resource: any): string;
13
+ /**
14
+ * Get the current namespace from the local kubeconfig
15
+ * @returns The current namespace
16
+ */
17
+ export declare function getCurrentNamespace(): string;
18
+ /**
19
+ * Set the current namespace in the local kubeconfig
20
+ * @param namespace The namespace to set
21
+ */
22
+ export declare function setCurrentNamespace(namespace: string): void;
package/config.js ADDED
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.readYamlFile = readYamlFile;
37
+ exports.inferResourceType = inferResourceType;
38
+ exports.getCurrentNamespace = getCurrentNamespace;
39
+ exports.setCurrentNamespace = setCurrentNamespace;
40
+ const fs_1 = require("fs");
41
+ const os_1 = require("os");
42
+ const path_1 = require("path");
43
+ const yaml = __importStar(require("js-yaml"));
44
+ const KUBECONFIG_PATH = (0, path_1.join)((0, os_1.homedir)(), '.kubeconfig');
45
+ const DEFAULT_NAMESPACE = 'default';
46
+ /**
47
+ * Read and parse a YAML file
48
+ * @param filePath Path to the YAML file
49
+ * @returns Parsed YAML content
50
+ */
51
+ function readYamlFile(filePath) {
52
+ try {
53
+ const fileContent = (0, fs_1.readFileSync)(filePath, 'utf8');
54
+ return yaml.load(fileContent);
55
+ }
56
+ catch (error) {
57
+ console.error(`Error reading YAML file: ${error}`);
58
+ throw error;
59
+ }
60
+ }
61
+ /**
62
+ * Infer the resource type from a Kubernetes YAML
63
+ * @param resource The parsed Kubernetes resource
64
+ * @returns The resource type (lowercase)
65
+ */
66
+ function inferResourceType(resource) {
67
+ if (!resource || !resource.kind) {
68
+ throw new Error('Invalid Kubernetes resource: missing kind');
69
+ }
70
+ return resource.kind.toLowerCase();
71
+ }
72
+ /**
73
+ * Get the current namespace from the local kubeconfig
74
+ * @returns The current namespace
75
+ */
76
+ function getCurrentNamespace() {
77
+ try {
78
+ if (!(0, fs_1.existsSync)(KUBECONFIG_PATH)) {
79
+ return DEFAULT_NAMESPACE;
80
+ }
81
+ const configContent = (0, fs_1.readFileSync)(KUBECONFIG_PATH, 'utf8');
82
+ const config = JSON.parse(configContent);
83
+ return config.currentNamespace || DEFAULT_NAMESPACE;
84
+ }
85
+ catch (error) {
86
+ console.error(`Error reading kubeconfig: ${error}`);
87
+ return DEFAULT_NAMESPACE;
88
+ }
89
+ }
90
+ /**
91
+ * Set the current namespace in the local kubeconfig
92
+ * @param namespace The namespace to set
93
+ */
94
+ function setCurrentNamespace(namespace) {
95
+ try {
96
+ let config = { currentNamespace: namespace };
97
+ if ((0, fs_1.existsSync)(KUBECONFIG_PATH)) {
98
+ try {
99
+ const configContent = (0, fs_1.readFileSync)(KUBECONFIG_PATH, 'utf8');
100
+ config = { ...JSON.parse(configContent), currentNamespace: namespace };
101
+ }
102
+ catch (error) {
103
+ console.error(`Error parsing existing kubeconfig: ${error}`);
104
+ }
105
+ }
106
+ (0, fs_1.writeFileSync)(KUBECONFIG_PATH, JSON.stringify(config, null, 2), 'utf8');
107
+ console.log(`Namespace set to "${namespace}"`);
108
+ }
109
+ catch (error) {
110
+ console.error(`Error setting namespace: ${error}`);
111
+ throw error;
112
+ }
113
+ }
@@ -0,0 +1,133 @@
1
+ import chalk from 'chalk';
2
+ import { KubernetesClient } from 'kubernetesjs';
3
+ import { readYamlFile } from '../config';
4
+ import * as fs from 'fs';
5
+ async function promptYamlFilePath(prompter, argv) {
6
+ const question = {
7
+ type: 'text',
8
+ name: 'filePath',
9
+ message: 'Enter path to YAML file',
10
+ required: true
11
+ };
12
+ const { filePath } = await prompter.prompt(argv, [question]);
13
+ return filePath;
14
+ }
15
+ async function applyResource(client, resource, namespace) {
16
+ const kind = resource.kind.toLowerCase();
17
+ const name = resource.metadata?.name;
18
+ if (!name) {
19
+ throw new Error('Resource must have a name');
20
+ }
21
+ console.log(chalk.blue(`Applying ${kind} "${name}" in namespace ${namespace}...`));
22
+ try {
23
+ switch (kind) {
24
+ case 'deployment':
25
+ await client.createAppsV1NamespacedDeployment({
26
+ path: { namespace },
27
+ query: {
28
+ pretty: 'true',
29
+ fieldManager: 'kubernetesjs-cli'
30
+ },
31
+ body: resource
32
+ });
33
+ console.log(chalk.green(`Deployment "${name}" created/updated successfully`));
34
+ break;
35
+ case 'service':
36
+ await client.createCoreV1NamespacedService({
37
+ path: { namespace },
38
+ query: {
39
+ pretty: 'true',
40
+ fieldManager: 'kubernetesjs-cli'
41
+ },
42
+ body: resource
43
+ });
44
+ console.log(chalk.green(`Service "${name}" created/updated successfully`));
45
+ break;
46
+ case 'pod':
47
+ await client.createCoreV1NamespacedPod({
48
+ path: { namespace },
49
+ query: {
50
+ pretty: 'true',
51
+ fieldManager: 'kubernetesjs-cli'
52
+ },
53
+ body: resource
54
+ });
55
+ console.log(chalk.green(`Pod "${name}" created/updated successfully`));
56
+ break;
57
+ case 'configmap':
58
+ await client.createCoreV1NamespacedConfigMap({
59
+ path: { namespace },
60
+ query: {
61
+ pretty: 'true',
62
+ fieldManager: 'kubernetesjs-cli'
63
+ },
64
+ body: resource
65
+ });
66
+ console.log(chalk.green(`ConfigMap "${name}" created/updated successfully`));
67
+ break;
68
+ case 'secret':
69
+ await client.createCoreV1NamespacedSecret({
70
+ path: { namespace },
71
+ query: {
72
+ pretty: 'true',
73
+ fieldManager: 'kubernetesjs-cli'
74
+ },
75
+ body: resource
76
+ });
77
+ console.log(chalk.green(`Secret "${name}" created/updated successfully`));
78
+ break;
79
+ default:
80
+ console.log(chalk.yellow(`Resource kind "${kind}" not implemented yet`));
81
+ }
82
+ }
83
+ catch (error) {
84
+ console.error(chalk.red(`Error applying ${kind} "${name}": ${error}`));
85
+ throw error;
86
+ }
87
+ }
88
+ export default async (argv, prompter, _options) => {
89
+ try {
90
+ const client = new KubernetesClient({
91
+ restEndpoint: argv.clientUrl
92
+ });
93
+ const filePath = argv.f || argv._?.[0] || await promptYamlFilePath(prompter, argv);
94
+ if (!filePath) {
95
+ console.error(chalk.red('No file path provided'));
96
+ return;
97
+ }
98
+ if (!fs.existsSync(filePath)) {
99
+ console.error(chalk.red(`File not found: ${filePath}`));
100
+ return;
101
+ }
102
+ let resources;
103
+ try {
104
+ const content = readYamlFile(filePath);
105
+ if (Array.isArray(content)) {
106
+ resources = content;
107
+ }
108
+ else if (content.kind === 'List' && Array.isArray(content.items)) {
109
+ resources = content.items;
110
+ }
111
+ else {
112
+ resources = [content];
113
+ }
114
+ }
115
+ catch (error) {
116
+ console.error(chalk.red(`Error parsing YAML file: ${error}`));
117
+ return;
118
+ }
119
+ for (const resource of resources) {
120
+ try {
121
+ const namespace = resource.metadata?.namespace || argv.n || argv.namespace || 'default';
122
+ await applyResource(client, resource, namespace);
123
+ }
124
+ catch (error) {
125
+ console.error(chalk.red(`Failed to apply resource: ${error}`));
126
+ }
127
+ }
128
+ console.log(chalk.green('Apply completed'));
129
+ }
130
+ catch (error) {
131
+ console.error(chalk.red(`Error: ${error}`));
132
+ }
133
+ };
@@ -0,0 +1,21 @@
1
+ import chalk from 'chalk';
2
+ import { KubernetesClient } from 'kubernetesjs';
3
+ export default async (_argv, _prompter, _options) => {
4
+ try {
5
+ const client = new KubernetesClient({
6
+ restEndpoint: _argv.clientUrl
7
+ });
8
+ console.log(chalk.blue('Kubernetes cluster info:'));
9
+ const apiVersions = await client.getAPIVersions({
10
+ params: {},
11
+ query: {}
12
+ });
13
+ console.log(chalk.bold('\nAPI Versions:'));
14
+ if (apiVersions.apiVersion) {
15
+ console.log(apiVersions.apiVersion);
16
+ }
17
+ }
18
+ catch (error) {
19
+ console.error(chalk.red(`Error: ${error}`));
20
+ }
21
+ };
@@ -0,0 +1,43 @@
1
+ import chalk from 'chalk';
2
+ import * as fs from 'fs';
3
+ import { readYamlFile, inferResourceType } from '../config';
4
+ /**
5
+ * Handle the --config flag by parsing the YAML file and executing the appropriate command
6
+ * @param argv Command line arguments
7
+ * @param prompter Inquirerer instance
8
+ * @param options CLI options
9
+ * @param commandMap Map of available commands
10
+ */
11
+ export default async (argv, prompter, options, commandMap) => {
12
+ if (!argv.config) {
13
+ return false;
14
+ }
15
+ const configPath = argv.config;
16
+ if (!fs.existsSync(configPath)) {
17
+ console.error(chalk.red(`Config file not found: ${configPath}`));
18
+ return true;
19
+ }
20
+ try {
21
+ const resource = readYamlFile(configPath);
22
+ const resourceType = inferResourceType(resource);
23
+ console.log(chalk.blue(`Detected resource type: ${resourceType}`));
24
+ let command;
25
+ command = 'apply';
26
+ const newArgv = {
27
+ ...argv,
28
+ _: [configPath],
29
+ f: configPath
30
+ };
31
+ if (commandMap[command]) {
32
+ await commandMap[command](newArgv, prompter, options);
33
+ }
34
+ else {
35
+ console.error(chalk.red(`No command found for resource type: ${resourceType}`));
36
+ }
37
+ return true;
38
+ }
39
+ catch (error) {
40
+ console.error(chalk.red(`Error processing config file: ${error}`));
41
+ return true;
42
+ }
43
+ };
@@ -0,0 +1,67 @@
1
+ import chalk from 'chalk';
2
+ import { KubernetesClient } from 'kubernetesjs';
3
+ import { getCurrentNamespace, setCurrentNamespace } from '../config';
4
+ async function promptNamespace(prompter, argv, client) {
5
+ try {
6
+ const namespaces = await client.listCoreV1Namespace({
7
+ query: {}
8
+ });
9
+ if (!namespaces.items || namespaces.items.length === 0) {
10
+ console.log(chalk.yellow('No namespaces found'));
11
+ return '';
12
+ }
13
+ const options = namespaces.items.map(ns => ({
14
+ name: ns.metadata.name,
15
+ value: ns.metadata.name
16
+ }));
17
+ const question = {
18
+ type: 'autocomplete',
19
+ name: 'namespace',
20
+ message: 'Select namespace',
21
+ options,
22
+ maxDisplayLines: 10,
23
+ required: true
24
+ };
25
+ const { namespace } = await prompter.prompt(argv, [question]);
26
+ return namespace;
27
+ }
28
+ catch (error) {
29
+ console.error(chalk.red(`Error getting namespaces: ${error}`));
30
+ return '';
31
+ }
32
+ }
33
+ export default async (argv, prompter, _options) => {
34
+ try {
35
+ const client = new KubernetesClient({
36
+ restEndpoint: argv.clientUrl
37
+ });
38
+ const subcommand = argv._?.[0];
39
+ if (subcommand === 'get-context') {
40
+ const namespace = getCurrentNamespace();
41
+ console.log(chalk.green(`Current namespace: ${namespace}`));
42
+ return;
43
+ }
44
+ if (subcommand === 'set-context') {
45
+ if (argv.current !== true) {
46
+ console.error(chalk.red('Missing --current flag'));
47
+ return;
48
+ }
49
+ let namespace = argv.namespace;
50
+ if (!namespace) {
51
+ namespace = await promptNamespace(prompter, argv, client);
52
+ if (!namespace) {
53
+ return;
54
+ }
55
+ }
56
+ setCurrentNamespace(namespace);
57
+ console.log(chalk.green(`Namespace set to "${namespace}"`));
58
+ return;
59
+ }
60
+ console.log(chalk.blue('Available config commands:'));
61
+ console.log(' get-context Display the current context');
62
+ console.log(' set-context --current --namespace=<namespace> Set the current namespace');
63
+ }
64
+ catch (error) {
65
+ console.error(chalk.red(`Error: ${error}`));
66
+ }
67
+ };
@@ -0,0 +1,218 @@
1
+ import chalk from 'chalk';
2
+ import { KubernetesClient } from 'kubernetesjs';
3
+ import { getCurrentNamespace, readYamlFile } from '../config';
4
+ import * as fs from 'fs';
5
+ async function promptResourceType(prompter, argv) {
6
+ const resourceTypes = [
7
+ 'pod',
8
+ 'service',
9
+ 'deployment',
10
+ 'replicaset',
11
+ 'statefulset',
12
+ 'daemonset',
13
+ 'configmap',
14
+ 'secret'
15
+ ];
16
+ const question = {
17
+ type: 'autocomplete',
18
+ name: 'resourceType',
19
+ message: 'Select resource type to delete',
20
+ options: resourceTypes,
21
+ maxDisplayLines: 10,
22
+ required: true
23
+ };
24
+ const { resourceType } = await prompter.prompt(argv, [question]);
25
+ return resourceType;
26
+ }
27
+ async function promptResourceSelection(prompter, argv, resourceType, namespace, client) {
28
+ let resources = [];
29
+ switch (resourceType) {
30
+ case 'pod':
31
+ const pods = await client.listCoreV1NamespacedPod({
32
+ path: { namespace },
33
+ query: { limit: 100 }
34
+ });
35
+ resources = pods.items || [];
36
+ break;
37
+ case 'service':
38
+ const services = await client.listCoreV1NamespacedService({
39
+ path: { namespace },
40
+ query: { limit: 100 }
41
+ });
42
+ resources = services.items || [];
43
+ break;
44
+ case 'deployment':
45
+ const deployments = await client.listAppsV1NamespacedDeployment({
46
+ path: { namespace },
47
+ query: { limit: 100 }
48
+ });
49
+ resources = deployments.items || [];
50
+ break;
51
+ case 'configmap':
52
+ const configmaps = await client.listCoreV1NamespacedConfigMap({
53
+ path: { namespace },
54
+ query: { limit: 100 }
55
+ });
56
+ resources = configmaps.items || [];
57
+ break;
58
+ case 'secret':
59
+ const secrets = await client.listCoreV1NamespacedSecret({
60
+ path: { namespace },
61
+ query: { limit: 100 }
62
+ });
63
+ resources = secrets.items || [];
64
+ break;
65
+ default:
66
+ console.log(chalk.yellow(`Resource type '${resourceType}' not implemented yet for selection`));
67
+ return [];
68
+ }
69
+ if (resources.length === 0) {
70
+ console.log(chalk.yellow(`No ${resourceType}s found in namespace ${namespace}`));
71
+ return [];
72
+ }
73
+ const options = resources.map(r => ({
74
+ name: r.metadata.name,
75
+ value: r.metadata.name
76
+ }));
77
+ const question = {
78
+ type: 'checkbox',
79
+ name: 'selectedResources',
80
+ message: `Select ${resourceType}(s) to delete`,
81
+ options,
82
+ maxDisplayLines: 10,
83
+ required: true
84
+ };
85
+ let selectedResources;
86
+ ({ selectedResources } = await prompter.prompt(argv, [question]));
87
+ return selectedResources
88
+ .filter(res => res.selected)
89
+ .map(res => res.value);
90
+ }
91
+ async function deleteResource(client, resourceType, resourceName, namespace) {
92
+ try {
93
+ switch (resourceType) {
94
+ case 'pod':
95
+ await client.deleteCoreV1NamespacedPod({
96
+ path: {
97
+ namespace,
98
+ name: resourceName
99
+ },
100
+ query: {}
101
+ });
102
+ console.log(chalk.green(`Pod "${resourceName}" deleted successfully`));
103
+ break;
104
+ case 'service':
105
+ await client.deleteCoreV1NamespacedService({
106
+ path: {
107
+ namespace,
108
+ name: resourceName
109
+ },
110
+ query: {}
111
+ });
112
+ console.log(chalk.green(`Service "${resourceName}" deleted successfully`));
113
+ break;
114
+ case 'deployment':
115
+ await client.deleteAppsV1NamespacedDeployment({
116
+ path: {
117
+ namespace,
118
+ name: resourceName
119
+ },
120
+ query: {}
121
+ });
122
+ console.log(chalk.green(`Deployment "${resourceName}" deleted successfully`));
123
+ break;
124
+ case 'configmap':
125
+ await client.deleteCoreV1NamespacedConfigMap({
126
+ path: {
127
+ namespace,
128
+ name: resourceName
129
+ },
130
+ query: {}
131
+ });
132
+ console.log(chalk.green(`ConfigMap "${resourceName}" deleted successfully`));
133
+ break;
134
+ case 'secret':
135
+ await client.deleteCoreV1NamespacedSecret({
136
+ path: {
137
+ namespace,
138
+ name: resourceName
139
+ },
140
+ query: {}
141
+ });
142
+ console.log(chalk.green(`Secret "${resourceName}" deleted successfully`));
143
+ break;
144
+ default:
145
+ console.log(chalk.yellow(`Resource type '${resourceType}' not implemented yet for deletion`));
146
+ }
147
+ }
148
+ catch (error) {
149
+ console.error(chalk.red(`Error deleting ${resourceType} "${resourceName}": ${error}`));
150
+ }
151
+ }
152
+ async function deleteFromYaml(client, filePath, namespace) {
153
+ try {
154
+ const content = readYamlFile(filePath);
155
+ const resources = Array.isArray(content) ? content :
156
+ (content.kind === 'List' && Array.isArray(content.items)) ? content.items :
157
+ [content];
158
+ for (const resource of resources) {
159
+ const kind = resource.kind.toLowerCase();
160
+ const name = resource.metadata?.name;
161
+ const ns = resource.metadata?.namespace || namespace;
162
+ if (!name) {
163
+ console.error(chalk.red('Resource must have a name'));
164
+ continue;
165
+ }
166
+ await deleteResource(client, kind, name, ns);
167
+ }
168
+ }
169
+ catch (error) {
170
+ console.error(chalk.red(`Error processing YAML file: ${error}`));
171
+ }
172
+ }
173
+ export default async (argv, prompter, _options) => {
174
+ try {
175
+ const client = new KubernetesClient({
176
+ restEndpoint: 'http://localhost:8001' // Default kube-proxy endpoint
177
+ });
178
+ const namespace = argv.n || argv.namespace || getCurrentNamespace();
179
+ if (argv.f || argv.filename) {
180
+ const filePath = argv.f || argv.filename;
181
+ if (!fs.existsSync(filePath)) {
182
+ console.error(chalk.red(`File not found: ${filePath}`));
183
+ return;
184
+ }
185
+ await deleteFromYaml(client, filePath, namespace);
186
+ return;
187
+ }
188
+ const resourceType = argv._?.[0] || await promptResourceType(prompter, argv);
189
+ const resourceName = argv._?.[1];
190
+ if (resourceName) {
191
+ await deleteResource(client, resourceType, resourceName, namespace);
192
+ }
193
+ else {
194
+ const selectedResources = await promptResourceSelection(prompter, argv, resourceType, namespace, client);
195
+ if (selectedResources.length === 0) {
196
+ console.log(chalk.yellow('No resources selected for deletion'));
197
+ return;
198
+ }
199
+ const confirmQuestion = {
200
+ type: 'confirm',
201
+ name: 'confirmDelete',
202
+ message: `Are you sure you want to delete ${selectedResources.length} ${resourceType}(s)?`,
203
+ required: true
204
+ };
205
+ const { confirmDelete } = await prompter.prompt(argv, [confirmQuestion]);
206
+ if (!confirmDelete) {
207
+ console.log(chalk.yellow('Deletion cancelled'));
208
+ return;
209
+ }
210
+ for (const resource of selectedResources) {
211
+ await deleteResource(client, resourceType, resource, namespace);
212
+ }
213
+ }
214
+ }
215
+ catch (error) {
216
+ console.error(chalk.red(`Error: ${error}`));
217
+ }
218
+ };