@botonic/nx-plugin 2.30.0 → 2.31.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.
@@ -18,7 +18,7 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var credentials_handler_exports = {};
20
20
  __export(credentials_handler_exports, {
21
- BotCredentialsHandler: () => BotCredentialsHandler,
21
+ BotsRegistryHandler: () => BotsRegistryHandler,
22
22
  CredentialsHandler: () => CredentialsHandler,
23
23
  GlobalCredentialsHandler: () => GlobalCredentialsHandler
24
24
  });
@@ -58,13 +58,13 @@ class CredentialsHandler {
58
58
  class GlobalCredentialsHandler extends CredentialsHandler {
59
59
  /**
60
60
  * @param baseDir - Optional directory for credentials (e.g. monorepo_root/.botonic).
61
- * When provided, credentials are stored at baseDir/credentials.json (source of truth in monorepo).
61
+ * When provided, credentials are stored at baseDir/env-credentials.json.
62
62
  * When omitted, uses ~/.botonic (user home).
63
63
  */
64
64
  constructor(baseDir) {
65
65
  super({
66
66
  homeDir: baseDir ? (0, import_path.resolve)(baseDir) : (0, import_path.join)((0, import_file_system.getHomeDirectory)(), import_constants.BOTONIC_HOME_DIRNAME),
67
- filename: import_constants.GLOBAL_CREDS_FILENAME
67
+ filename: import_constants.ENV_CREDENTIALS_FILENAME
68
68
  });
69
69
  }
70
70
  initialize() {
@@ -79,37 +79,55 @@ class GlobalCredentialsHandler extends CredentialsHandler {
79
79
  return this.dumpJSON(obj);
80
80
  }
81
81
  }
82
- class BaseBotCredentialsHandler extends CredentialsHandler {
83
- constructor(args) {
82
+ class BotsRegistryHandler extends CredentialsHandler {
83
+ constructor() {
84
84
  super({
85
- homeDir: args.homeDir,
86
- filename: args.filename
85
+ homeDir: (0, import_path.join)((0, import_file_system.getHomeDirectory)(), import_constants.BOTONIC_HOME_DIRNAME),
86
+ filename: import_constants.BOTS_REGISTRY_FILENAME
87
87
  });
88
88
  }
89
89
  load() {
90
- const json = this.loadJSON();
91
- if (!json) return void 0;
92
- return json;
90
+ try {
91
+ if (!(0, import_file_system.pathExists)(this.pathToCredentials)) return {};
92
+ const result = (0, import_file_system.readJSON)(this.pathToCredentials);
93
+ return result && !Array.isArray(result) ? result : {};
94
+ } catch {
95
+ console.warn("bots.json could not be loaded");
96
+ return {};
97
+ }
93
98
  }
94
- dump(obj) {
95
- return this.dumpJSON(obj);
99
+ dump(registry) {
100
+ try {
101
+ (0, import_file_system.writeJSON)(this.pathToCredentials, registry);
102
+ } catch {
103
+ console.warn("bots.json could not be written");
104
+ }
96
105
  }
97
- }
98
- class BotCredentialsHandler extends BaseBotCredentialsHandler {
99
- /**
100
- * @param projectRoot - Directory for app/project .botonic.json (e.g. apps/my-bot).
101
- * When omitted, uses process.cwd() (may write to repo root when Nx cwd is workspace root).
102
- */
103
- constructor(projectRoot) {
104
- super({
105
- homeDir: projectRoot ? (0, import_path.resolve)(projectRoot) : import_constants.BOTONIC_PROJECT_PATH,
106
- filename: import_constants.BOT_CREDENTIALS_FILENAME
107
- });
106
+ upsert(env, entry) {
107
+ try {
108
+ const registry = this.load();
109
+ const list = registry[env] ?? [];
110
+ const idx = list.findIndex((e) => e.id === entry.id);
111
+ if (idx !== -1) {
112
+ list[idx] = entry;
113
+ } else {
114
+ list.push(entry);
115
+ }
116
+ registry[env] = list;
117
+ this.dump(registry);
118
+ } catch {
119
+ console.warn("bots.json could not be updated");
120
+ }
121
+ }
122
+ findLatestForEnv(env) {
123
+ const registry = this.load();
124
+ const list = registry[env] ?? [];
125
+ return list.length > 0 ? list[list.length - 1] : void 0;
108
126
  }
109
127
  }
110
128
  // Annotate the CommonJS export names for ESM import in node:
111
129
  0 && (module.exports = {
112
- BotCredentialsHandler,
130
+ BotsRegistryHandler,
113
131
  CredentialsHandler,
114
132
  GlobalCredentialsHandler
115
133
  });
@@ -24,23 +24,20 @@ export interface EnvironmentCredentials {
24
24
  }
25
25
  /** Store: one entry per environment so multiple envs can be logged in. */
26
26
  export type GlobalCredentialsStore = Record<string, EnvironmentCredentials>;
27
+ export interface ProviderAccountEntry {
28
+ id: string;
29
+ provider: string;
30
+ is_test: boolean;
31
+ is_active: boolean;
32
+ }
27
33
  export interface BotDetail {
28
34
  id: string;
29
35
  name: string;
30
- organization: string;
31
- last_update: any;
32
- created_at: string;
33
- provider_accounts: any[];
34
- is_debug: boolean;
35
- is_published: boolean;
36
- active_users: number;
37
- }
38
- export interface BotCredentials {
39
- bot: BotDetail | null;
40
- }
41
- export interface LocalRuntimeBotCredentials {
42
- localRuntimeBot: BotDetail | null;
36
+ providers?: ProviderAccountEntry[];
37
+ [key: string]: unknown;
43
38
  }
39
+ export type BotRegistryEntry = BotDetail;
40
+ export type BotsRegistry = Record<string, BotRegistryEntry[]>;
44
41
  export type JSONPrimitive = string | number | boolean | null;
45
42
  export type JSONValue = JSONPrimitive | JSONObject | JSONArray;
46
43
  export type JSONObject = {
@@ -1,6 +1,5 @@
1
1
  import type { ExecutorContext } from '@nx/devkit';
2
2
  import { BotonicAPIService } from '../api-service';
3
- import type { BotDetail } from '../interfaces';
4
3
  export declare function resolveProjectPath(context: ExecutorContext): string;
5
4
  export declare function askEmailPassword(): Promise<{
6
5
  email: string;
@@ -15,7 +14,7 @@ export declare function handleAuthentication(botonicApiService: BotonicAPIServic
15
14
  */
16
15
  export declare function logWorkingAsAndEnvironment(botonicApiService: BotonicAPIService): Promise<void>;
17
16
  export declare function getAvailableBots(botonicApiService: BotonicAPIService): Promise<any[]>;
18
- export declare function createNewBotWithName(botonicApiService: BotonicAPIService, botName: string): Promise<void>;
17
+ export declare function createNewBotWithName(botonicApiService: BotonicAPIService, botName: string, isTest?: boolean): Promise<void>;
19
18
  export declare function getAppIdFromEnvFile(projectRoot: string, appIdKey: string): string | null;
20
19
  /**
21
20
  * Reads VITE_HUBTYPE_APP_ID from .env.[configuration] (e.g. .env.dev) or .env.local when configuration is 'local'.
@@ -53,24 +52,14 @@ export declare function resolveHubtypeEnvironment(context: ExecutorContext, opti
53
52
  };
54
53
  /**
55
54
  * Ensures the user is logged in to Hubtype before starting the tunnel flow.
56
- * Run this before Lambda + cloudflared + deploy_local_runtime so the login prompt happens first.
57
55
  */
58
- export declare function ensureHubtypeLoginBeforeTunnel(context: ExecutorContext, projectRoot: string, options?: PerformDeployLocalRuntimeOptions): Promise<void>;
56
+ export declare function ensureHubtypeLoginBeforeTunnel(context: ExecutorContext, projectRoot: string, options?: DeployDevSessionOptions): Promise<void>;
59
57
  /**
60
- * Ensures a local runtime bot is selected or created and persisted to .botonic.json.
61
- * Call this after ensureHubtypeLoginBeforeTunnel and before starting the tunnel, so bot detection runs after login but before tunnel setup.
62
- * Does not log "Working as..." (already logged by ensureHubtypeLoginBeforeTunnel).
58
+ * Ensures a bot is set: reuses one from bots.json registry, or prompts to select an existing
59
+ * deployed bot or create a new one. The selected bot must be deployed with botonic_v2 strategy before
60
+ * dev session registration will succeed the user is informed of this requirement.
63
61
  */
64
- export declare function ensureLocalRuntimeBotBeforeTunnel(context: ExecutorContext, projectRoot: string, options?: PerformDeployLocalRuntimeOptions): Promise<void>;
65
- /**
66
- * Writes the local runtime bot to .botonic.json in the app folder so the created bot is persisted per project.
67
- */
68
- export declare function writeLocalRuntimeBotToAppFolder(projectRoot: string, bot: BotDetail): void;
69
- /**
70
- * Removes the app folder .botonic.json so the next run will prompt to create/select a new bot (e.g. after 404 when bot was deleted).
71
- */
72
- export declare function removeAppBotonicJson(projectRoot: string): void;
73
- export declare function ensureLocalRuntimeBot(botonicApiService: BotonicAPIService): Promise<void>;
62
+ export declare function ensureBot(botonicApiService: BotonicAPIService): Promise<void>;
74
63
  export type ProviderAccountListItem = {
75
64
  id: string;
76
65
  provider?: string;
@@ -78,26 +67,66 @@ export type ProviderAccountListItem = {
78
67
  is_active?: boolean;
79
68
  };
80
69
  /**
81
- * APP_ID for local runtime must be the webchat test provider not WhatsApp
70
+ * Returns the imp_id of the first active real (non-test) webchat PA on the bot.
71
+ * Used by serve to auto-write VITE_HUBTYPE_APP_ID so the local widget connects.
72
+ */
73
+ export declare function getActiveWebchatProviderAppId(results: ProviderAccountListItem[] | undefined): string | undefined;
74
+ /**
75
+ * APP_ID for the dev session must be the webchat test provider — not WhatsApp
82
76
  * or other channels, which may also be test+active on the same bot.
83
77
  */
84
78
  export declare function getActiveTestWebchatProviderAppId(results: ProviderAccountListItem[] | undefined): string | undefined;
85
- export interface PerformDeployLocalRuntimeOptions {
79
+ export interface DeployDevSessionOptions {
86
80
  email?: string;
87
81
  password?: string;
88
82
  env?: Record<string, unknown>;
89
83
  /** Explicit configuration name (e.g. 'dev') so deploy uses the right environment when Nx does not merge config. */
90
84
  configuration?: string;
85
+ /** E.164 phone number to register for WhatsApp local routing (e.g. +34612345678). */
86
+ whatsappPhone?: string;
87
+ /** Bot id pre-selected by selectBotForServe — skips ensureBot lookup so the correct bot is used. */
88
+ selectedBotId?: string;
91
89
  }
92
- export interface PerformDeployLocalRuntimeResult {
90
+ export interface DeployDevSessionResult {
93
91
  botId: string;
92
+ apiUrl: string;
93
+ accessToken: string;
94
+ refreshToken: string;
95
+ clientId: string;
94
96
  targetEnvironment: string;
95
97
  environmentVariables: Record<string, unknown>;
98
+ lambdaFunctionName: string | undefined;
99
+ teardownWebchat: () => Promise<void>;
96
100
  }
97
101
  /**
98
- * Performs deploy_local_runtime with the given endpoint (e.g. tunnel URL).
99
- * Handles auth, bot creation/selection, and deploy. Returns the bot id and env for later cleanup (e.g. deleteBot on shutdown).
102
+ * Registers a dev session with the given tunnel endpoint.
103
+ * Handles auth, bot creation/selection, and registration. Returns the bot id and env.
100
104
  * Used by serve-bot (tunnel is always on).
101
105
  */
102
- export declare function performDeployLocalRuntimeWithEndpoint(context: ExecutorContext, projectRoot: string, endpoint: string, options?: PerformDeployLocalRuntimeOptions): Promise<PerformDeployLocalRuntimeResult>;
106
+ export declare function performDeployLocalRuntimeWithEndpoint(context: ExecutorContext, projectRoot: string, endpoint: string, options?: DeployDevSessionOptions): Promise<DeployDevSessionResult>;
107
+ /**
108
+ * Always prompts the user to select or create a bot for local development.
109
+ * Pre-selects the previously used bot (from registry). When botName is provided,
110
+ * skips the prompt entirely. For newly created bots, auto-deploys before returning
111
+ * so the serve flow can proceed without manual intervention.
112
+ *
113
+ * Must be called before tunnel startup so that auto-deploys don't waste tunnel
114
+ * resources and the selected bot is saved to the registry for
115
+ * performDeployLocalRuntimeWithEndpoint to load.
116
+ */
117
+ export declare function selectBotForServe(context: ExecutorContext, projectRoot: string, options?: DeployDevSessionOptions & {
118
+ botName?: string;
119
+ }): Promise<string | undefined>;
120
+ export declare function isBotDeployedRestartRequired(error: unknown): boolean;
121
+ /**
122
+ * Returns true if the currently selected bot (last entry in bots.json for the
123
+ * given env) has an active WhatsApp provider. Used by the serve executor to
124
+ * decide whether to enable the WhatsApp dev panel.
125
+ */
126
+ export declare function selectedBotHasActiveWhatsapp(botId: string): boolean;
127
+ /**
128
+ * Builds the bot and deploys it to Hubtype Cloud. Shared by the deploy executor
129
+ * and the serve executor's auto-deploy path for newly created bots.
130
+ */
131
+ export declare function deployBotToHubtype(botonicApiService: BotonicAPIService, projectRoot: string, projectName: string): Promise<void>;
103
132
  export {};