@botim/botim-cli 0.0.4 → 0.0.6

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 (3) hide show
  1. package/dist/cli.js +144 -64
  2. package/dist/cli.mjs +6 -6
  3. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -1,21 +1,31 @@
1
1
  #!/usr/bin/env node
2
+ {
3
+ const origEmit = process.emit;
4
+ process.emit = function(name, data, ...args) {
5
+ if (name === "warning" && data && data.name === "DeprecationWarning") {
6
+ return false;
7
+ }
8
+ return origEmit.call(process, name, data, ...args);
9
+ };
10
+ }
2
11
  import { Command } from "commander";
3
12
  import { createReactApp, createVueApp, handleLogin, handleLogout, handleQRCode } from "./commands/index.js";
4
13
  import { showMenuOrRequireAuth } from "./commands/auth/index.js";
5
14
  import { displayExamples, displayQuickStart } from "./utils/help.js";
6
- import { logger } from "./utils/logger.js";
15
+ import { logger, displayErrorSync } from "./utils/logger.js";
7
16
  import { isLoggedIn, getCurrentEnvironment, setCurrentEnvironment, getAllEnvironmentStatus } from "./utils/config.js";
8
17
  import { setRuntimeEnvironment, parseEnvironment, getEnvironmentDisplayName } from "./utils/environment.js";
18
+ import { executeWithAuthRetry } from "./utils/auth-handler.js";
9
19
  import chalk from "chalk";
10
20
  import fs from "fs-extra";
11
21
  import path from "path";
12
- const version = "0.0.4";
22
+ const version = "0.0.6";
13
23
  const program = new Command();
14
- program.name("botim-cli").description("CLI tool to generate boilerplate code for React and Vue applications").version(version, "-v, --version", "Output the current version").option("--env <environment>", "Target environment: prod or uat (overrides default)", (value) => {
24
+ program.name("botim-cli").description("CLI tool to generate boilerplate code for React and Vue applications").version(version, "-v, --version", "Output the current version").option("--env <environment>", "Target environment: prod, uat, or beta (overrides default)", (value) => {
15
25
  const env = parseEnvironment(value);
16
26
  if (!env) {
17
27
  console.error(chalk.red(`
18
- Invalid environment: ${value}. Valid values: prod, uat
28
+ Invalid environment: ${value}. Valid values: prod, uat, beta
19
29
  `));
20
30
  process.exit(1);
21
31
  }
@@ -108,10 +118,20 @@ program.command("status").description("Show login status for all environments").
108
118
  console.log(chalk.gray(" Not logged in"));
109
119
  }
110
120
  console.log("");
121
+ const betaStatus = allStatus.beta;
122
+ const betaIndicator = betaStatus.loggedIn ? chalk.green("\u2713") : chalk.red("\u2717");
123
+ const betaActive = currentEnv === "beta" ? chalk.cyan(" (active)") : "";
124
+ console.log(` ${betaIndicator} Beta${betaActive}`);
125
+ if (betaStatus.loggedIn && betaStatus.partnerName) {
126
+ console.log(chalk.gray(` Partner: ${betaStatus.partnerName}`));
127
+ } else if (!betaStatus.loggedIn) {
128
+ console.log(chalk.gray(" Not logged in"));
129
+ }
130
+ console.log("");
111
131
  console.log(chalk.gray("Tips:"));
112
132
  console.log(chalk.gray(" Switch environment: botim-cli config set env uat"));
113
- console.log(chalk.gray(" One-time override: botim-cli --env uat <command>"));
114
- console.log(chalk.gray(" Login to uat: botim-cli --env uat login\n"));
133
+ console.log(chalk.gray(" One-time override: botim-cli --env beta <command>"));
134
+ console.log(chalk.gray(" Login to beta: botim-cli --env beta login\n"));
115
135
  });
116
136
  program.command("auth").description("Access authenticated commands (requires login)").alias("authenticated").action(async () => {
117
137
  await showMenuOrRequireAuth();
@@ -166,88 +186,133 @@ Audience Options:
166
186
  1 - Private (only accessible to specific users)
167
187
  2 - Public (accessible to all users) (default)
168
188
  `).action(async (options) => {
169
- const loggedIn = await isLoggedIn();
170
- if (!loggedIn) {
171
- const currentEnv = await getCurrentEnvironment();
172
- const envDisplay = getEnvironmentDisplayName(currentEnv);
173
- console.log(chalk.red(`
189
+ try {
190
+ const loggedIn = await isLoggedIn();
191
+ if (!loggedIn) {
192
+ const currentEnv = await getCurrentEnvironment();
193
+ const envDisplay = getEnvironmentDisplayName(currentEnv);
194
+ console.log(chalk.red(`
174
195
  \u274C Authentication required for ${envDisplay}. Please login first using: botim-cli ${currentEnv === "uat" ? "--env uat " : ""}login
175
196
  `));
197
+ process.exit(1);
198
+ }
199
+ const { authenticatedCommandRegistry } = await import("./commands/auth/index.js");
200
+ const command = authenticatedCommandRegistry.get("cmp");
201
+ if (command) {
202
+ const processedOptions = {
203
+ ...options,
204
+ audience: parseInt(options.audience, 10)
205
+ };
206
+ await executeWithAuthRetry(
207
+ () => command.execute(processedOptions),
208
+ { commandName: "create-mp-app", retryAfterLogin: true }
209
+ );
210
+ }
211
+ } catch (error) {
212
+ logger.error("create-mp-app command failed", error);
213
+ displayErrorSync(error, "Create MP App failed");
176
214
  process.exit(1);
177
215
  }
178
- const { authenticatedCommandRegistry } = await import("./commands/auth/index.js");
179
- const command = authenticatedCommandRegistry.get("cmp");
180
- if (command) {
181
- const processedOptions = {
182
- ...options,
183
- audience: parseInt(options.audience, 10)
184
- };
185
- await command.execute(processedOptions);
186
- }
187
216
  });
188
217
  program.command("init-mp-app").description("Initialize MP app in current directory (requires authentication)").alias("init-mp").action(async () => {
189
- const loggedIn = await isLoggedIn();
190
- if (!loggedIn) {
191
- const currentEnv = await getCurrentEnvironment();
192
- const envDisplay = getEnvironmentDisplayName(currentEnv);
193
- console.log(chalk.red(`
218
+ try {
219
+ const loggedIn = await isLoggedIn();
220
+ if (!loggedIn) {
221
+ const currentEnv = await getCurrentEnvironment();
222
+ const envDisplay = getEnvironmentDisplayName(currentEnv);
223
+ console.log(chalk.red(`
194
224
  \u274C Authentication required for ${envDisplay}. Please login first using: botim-cli ${currentEnv === "uat" ? "--env uat " : ""}login
195
225
  `));
226
+ process.exit(1);
227
+ }
228
+ const { authenticatedCommandRegistry } = await import("./commands/auth/index.js");
229
+ const command = authenticatedCommandRegistry.get("init-mp-app");
230
+ if (command) {
231
+ await executeWithAuthRetry(
232
+ () => command.execute(),
233
+ { commandName: "init-mp-app", retryAfterLogin: true }
234
+ );
235
+ }
236
+ } catch (error) {
237
+ logger.error("init-mp-app command failed", error);
238
+ displayErrorSync(error, "Init MP App failed");
196
239
  process.exit(1);
197
240
  }
198
- const { authenticatedCommandRegistry } = await import("./commands/auth/index.js");
199
- const command = authenticatedCommandRegistry.get("init-mp-app");
200
- if (command) {
201
- await command.execute();
202
- }
203
241
  });
204
242
  program.command("deploy-mp-app").description("Deploy MP app to server (requires authentication)").alias("deploy").option("-w, --website <url>", "Website/Endpoint URL (required for H5BRIDGE apps)").option("-n, --note <note>", 'Review note (optional, defaults to "Deployed via CLI")').option("-t, --testflight", "Release to TestFlight (Beta) - this is the default for direct mode").option("-y, --yes", "Skip confirmation prompts (Note: Production releases require interactive mode)").action(async (options) => {
205
- const loggedIn = await isLoggedIn();
206
- if (!loggedIn) {
207
- const currentEnv = await getCurrentEnvironment();
208
- const envDisplay = getEnvironmentDisplayName(currentEnv);
209
- console.log(chalk.red(`
243
+ try {
244
+ const loggedIn = await isLoggedIn();
245
+ if (!loggedIn) {
246
+ const currentEnv = await getCurrentEnvironment();
247
+ const envDisplay = getEnvironmentDisplayName(currentEnv);
248
+ console.log(chalk.red(`
210
249
  \u274C Authentication required for ${envDisplay}. Please login first using: botim-cli ${currentEnv === "uat" ? "--env uat " : ""}login
211
250
  `));
251
+ process.exit(1);
252
+ }
253
+ const { authenticatedCommandRegistry } = await import("./commands/auth/index.js");
254
+ const command = authenticatedCommandRegistry.get("deploy-mp-app");
255
+ if (command) {
256
+ await executeWithAuthRetry(
257
+ () => command.execute(options),
258
+ { commandName: "deploy-mp-app", retryAfterLogin: true }
259
+ );
260
+ }
261
+ } catch (error) {
262
+ logger.error("deploy-mp-app command failed", error);
263
+ displayErrorSync(error, "Deployment failed");
212
264
  process.exit(1);
213
265
  }
214
- const { authenticatedCommandRegistry } = await import("./commands/auth/index.js");
215
- const command = authenticatedCommandRegistry.get("deploy-mp-app");
216
- if (command) {
217
- await command.execute(options);
218
- }
219
266
  });
220
267
  program.command("debug-mp-app").description("Debug MP app (requires authentication and botim_config.json)").alias("debug").action(async () => {
221
- const loggedIn = await isLoggedIn();
222
- if (!loggedIn) {
223
- const currentEnv = await getCurrentEnvironment();
224
- const envDisplay = getEnvironmentDisplayName(currentEnv);
225
- console.log(chalk.red(`
268
+ try {
269
+ const loggedIn = await isLoggedIn();
270
+ if (!loggedIn) {
271
+ const currentEnv = await getCurrentEnvironment();
272
+ const envDisplay = getEnvironmentDisplayName(currentEnv);
273
+ console.log(chalk.red(`
226
274
  \u274C Authentication required for ${envDisplay}. Please login first using: botim-cli ${currentEnv === "uat" ? "--env uat " : ""}login
227
275
  `));
276
+ process.exit(1);
277
+ }
278
+ const { authenticatedCommandRegistry } = await import("./commands/auth/index.js");
279
+ const command = authenticatedCommandRegistry.get("debug-mp-app");
280
+ if (command) {
281
+ await executeWithAuthRetry(
282
+ () => command.execute(),
283
+ { commandName: "debug-mp-app", retryAfterLogin: true }
284
+ );
285
+ }
286
+ } catch (error) {
287
+ logger.error("debug-mp-app command failed", error);
288
+ displayErrorSync(error, "Debug MP App failed");
228
289
  process.exit(1);
229
290
  }
230
- const { authenticatedCommandRegistry } = await import("./commands/auth/index.js");
231
- const command = authenticatedCommandRegistry.get("debug-mp-app");
232
- if (command) {
233
- await command.execute();
234
- }
235
291
  });
236
292
  program.command("list-mp-permissions [app-id]").description("List permissions for a mini-program app (requires authentication)").alias("perms").action(async (appId) => {
237
- const loggedIn = await isLoggedIn();
238
- if (!loggedIn) {
239
- const currentEnv = await getCurrentEnvironment();
240
- const envDisplay = getEnvironmentDisplayName(currentEnv);
241
- console.log(chalk.red(`
293
+ try {
294
+ const loggedIn = await isLoggedIn();
295
+ if (!loggedIn) {
296
+ const currentEnv = await getCurrentEnvironment();
297
+ const envDisplay = getEnvironmentDisplayName(currentEnv);
298
+ console.log(chalk.red(`
242
299
  \u274C Authentication required for ${envDisplay}. Please login first using: botim-cli ${currentEnv === "uat" ? "--env uat " : ""}login
243
300
  `));
301
+ process.exit(1);
302
+ }
303
+ const { authenticatedCommandRegistry } = await import("./commands/auth/index.js");
304
+ const command = authenticatedCommandRegistry.get("list-mp-permissions");
305
+ if (command) {
306
+ await executeWithAuthRetry(
307
+ () => command.execute({ appId }),
308
+ { commandName: "list-mp-permissions", retryAfterLogin: true }
309
+ );
310
+ }
311
+ } catch (error) {
312
+ logger.error("list-mp-permissions command failed", error);
313
+ displayErrorSync(error, "List MP Permissions failed");
244
314
  process.exit(1);
245
315
  }
246
- const { authenticatedCommandRegistry } = await import("./commands/auth/index.js");
247
- const command = authenticatedCommandRegistry.get("list-mp-permissions");
248
- if (command) {
249
- await command.execute({ appId });
250
- }
251
316
  });
252
317
  const configCommand = program.command("config").description("Manage CLI configuration");
253
318
  configCommand.command("set <key> <value>").description("Set a configuration value").action(async (key, value) => {
@@ -259,7 +324,7 @@ configCommand.command("set <key> <value>").description("Set a configuration valu
259
324
  if (!env) {
260
325
  console.log(chalk.red(`\u274C Invalid environment: ${value}
261
326
  `));
262
- console.log(chalk.yellow("Valid values: prod, production, uat\n"));
327
+ console.log(chalk.yellow("Valid values: prod, production, uat, beta\n"));
263
328
  process.exit(1);
264
329
  }
265
330
  await setCurrentEnvironment(env);
@@ -288,7 +353,7 @@ configCommand.command("set <key> <value>").description("Set a configuration valu
288
353
  console.log(chalk.red(`\u274C Unknown configuration key: ${key}
289
354
  `));
290
355
  console.log(chalk.yellow("Available keys:\n"));
291
- console.log(chalk.yellow(" - env (or environment): Set default environment (prod, uat)\n"));
356
+ console.log(chalk.yellow(" - env (or environment): Set default environment (prod, uat, beta)\n"));
292
357
  console.log(chalk.yellow("\nNote: Template repository URLs are configured via .env file, not CLI commands.\n"));
293
358
  process.exit(1);
294
359
  }
@@ -529,9 +594,13 @@ async function showMainMenu() {
529
594
  const command = authenticatedCommandRegistry.get(commandName);
530
595
  if (command) {
531
596
  try {
532
- await command.execute();
597
+ await executeWithAuthRetry(
598
+ () => command.execute(),
599
+ { commandName, retryAfterLogin: true }
600
+ );
533
601
  } catch (error) {
534
- console.error(chalk.red("\n\u274C Error executing command:"), error);
602
+ logger.error("Command execution failed", error);
603
+ displayErrorSync(error, "Command failed");
535
604
  process.exit(1);
536
605
  }
537
606
  }
@@ -578,6 +647,10 @@ async function showMainMenu() {
578
647
  name: `UAT ${allStatus.uat.loggedIn ? chalk.green("\u2713 Logged in") : chalk.gray("(not logged in)")}${currentEnv === "uat" ? chalk.cyan(" \u2190 current") : ""}`,
579
648
  value: "uat"
580
649
  },
650
+ {
651
+ name: `Beta ${allStatus.beta.loggedIn ? chalk.green("\u2713 Logged in") : chalk.gray("(not logged in)")}${currentEnv === "beta" ? chalk.cyan(" \u2190 current") : ""}`,
652
+ value: "beta"
653
+ },
581
654
  new inquirer.Separator(),
582
655
  { name: "\u2190 Back to main menu", value: "back" }
583
656
  ]
@@ -619,6 +692,13 @@ async function showMainMenu() {
619
692
  if (uatStatus.loggedIn && uatStatus.partnerName) {
620
693
  console.log(chalk.gray(` Partner: ${uatStatus.partnerName}`));
621
694
  }
695
+ const betaStatus = allStatus.beta;
696
+ const betaIndicator = betaStatus.loggedIn ? chalk.green("\u2713") : chalk.red("\u2717");
697
+ const betaActive = currentEnv === "beta" ? chalk.cyan(" (active)") : "";
698
+ console.log(` ${betaIndicator} Beta${betaActive}`);
699
+ if (betaStatus.loggedIn && betaStatus.partnerName) {
700
+ console.log(chalk.gray(` Partner: ${betaStatus.partnerName}`));
701
+ }
622
702
  console.log("");
623
703
  await showMainMenu();
624
704
  } else if (action === "login") {