@chabokan.net/cli 0.8.10 → 0.8.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -20,7 +20,7 @@ $ npm install -g @chabokan.net/cli
20
20
  $ chabok COMMAND
21
21
  running command...
22
22
  $ chabok (--version|-v)
23
- @chabokan.net/cli/0.8.10 darwin-arm64 node-v20.13.1
23
+ @chabokan.net/cli/0.8.15 darwin-arm64 node-v20.13.1
24
24
  $ chabok --help [COMMAND]
25
25
  USAGE
26
26
  $ chabok COMMAND
@@ -69,7 +69,7 @@ DESCRIPTION
69
69
  show accounts list
70
70
  ```
71
71
 
72
- _See code: [src/commands/account/list.ts](https://github.com/chabokan/cli/blob/v0.8.10/src/commands/account/list.ts)_
72
+ _See code: [src/commands/account/list.ts](https://github.com/chabokan/cli/blob/v0.8.15/src/commands/account/list.ts)_
73
73
 
74
74
  ## `chabok account remove`
75
75
 
@@ -86,7 +86,7 @@ DESCRIPTION
86
86
  remove account from list
87
87
  ```
88
88
 
89
- _See code: [src/commands/account/remove.ts](https://github.com/chabokan/cli/blob/v0.8.10/src/commands/account/remove.ts)_
89
+ _See code: [src/commands/account/remove.ts](https://github.com/chabokan/cli/blob/v0.8.15/src/commands/account/remove.ts)_
90
90
 
91
91
  ## `chabok account use`
92
92
 
@@ -104,7 +104,7 @@ DESCRIPTION
104
104
  switch your default user between logged in users
105
105
  ```
106
106
 
107
- _See code: [src/commands/account/use.ts](https://github.com/chabokan/cli/blob/v0.8.10/src/commands/account/use.ts)_
107
+ _See code: [src/commands/account/use.ts](https://github.com/chabokan/cli/blob/v0.8.15/src/commands/account/use.ts)_
108
108
 
109
109
  ## `chabok autocomplete [SHELL]`
110
110
 
@@ -154,7 +154,7 @@ DESCRIPTION
154
154
  this command help you build and deploy your service to chabokan in easy way.
155
155
  ```
156
156
 
157
- _See code: [src/commands/deploy.ts](https://github.com/chabokan/cli/blob/v0.8.10/src/commands/deploy.ts)_
157
+ _See code: [src/commands/deploy.ts](https://github.com/chabokan/cli/blob/v0.8.15/src/commands/deploy.ts)_
158
158
 
159
159
  ## `chabok help [COMMAND]`
160
160
 
@@ -194,7 +194,7 @@ DESCRIPTION
194
194
  login to hub.chabokan.net account
195
195
  ```
196
196
 
197
- _See code: [src/commands/login.ts](https://github.com/chabokan/cli/blob/v0.8.10/src/commands/login.ts)_
197
+ _See code: [src/commands/login.ts](https://github.com/chabokan/cli/blob/v0.8.15/src/commands/login.ts)_
198
198
 
199
199
  ## `chabok plugins`
200
200
 
@@ -501,7 +501,7 @@ DESCRIPTION
501
501
  show account services list
502
502
  ```
503
503
 
504
- _See code: [src/commands/service/list.ts](https://github.com/chabokan/cli/blob/v0.8.10/src/commands/service/list.ts)_
504
+ _See code: [src/commands/service/list.ts](https://github.com/chabokan/cli/blob/v0.8.15/src/commands/service/list.ts)_
505
505
 
506
506
  ## `chabok service logs`
507
507
 
@@ -519,7 +519,7 @@ DESCRIPTION
519
519
  read latest logs from service
520
520
  ```
521
521
 
522
- _See code: [src/commands/service/logs.ts](https://github.com/chabokan/cli/blob/v0.8.10/src/commands/service/logs.ts)_
522
+ _See code: [src/commands/service/logs.ts](https://github.com/chabokan/cli/blob/v0.8.15/src/commands/service/logs.ts)_
523
523
 
524
524
  ## `chabok service resize`
525
525
 
@@ -540,7 +540,7 @@ DESCRIPTION
540
540
  resize a service
541
541
  ```
542
542
 
543
- _See code: [src/commands/service/resize.ts](https://github.com/chabokan/cli/blob/v0.8.10/src/commands/service/resize.ts)_
543
+ _See code: [src/commands/service/resize.ts](https://github.com/chabokan/cli/blob/v0.8.15/src/commands/service/resize.ts)_
544
544
 
545
545
  ## `chabok service restart`
546
546
 
@@ -558,7 +558,7 @@ DESCRIPTION
558
558
  restart a service
559
559
  ```
560
560
 
561
- _See code: [src/commands/service/restart.ts](https://github.com/chabokan/cli/blob/v0.8.10/src/commands/service/restart.ts)_
561
+ _See code: [src/commands/service/restart.ts](https://github.com/chabokan/cli/blob/v0.8.15/src/commands/service/restart.ts)_
562
562
 
563
563
  ## `chabok service start`
564
564
 
@@ -576,7 +576,7 @@ DESCRIPTION
576
576
  start a service
577
577
  ```
578
578
 
579
- _See code: [src/commands/service/start.ts](https://github.com/chabokan/cli/blob/v0.8.10/src/commands/service/start.ts)_
579
+ _See code: [src/commands/service/start.ts](https://github.com/chabokan/cli/blob/v0.8.15/src/commands/service/start.ts)_
580
580
 
581
581
  ## `chabok service stop`
582
582
 
@@ -594,7 +594,7 @@ DESCRIPTION
594
594
  stop a service
595
595
  ```
596
596
 
597
- _See code: [src/commands/service/stop.ts](https://github.com/chabokan/cli/blob/v0.8.10/src/commands/service/stop.ts)_
597
+ _See code: [src/commands/service/stop.ts](https://github.com/chabokan/cli/blob/v0.8.15/src/commands/service/stop.ts)_
598
598
 
599
599
  ## `chabok version`
600
600
 
package/dist/base.d.ts CHANGED
@@ -1,15 +1,17 @@
1
1
  import { Command } from '@oclif/core';
2
+ import { AxiosRequestConfig } from 'axios';
3
+ import type { ConfigFile } from './types.js';
2
4
  export default abstract class extends Command {
3
5
  static flags: {
4
6
  help: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<void>;
5
7
  };
6
- axiosConfig: any;
8
+ axiosConfig: AxiosRequestConfig;
7
9
  got: import("got").Got<never>;
8
- read_config(): Promise<{
9
- users: {};
10
- default_user: string;
11
- }>;
12
- write_config(object: any): Promise<void>;
13
- get_services(filter?: {}): Promise<any>;
10
+ read_config(): Promise<ConfigFile>;
11
+ write_config(object: ConfigFile): Promise<void>;
12
+ get_services(filter?: Record<string, string>): Promise<Array<{
13
+ value: string;
14
+ name: string;
15
+ }>>;
14
16
  init_run(): Promise<void>;
15
17
  }
package/dist/base.js CHANGED
@@ -11,14 +11,15 @@ export default class default_1 extends Command {
11
11
  help: Flags.help({ char: 'h' }),
12
12
  };
13
13
  axiosConfig = {
14
- ...axios.defaults
14
+ ...axios.defaults,
15
+ headers: {}
15
16
  };
16
17
  got = got.extend();
17
18
  async read_config() {
18
19
  return read_config_file();
19
20
  }
20
21
  async write_config(object) {
21
- fs.writeFileSync(GLOBAL_CONF_PATH, JSON.stringify(object));
22
+ fs.writeFileSync(GLOBAL_CONF_PATH, JSON.stringify(object, null, 2));
22
23
  }
23
24
  async get_services(filter = {}) {
24
25
  return await get_all_services(filter, this.axiosConfig);
@@ -28,20 +29,19 @@ export default class default_1 extends Command {
28
29
  const main_agent = new https.Agent({
29
30
  rejectUnauthorized: false
30
31
  });
31
- // @ts-ignore
32
- const gotConfig = {};
32
+ const gotConfig = {
33
+ prefixUrl: BASE_API_URL,
34
+ agent: { https: main_agent }
35
+ };
33
36
  this.axiosConfig.httpsAgent = main_agent;
34
37
  this.axiosConfig.baseURL = BASE_API_URL;
35
- gotConfig.prefixUrl = this.axiosConfig.baseURL;
36
- gotConfig.agent = { https: main_agent };
37
38
  const proxy = process.env.http_proxy || process.env.https_proxy;
38
39
  if (proxy) {
39
40
  this.log(`Using proxy server ${proxy}`);
40
- // @ts-ignore
41
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call
41
42
  const agent = new HttpsProxyAgent(proxy);
42
43
  this.axiosConfig.httpsAgent = agent;
43
44
  this.axiosConfig.proxy = false;
44
- // @ts-ignore
45
45
  gotConfig.agent = { https: agent };
46
46
  }
47
47
  const config_json = read_config_file();
@@ -49,9 +49,12 @@ export default class default_1 extends Command {
49
49
  if (isEmptyObject(config_json) || isEmptyObject(config_json.users)) {
50
50
  return;
51
51
  }
52
- // @ts-ignore
53
- const token = config_json.users[config_json.default_user]["token"] || null;
52
+ const defaultUser = config_json.default_user;
53
+ const token = defaultUser && config_json.users[defaultUser]?.token;
54
54
  if (token) {
55
+ if (!this.axiosConfig.headers) {
56
+ this.axiosConfig.headers = {};
57
+ }
55
58
  this.axiosConfig.headers.Authorization = `Token ${token}`;
56
59
  gotConfig.headers = { Authorization: `Token ${token}` };
57
60
  }
@@ -1,28 +1,37 @@
1
1
  import Command from "../../base.js";
2
2
  import { ux } from "@oclif/core";
3
+ import chalk from "chalk";
3
4
  export default class AccountList extends Command {
4
5
  static description = "show accounts list";
5
6
  static flags = {
6
7
  ...Command.flags,
7
8
  };
8
9
  async run() {
9
- const { args, flags } = await this.parse(AccountList);
10
+ const { flags } = await this.parse(AccountList);
10
11
  const cli = this;
11
- await this.init_run();
12
- const config_json = await this.read_config();
13
- if (Object.keys(config_json.users).length > 0) {
14
- const accounts_data = Object.keys(config_json.users).map((account) => {
15
- return {
16
- Name: account,
17
- };
18
- });
19
- ux.table(accounts_data, {
20
- Name: {},
21
- }, flags);
12
+ try {
13
+ await this.init_run();
14
+ const config_json = await this.read_config();
15
+ if (Object.keys(config_json.users).length > 0) {
16
+ const accounts_data = Object.keys(config_json.users).map((account) => {
17
+ return {
18
+ Name: account,
19
+ };
20
+ });
21
+ ux.table(accounts_data, {
22
+ Name: {},
23
+ }, flags);
24
+ }
25
+ else {
26
+ cli.log(`${chalk.yellow('[Info]')} No accounts found. Please login first using 'chabok login'.`);
27
+ return;
28
+ }
22
29
  }
23
- else {
24
- cli.log("first you should login");
25
- return;
30
+ catch (error) {
31
+ cli.log(`${chalk.red('[Error]')} Failed to list accounts. Please try again.`);
32
+ if (process.env.CHABOK_DEBUG === "true") {
33
+ cli.log(error);
34
+ }
26
35
  }
27
36
  }
28
37
  }
@@ -11,24 +11,28 @@ export default class AccountRemove extends Command {
11
11
  };
12
12
  async run() {
13
13
  const cli = this;
14
- const { args, flags } = await this.parse(AccountRemove);
14
+ const { flags } = await this.parse(AccountRemove);
15
15
  const config_json = read_config_file();
16
16
  if (isEmptyObject(config_json.users)) {
17
17
  cli.log(`${chalk.red("[Error]")} first you should login!`);
18
18
  return;
19
19
  }
20
- let { user } = await inquirer.prompt({
20
+ const { user } = await inquirer.prompt({
21
21
  type: "list",
22
22
  message: "Please select a user:",
23
23
  name: "user",
24
24
  choices: Object.keys(config_json.users),
25
25
  });
26
- // @ts-ignore
27
- delete config_json.users[user];
28
- if (config_json["default_user"] == user) {
29
- config_json["default_user"] = "";
26
+ if (user in config_json.users) {
27
+ delete config_json.users[user];
28
+ if (config_json.default_user === user) {
29
+ config_json.default_user = "";
30
+ }
31
+ fs.writeFileSync(GLOBAL_CONF_PATH, JSON.stringify(config_json, null, 2));
32
+ cli.log(`${chalk.green("[Success]")} user deleted successfully.`);
33
+ }
34
+ else {
35
+ cli.log(`${chalk.red("[Error]")} selected user does not exist!`);
30
36
  }
31
- fs.writeFileSync(GLOBAL_CONF_PATH, JSON.stringify(config_json));
32
- cli.log(`${chalk.green("[Success]")} user deleted successfully.`);
33
37
  }
34
38
  }
@@ -13,7 +13,7 @@ export default class AccountUse extends Command {
13
13
  };
14
14
  async run() {
15
15
  const cli = this;
16
- const { args, flags } = await this.parse(AccountUse);
16
+ const { flags } = await this.parse(AccountUse);
17
17
  const config_json = read_config_file();
18
18
  let default_user = flags.user;
19
19
  if (isEmptyObject(config_json.users)) {
@@ -21,7 +21,7 @@ export default class AccountUse extends Command {
21
21
  return;
22
22
  }
23
23
  if (!flags.user) {
24
- let { user } = await inquirer.prompt({
24
+ const { user } = await inquirer.prompt({
25
25
  type: "list",
26
26
  message: "Please select a user:",
27
27
  name: "user",
@@ -29,13 +29,13 @@ export default class AccountUse extends Command {
29
29
  });
30
30
  default_user = user;
31
31
  }
32
- if (default_user in config_json.users) {
33
- config_json["default_user"] = default_user;
34
- fs.writeFileSync(GLOBAL_CONF_PATH, JSON.stringify(config_json));
32
+ if (default_user && default_user in config_json.users) {
33
+ config_json.default_user = default_user;
34
+ fs.writeFileSync(GLOBAL_CONF_PATH, JSON.stringify(config_json, null, 2));
35
35
  cli.log(`${chalk.green("[Success]")} user changed successfully.`);
36
36
  }
37
37
  else {
38
- cli.log(`${chalk.red("[Error]")} selected user not exist!`);
38
+ cli.log(`${chalk.red("[Error]")} selected user does not exist!`);
39
39
  }
40
40
  }
41
41
  }
@@ -1,4 +1,5 @@
1
1
  import Command from "../base.js";
2
+ import type { ChabokFile } from "../types.js";
2
3
  export default class Deploy extends Command {
3
4
  static description: string;
4
5
  static flags: {
@@ -7,8 +8,8 @@ export default class Deploy extends Command {
7
8
  help: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<void>;
8
9
  };
9
10
  run(): Promise<void>;
10
- prepare_archive(project_path: any): Promise<string>;
11
- upload(archive_path: any, selected_service: any, cli: any, chabok_file: any): Promise<{
11
+ prepare_archive(project_path: string): Promise<string>;
12
+ upload(archive_path: string, selected_service: string, cli: Command, chabok_file: ChabokFile): Promise<{
12
13
  success: boolean;
13
14
  message: string;
14
15
  }>;
@@ -2,7 +2,7 @@ import { Flags } from "@oclif/core";
2
2
  import inquirer from "inquirer";
3
3
  import chalk from "chalk";
4
4
  import Command from "../base.js";
5
- import { addIgnorePatterns, isEmptyObject } from "../helper.js";
5
+ import { addIgnorePatterns, isEmptyObject, handleApiError, logErrorDetails } from "../helper.js";
6
6
  import ProgressBar from "progress";
7
7
  import FormData from "form-data";
8
8
  import ignore from "ignore";
@@ -23,21 +23,25 @@ export default class Deploy extends Command {
23
23
  service: Flags.string({ char: "s", description: "service name" }),
24
24
  };
25
25
  async run() {
26
- const { args, flags } = await this.parse(Deploy);
26
+ const { flags } = await this.parse(Deploy);
27
27
  const cli = this;
28
28
  await this.init_run();
29
29
  const config_json = await this.read_config();
30
30
  let selected_service = flags.service;
31
- let project_path = flags.path ? flags.path : process.cwd();
31
+ const project_path = flags.path ? flags.path : process.cwd();
32
32
  let chabok_file = { service: "" };
33
33
  try {
34
- chabok_file =
35
- JSON.parse(fs
36
- .readFileSync(path.join(project_path, "chabok.json"))
37
- .toString("utf-8")) || {};
38
- cli.log("Reading Config from chabok.json ...");
34
+ const chabokFilePath = path.join(project_path, "chabok.json");
35
+ if (fs.existsSync(chabokFilePath)) {
36
+ chabok_file = JSON.parse(fs.readFileSync(chabokFilePath).toString("utf-8")) || {};
37
+ cli.log("Reading Config from chabok.json ...");
38
+ }
39
+ }
40
+ catch (error) {
41
+ if (process.env.CHABOK_DEBUG === "true") {
42
+ cli.log(`Error reading chabok.json: ${error}`);
43
+ }
39
44
  }
40
- catch { }
41
45
  if (chabok_file.service) {
42
46
  selected_service = chabok_file.service;
43
47
  }
@@ -46,12 +50,12 @@ export default class Deploy extends Command {
46
50
  return;
47
51
  }
48
52
  if (!selected_service) {
49
- let all_services = await this.get_services({
53
+ const all_services = await this.get_services({
50
54
  has_deploy: "true",
51
55
  status: "on",
52
56
  });
53
57
  if (all_services.length > 0) {
54
- let { service } = await inquirer.prompt({
58
+ const { service } = await inquirer.prompt({
55
59
  type: "list",
56
60
  message: "Please select a service:",
57
61
  name: "service",
@@ -64,72 +68,106 @@ export default class Deploy extends Command {
64
68
  return;
65
69
  }
66
70
  }
67
- let archive_path = await this.prepare_archive(project_path);
68
- let upload_response = await this.upload(archive_path, selected_service, cli, chabok_file);
69
- if (upload_response.success) {
70
- cli.log(chalk.green(upload_response.message));
71
+ if (!selected_service) {
72
+ cli.log(`${chalk.red("[Error]")} No service selected.`);
73
+ return;
71
74
  }
72
- else {
73
- cli.log(chalk.red("[Error] " + upload_response.message));
75
+ try {
76
+ const archive_path = await this.prepare_archive(project_path);
77
+ const upload_response = await this.upload(archive_path, selected_service, cli, chabok_file);
78
+ if (upload_response.success) {
79
+ cli.log(chalk.green(upload_response.message));
80
+ }
81
+ else {
82
+ cli.log(chalk.red(`[Error] ${upload_response.message}`));
83
+ }
84
+ }
85
+ catch (error) {
86
+ const errorInfo = handleApiError(error, 'Deployment failed. Please check your project files and try again.', {
87
+ endpoint: `services/${selected_service}/deploy/`,
88
+ serviceName: selected_service,
89
+ operation: 'Deploy'
90
+ });
91
+ cli.log(chalk.red(`[Error] ${errorInfo.message}`));
92
+ logErrorDetails(errorInfo, cli);
74
93
  }
75
94
  }
76
95
  async prepare_archive(project_path) {
77
- const defaultIgnores = [
78
- ".npm",
79
- ".git",
80
- ".idea",
81
- ".DS_Store",
82
- ".vscode",
83
- "__pycache__",
84
- ".next",
85
- ".nuxt",
86
- "*.*~",
87
- "node_modules",
88
- "bower_components",
89
- "venv",
90
- "/vendor",
91
- "*.log",
92
- ];
93
- const ignoreCache = {};
94
- const ignoreInstance = ignore.default({ ignorecase: false });
95
- ignoreInstance.add(defaultIgnores);
96
- const ignoreFN = (f) => {
97
- const dir = dirname(f);
98
- if (!ignoreCache[dir]) {
99
- addIgnorePatterns(ignoreInstance, project_path, dir);
100
- ignoreCache[dir] = true;
96
+ try {
97
+ if (!fs.existsSync(project_path)) {
98
+ throw new Error(`Project path does not exist: ${project_path}`);
101
99
  }
102
- if (!ignoreInstance.ignores(f)) {
103
- return true;
100
+ if (!fs.statSync(project_path).isDirectory()) {
101
+ throw new Error(`Project path is not a directory: ${project_path}`);
104
102
  }
105
- console.log(`ignoring ${f}`);
106
- return false;
107
- };
108
- const tmpDir = path.join(os.tmpdir(), "/chabok-cli");
109
- const archivePath = path.join(tmpDir, `${Date.now()}.tar.gz`);
110
- fs.ensureDirSync(tmpDir);
111
- const fileList = fs.readdirSync(project_path).filter(ignoreFN);
112
- tar.c({
113
- gzip: {
114
- level: 9,
115
- },
116
- sync: true,
117
- cwd: project_path,
118
- filter: ignoreFN,
119
- file: archivePath,
120
- }, fileList);
121
- return archivePath;
103
+ const defaultIgnores = [
104
+ ".npm",
105
+ ".git",
106
+ ".idea",
107
+ ".DS_Store",
108
+ ".vscode",
109
+ "__pycache__",
110
+ ".next",
111
+ ".nuxt",
112
+ "*.*~",
113
+ "node_modules",
114
+ "bower_components",
115
+ "venv",
116
+ "/vendor",
117
+ "*.log",
118
+ ];
119
+ const ignoreCache = {};
120
+ const ignoreInstance = ignore.default({ ignorecase: false });
121
+ ignoreInstance.add(defaultIgnores);
122
+ const ignoreFN = (f) => {
123
+ const dir = dirname(f);
124
+ if (!ignoreCache[dir]) {
125
+ addIgnorePatterns(ignoreInstance, project_path, dir);
126
+ ignoreCache[dir] = true;
127
+ }
128
+ if (!ignoreInstance.ignores(f)) {
129
+ return true;
130
+ }
131
+ if (process.env.CHABOK_DEBUG === "true") {
132
+ console.log(`ignoring ${f}`);
133
+ }
134
+ return false;
135
+ };
136
+ const tmpDir = path.join(os.tmpdir(), "/chabok-cli");
137
+ const archivePath = path.join(tmpDir, `${Date.now()}.tar.gz`);
138
+ fs.ensureDirSync(tmpDir);
139
+ const fileList = fs.readdirSync(project_path).filter(ignoreFN);
140
+ if (fileList.length === 0) {
141
+ throw new Error(`No files to archive in ${project_path}. The directory may be empty or all files are ignored.`);
142
+ }
143
+ tar.c({
144
+ gzip: {
145
+ level: 9,
146
+ },
147
+ sync: true,
148
+ cwd: project_path,
149
+ filter: ignoreFN,
150
+ file: archivePath,
151
+ }, fileList);
152
+ return archivePath;
153
+ }
154
+ catch (error) {
155
+ if (error instanceof Error) {
156
+ throw new Error(`Failed to prepare archive: ${error.message}`);
157
+ }
158
+ throw new Error('Failed to prepare archive: Unknown error');
159
+ }
122
160
  }
123
161
  async upload(archive_path, selected_service, cli, chabok_file) {
124
- let upload_response = {
162
+ const upload_response = {
125
163
  success: false,
126
164
  message: "some problem",
127
165
  };
128
166
  const body = new FormData();
129
- // @ts-ignore
130
167
  body.append("file", fs.createReadStream(archive_path));
131
168
  body.append("options", JSON.stringify(chabok_file));
132
- const { size: sourceSize } = fs.statSync(archive_path);
169
+ const stats = fs.statSync(archive_path);
170
+ const sourceSize = stats.size;
133
171
  if (sourceSize > MAX_SOURCE_SIZE) {
134
172
  upload_response.message = "Source is too large. (max: 100MB)";
135
173
  return upload_response;
@@ -150,24 +188,31 @@ export default class Deploy extends Command {
150
188
  .json();
151
189
  if (response.success) {
152
190
  upload_response.success = true;
153
- upload_response.message = "Deployment finished successfully.";
191
+ upload_response.message = `Deployment to service '${selected_service}' finished successfully.`;
154
192
  }
155
193
  else {
156
- if (process.env.CHABOK_DEBUG == "true") {
157
- cli.log(response);
194
+ upload_response.message = `Deployment failed: ${String(response.message || "Unknown error occurred. Please try again.")}`;
195
+ if (process.env.CHABOK_DEBUG === "true") {
196
+ cli.log(JSON.stringify(response, null, 2));
158
197
  }
159
198
  }
160
199
  return upload_response;
161
200
  }
162
201
  catch (error) {
163
- if (process.env.CHABOK_DEBUG == "true") {
164
- cli.log(error);
165
- }
202
+ const errorInfo = handleApiError(error, 'Deployment failed. Please check your project files and network connection.', {
203
+ endpoint: `services/${selected_service}/deploy/`,
204
+ serviceName: selected_service,
205
+ operation: 'Upload Deployment'
206
+ });
207
+ upload_response.message = errorInfo.message;
208
+ logErrorDetails(errorInfo, cli);
166
209
  return upload_response;
167
210
  }
168
211
  finally {
169
212
  // cleanup
170
- fs.unlink(archive_path).catch(() => { });
213
+ fs.unlink(archive_path).catch(() => {
214
+ // Ignore cleanup errors
215
+ });
171
216
  }
172
217
  }
173
218
  }