@botim/botim-cli 0.0.3 → 0.0.5

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 +137 -72
  2. package/dist/cli.mjs +6 -6
  3. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -6,16 +6,17 @@ import { displayExamples, displayQuickStart } from "./utils/help.js";
6
6
  import { logger } from "./utils/logger.js";
7
7
  import { isLoggedIn, getCurrentEnvironment, setCurrentEnvironment, getAllEnvironmentStatus } from "./utils/config.js";
8
8
  import { setRuntimeEnvironment, parseEnvironment, getEnvironmentDisplayName } from "./utils/environment.js";
9
+ import { executeWithAuthRetry } from "./utils/auth-handler.js";
9
10
  import chalk from "chalk";
10
11
  import fs from "fs-extra";
11
12
  import path from "path";
12
- const version = "0.0.3";
13
+ const version = "0.0.5";
13
14
  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 beta (overrides default)", (value) => {
15
+ 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
16
  const env = parseEnvironment(value);
16
17
  if (!env) {
17
18
  console.error(chalk.red(`
18
- Invalid environment: ${value}. Valid values: prod, beta
19
+ Invalid environment: ${value}. Valid values: prod, uat, beta
19
20
  `));
20
21
  process.exit(1);
21
22
  }
@@ -64,7 +65,7 @@ program.command("quick-start").description("Show quick start guide").alias("qs")
64
65
  program.command("login").description("Login via QR code and save authentication token").action(async () => {
65
66
  const currentEnv = await getCurrentEnvironment();
66
67
  const envDisplay = getEnvironmentDisplayName(currentEnv);
67
- const envColor = currentEnv === "beta" ? chalk.yellow : chalk.green;
68
+ const envColor = currentEnv === "production" ? chalk.green : chalk.yellow;
68
69
  console.log(chalk.cyan.bold(`
69
70
  \u{1F510} Botim CLI v${version} - Login ${envColor(`[${envDisplay}]`)}
70
71
  `));
@@ -73,7 +74,7 @@ program.command("login").description("Login via QR code and save authentication
73
74
  program.command("logout").description("Logout and clear saved authentication token").option("--all", "Clear credentials for all environments").action(async (options) => {
74
75
  const currentEnv = await getCurrentEnvironment();
75
76
  const envDisplay = getEnvironmentDisplayName(currentEnv);
76
- const envColor = currentEnv === "beta" ? chalk.yellow : chalk.green;
77
+ const envColor = currentEnv === "production" ? chalk.green : chalk.yellow;
77
78
  console.log(chalk.cyan.bold(`
78
79
  \u{1F6AA} Botim CLI v${version} - Logout ${envColor(`[${envDisplay}]`)}
79
80
  `));
@@ -98,6 +99,16 @@ program.command("status").description("Show login status for all environments").
98
99
  console.log(chalk.gray(" Not logged in"));
99
100
  }
100
101
  console.log("");
102
+ const uatStatus = allStatus.uat;
103
+ const uatIndicator = uatStatus.loggedIn ? chalk.green("\u2713") : chalk.red("\u2717");
104
+ const uatActive = currentEnv === "uat" ? chalk.cyan(" (active)") : "";
105
+ console.log(` ${uatIndicator} UAT${uatActive}`);
106
+ if (uatStatus.loggedIn && uatStatus.partnerName) {
107
+ console.log(chalk.gray(` Partner: ${uatStatus.partnerName}`));
108
+ } else if (!uatStatus.loggedIn) {
109
+ console.log(chalk.gray(" Not logged in"));
110
+ }
111
+ console.log("");
101
112
  const betaStatus = allStatus.beta;
102
113
  const betaIndicator = betaStatus.loggedIn ? chalk.green("\u2713") : chalk.red("\u2717");
103
114
  const betaActive = currentEnv === "beta" ? chalk.cyan(" (active)") : "";
@@ -109,7 +120,7 @@ program.command("status").description("Show login status for all environments").
109
120
  }
110
121
  console.log("");
111
122
  console.log(chalk.gray("Tips:"));
112
- console.log(chalk.gray(" Switch environment: botim-cli config set env beta"));
123
+ console.log(chalk.gray(" Switch environment: botim-cli config set env uat"));
113
124
  console.log(chalk.gray(" One-time override: botim-cli --env beta <command>"));
114
125
  console.log(chalk.gray(" Login to beta: botim-cli --env beta login\n"));
115
126
  });
@@ -150,8 +161,8 @@ Examples:
150
161
  --audience 1 \\
151
162
  --reviewNote "Internal testing app"
152
163
 
153
- Use beta environment:
154
- $ botim-cli --env beta create-mp-app --projectName my-beta-app
164
+ Use UAT environment:
165
+ $ botim-cli --env uat create-mp-app --projectName my-uat-app
155
166
 
156
167
  Creator Types:
157
168
  hybrid - Fastest, local resources with full platform capabilities (default)
@@ -166,88 +177,128 @@ Audience Options:
166
177
  1 - Private (only accessible to specific users)
167
178
  2 - Public (accessible to all users) (default)
168
179
  `).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(`
174
- \u274C Authentication required for ${envDisplay}. Please login first using: botim-cli ${currentEnv === "beta" ? "--env beta " : ""}login
180
+ try {
181
+ const loggedIn = await isLoggedIn();
182
+ if (!loggedIn) {
183
+ const currentEnv = await getCurrentEnvironment();
184
+ const envDisplay = getEnvironmentDisplayName(currentEnv);
185
+ console.log(chalk.red(`
186
+ \u274C Authentication required for ${envDisplay}. Please login first using: botim-cli ${currentEnv === "uat" ? "--env uat " : ""}login
175
187
  `));
188
+ process.exit(1);
189
+ }
190
+ const { authenticatedCommandRegistry } = await import("./commands/auth/index.js");
191
+ const command = authenticatedCommandRegistry.get("cmp");
192
+ if (command) {
193
+ const processedOptions = {
194
+ ...options,
195
+ audience: parseInt(options.audience, 10)
196
+ };
197
+ await executeWithAuthRetry(
198
+ () => command.execute(processedOptions),
199
+ { commandName: "create-mp-app", retryAfterLogin: true }
200
+ );
201
+ }
202
+ } catch (error) {
203
+ logger.error("create-mp-app command failed", error);
176
204
  process.exit(1);
177
205
  }
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
206
  });
188
207
  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(`
194
- \u274C Authentication required for ${envDisplay}. Please login first using: botim-cli ${currentEnv === "beta" ? "--env beta " : ""}login
208
+ try {
209
+ const loggedIn = await isLoggedIn();
210
+ if (!loggedIn) {
211
+ const currentEnv = await getCurrentEnvironment();
212
+ const envDisplay = getEnvironmentDisplayName(currentEnv);
213
+ console.log(chalk.red(`
214
+ \u274C Authentication required for ${envDisplay}. Please login first using: botim-cli ${currentEnv === "uat" ? "--env uat " : ""}login
195
215
  `));
216
+ process.exit(1);
217
+ }
218
+ const { authenticatedCommandRegistry } = await import("./commands/auth/index.js");
219
+ const command = authenticatedCommandRegistry.get("init-mp-app");
220
+ if (command) {
221
+ await executeWithAuthRetry(
222
+ () => command.execute(),
223
+ { commandName: "init-mp-app", retryAfterLogin: true }
224
+ );
225
+ }
226
+ } catch (error) {
227
+ logger.error("init-mp-app command failed", error);
196
228
  process.exit(1);
197
229
  }
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
230
  });
204
231
  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(`
210
- \u274C Authentication required for ${envDisplay}. Please login first using: botim-cli ${currentEnv === "beta" ? "--env beta " : ""}login
232
+ try {
233
+ const loggedIn = await isLoggedIn();
234
+ if (!loggedIn) {
235
+ const currentEnv = await getCurrentEnvironment();
236
+ const envDisplay = getEnvironmentDisplayName(currentEnv);
237
+ console.log(chalk.red(`
238
+ \u274C Authentication required for ${envDisplay}. Please login first using: botim-cli ${currentEnv === "uat" ? "--env uat " : ""}login
211
239
  `));
240
+ process.exit(1);
241
+ }
242
+ const { authenticatedCommandRegistry } = await import("./commands/auth/index.js");
243
+ const command = authenticatedCommandRegistry.get("deploy-mp-app");
244
+ if (command) {
245
+ await executeWithAuthRetry(
246
+ () => command.execute(options),
247
+ { commandName: "deploy-mp-app", retryAfterLogin: true }
248
+ );
249
+ }
250
+ } catch (error) {
251
+ logger.error("deploy-mp-app command failed", error);
212
252
  process.exit(1);
213
253
  }
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
254
  });
220
255
  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(`
226
- \u274C Authentication required for ${envDisplay}. Please login first using: botim-cli ${currentEnv === "beta" ? "--env beta " : ""}login
256
+ try {
257
+ const loggedIn = await isLoggedIn();
258
+ if (!loggedIn) {
259
+ const currentEnv = await getCurrentEnvironment();
260
+ const envDisplay = getEnvironmentDisplayName(currentEnv);
261
+ console.log(chalk.red(`
262
+ \u274C Authentication required for ${envDisplay}. Please login first using: botim-cli ${currentEnv === "uat" ? "--env uat " : ""}login
227
263
  `));
264
+ process.exit(1);
265
+ }
266
+ const { authenticatedCommandRegistry } = await import("./commands/auth/index.js");
267
+ const command = authenticatedCommandRegistry.get("debug-mp-app");
268
+ if (command) {
269
+ await executeWithAuthRetry(
270
+ () => command.execute(),
271
+ { commandName: "debug-mp-app", retryAfterLogin: true }
272
+ );
273
+ }
274
+ } catch (error) {
275
+ logger.error("debug-mp-app command failed", error);
228
276
  process.exit(1);
229
277
  }
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
278
  });
236
279
  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(`
242
- \u274C Authentication required for ${envDisplay}. Please login first using: botim-cli ${currentEnv === "beta" ? "--env beta " : ""}login
280
+ try {
281
+ const loggedIn = await isLoggedIn();
282
+ if (!loggedIn) {
283
+ const currentEnv = await getCurrentEnvironment();
284
+ const envDisplay = getEnvironmentDisplayName(currentEnv);
285
+ console.log(chalk.red(`
286
+ \u274C Authentication required for ${envDisplay}. Please login first using: botim-cli ${currentEnv === "uat" ? "--env uat " : ""}login
243
287
  `));
288
+ process.exit(1);
289
+ }
290
+ const { authenticatedCommandRegistry } = await import("./commands/auth/index.js");
291
+ const command = authenticatedCommandRegistry.get("list-mp-permissions");
292
+ if (command) {
293
+ await executeWithAuthRetry(
294
+ () => command.execute({ appId }),
295
+ { commandName: "list-mp-permissions", retryAfterLogin: true }
296
+ );
297
+ }
298
+ } catch (error) {
299
+ logger.error("list-mp-permissions command failed", error);
244
300
  process.exit(1);
245
301
  }
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
302
  });
252
303
  const configCommand = program.command("config").description("Manage CLI configuration");
253
304
  configCommand.command("set <key> <value>").description("Set a configuration value").action(async (key, value) => {
@@ -259,7 +310,7 @@ configCommand.command("set <key> <value>").description("Set a configuration valu
259
310
  if (!env) {
260
311
  console.log(chalk.red(`\u274C Invalid environment: ${value}
261
312
  `));
262
- console.log(chalk.yellow("Valid values: prod, production, beta\n"));
313
+ console.log(chalk.yellow("Valid values: prod, production, uat, beta\n"));
263
314
  process.exit(1);
264
315
  }
265
316
  await setCurrentEnvironment(env);
@@ -288,7 +339,7 @@ configCommand.command("set <key> <value>").description("Set a configuration valu
288
339
  console.log(chalk.red(`\u274C Unknown configuration key: ${key}
289
340
  `));
290
341
  console.log(chalk.yellow("Available keys:\n"));
291
- console.log(chalk.yellow(" - env (or environment): Set default environment (prod, beta)\n"));
342
+ console.log(chalk.yellow(" - env (or environment): Set default environment (prod, uat, beta)\n"));
292
343
  console.log(chalk.yellow("\nNote: Template repository URLs are configured via .env file, not CLI commands.\n"));
293
344
  process.exit(1);
294
345
  }
@@ -464,7 +515,7 @@ async function showMainMenu() {
464
515
  try {
465
516
  const currentEnv = await getCurrentEnvironment();
466
517
  const envDisplay = getEnvironmentDisplayName(currentEnv);
467
- const envColor = currentEnv === "beta" ? chalk.yellow : chalk.green;
518
+ const envColor = currentEnv === "production" ? chalk.green : chalk.yellow;
468
519
  console.log(chalk.cyan.bold("\n\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"));
469
520
  console.log(chalk.cyan.bold("\u2551 \u{1F680} Botim CLI Generator \u2551"));
470
521
  console.log(chalk.cyan.bold(`\u2551 v${version.padEnd(32)}\u2551`));
@@ -529,9 +580,12 @@ async function showMainMenu() {
529
580
  const command = authenticatedCommandRegistry.get(commandName);
530
581
  if (command) {
531
582
  try {
532
- await command.execute();
583
+ await executeWithAuthRetry(
584
+ () => command.execute(),
585
+ { commandName, retryAfterLogin: true }
586
+ );
533
587
  } catch (error) {
534
- console.error(chalk.red("\n\u274C Error executing command:"), error);
588
+ logger.error("Command execution failed", error);
535
589
  process.exit(1);
536
590
  }
537
591
  }
@@ -574,6 +628,10 @@ async function showMainMenu() {
574
628
  name: `Production ${allStatus.production.loggedIn ? chalk.green("\u2713 Logged in") : chalk.gray("(not logged in)")}${currentEnv === "production" ? chalk.cyan(" \u2190 current") : ""}`,
575
629
  value: "production"
576
630
  },
631
+ {
632
+ name: `UAT ${allStatus.uat.loggedIn ? chalk.green("\u2713 Logged in") : chalk.gray("(not logged in)")}${currentEnv === "uat" ? chalk.cyan(" \u2190 current") : ""}`,
633
+ value: "uat"
634
+ },
577
635
  {
578
636
  name: `Beta ${allStatus.beta.loggedIn ? chalk.green("\u2713 Logged in") : chalk.gray("(not logged in)")}${currentEnv === "beta" ? chalk.cyan(" \u2190 current") : ""}`,
579
637
  value: "beta"
@@ -612,6 +670,13 @@ async function showMainMenu() {
612
670
  if (prodStatus.loggedIn && prodStatus.partnerName) {
613
671
  console.log(chalk.gray(` Partner: ${prodStatus.partnerName}`));
614
672
  }
673
+ const uatStatus = allStatus.uat;
674
+ const uatIndicator = uatStatus.loggedIn ? chalk.green("\u2713") : chalk.red("\u2717");
675
+ const uatActive = currentEnv === "uat" ? chalk.cyan(" (active)") : "";
676
+ console.log(` ${uatIndicator} UAT${uatActive}`);
677
+ if (uatStatus.loggedIn && uatStatus.partnerName) {
678
+ console.log(chalk.gray(` Partner: ${uatStatus.partnerName}`));
679
+ }
615
680
  const betaStatus = allStatus.beta;
616
681
  const betaIndicator = betaStatus.loggedIn ? chalk.green("\u2713") : chalk.red("\u2717");
617
682
  const betaActive = currentEnv === "beta" ? chalk.cyan(" (active)") : "";