busa-sdk 0.17.3 → 0.19.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.
@@ -1,45 +1,5 @@
1
- import { BusabaseAirAppAuthStatus } from './airapp-node.js';
2
- import './oauth-node.js';
3
- import './oauth.js';
4
-
5
- /**
6
- * The AirApp connect gate — the browser half of local onboarding.
7
- *
8
- * `busabase-sdk/airapp-node` already owns the *flow* (PKCE, credential
9
- * rotation, Space validation, the `/api/v1` proxy). This module owns the
10
- * remaining copy-paste: deciding which of the three screens to show, and
11
- * drawing them. 62 App-in-Skills carried a 160-line renderer whose only
12
- * per-app difference was the display name interpolated into an HTML string,
13
- * plus a byte-identical 290-line stylesheet — while the app-creator template
14
- * grew a second, differently-classed implementation of the same three screens.
15
- *
16
- * Structure, deliberately: every decision and every piece of markup is a pure
17
- * function of the gateway's status. The DOM is touched only in `mount` /
18
- * `wire`. That is what makes the escaping (the one security-relevant part —
19
- * `oauth_error` and Space names both come from outside) testable without a
20
- * browser, and what lets an app swap the renderer without reimplementing the
21
- * state machine.
22
- *
23
- * Import `busabase-sdk/airapp-gate.css` (or copy it) for the default look; it
24
- * is themed entirely through custom properties.
25
- *
26
- * @example
27
- * ```ts
28
- * import { createAirAppConnectGate } from "busabase-sdk/airapp-gate";
29
- *
30
- * const gate = createAirAppConnectGate({
31
- * appName: "Kelly CRM",
32
- * onProvision: () => provider.provisionResources(),
33
- * });
34
- *
35
- * // Before mounting the app shell:
36
- * if (await gate.pass({ onReady: () => start() })) start();
37
- *
38
- * // When loading data fails because the workspace is not set up yet:
39
- * gate.renderSetupRequired(error, () => start());
40
- * ```
41
- */
42
-
1
+ import { BusabaseAirAppAuthStatus } from "./airapp-node.js";
2
+ //#region src/airapp-gate.d.ts
43
3
  /** Which screen the gate owes the operator right now. */
44
4
  type AirAppGateScreen = "connect" | "space" | "ready";
45
5
  /**
@@ -52,14 +12,14 @@ type AirAppGateScreen = "connect" | "space" | "ready";
52
12
  declare function selectAirAppGateScreen(status: Partial<BusabaseAirAppAuthStatus> | null | undefined): AirAppGateScreen;
53
13
  /** The five setup states, decoded into what the workspace screen needs to know. */
54
14
  interface AirAppSetupDescription {
55
- code: string;
56
- /** The message with its `CODE: ` prefix stripped. */
57
- detail: string;
58
- title: string;
59
- /** Offer an "Initialize workspace" button. */
60
- canProvision: boolean;
61
- /** Offer a "Check again" button (the app cannot act; the operator can retry). */
62
- canRetry: boolean;
15
+ code: string;
16
+ /** The message with its `CODE: ` prefix stripped. */
17
+ detail: string;
18
+ title: string;
19
+ /** Offer an "Initialize workspace" button. */
20
+ canProvision: boolean;
21
+ /** Offer a "Check again" button (the app cannot act; the operator can retry). */
22
+ canRetry: boolean;
63
23
  }
64
24
  /**
65
25
  * Decode a setup failure. Accepts an `AirAppSetupError`, any `Error` whose
@@ -68,62 +28,62 @@ interface AirAppSetupDescription {
68
28
  */
69
29
  declare function describeAirAppSetupError(error: unknown): AirAppSetupDescription;
70
30
  interface AirAppGateOptions {
71
- /** Shown in the gate's prose, e.g. "Kelly CRM". The one per-app value. */
72
- appName: string;
73
- /**
74
- * Where to mount. A selector, an element, or omitted to create and prepend
75
- * `#busabaseAirAppGate` to `<body>`.
76
- */
77
- mount?: string | HTMLElement;
78
- /** Prefix for the gateway routes; `""` means `/auth/status`, `/auth/start`, … */
79
- authBasePath?: string;
80
- /**
81
- * Whether this run owes a gate at all. Return `false` for a Busabase-hosted
82
- * AirApp (the ambient session owns auth) or for a demo/offline mode.
83
- *
84
- * **Pass this.** Omitted, `pass()` falls back to probing `/auth/status` and
85
- * treating an unreachable or non-JSON answer as "hosted" — which works, but
86
- * infers something the host already states outright. A Busabase-hosted AirApp
87
- * is identified by the `BUSABASE_AIRAPP_RUNTIME` env var Busabase injects into
88
- * the process it spawns, surfaced to the browser by the app's own server;
89
- * never by hostname, iframe nesting, or path, since a hosted AirApp can be
90
- * served from localhost and a standalone run can be reached over a dev tunnel.
91
- */
92
- shouldGate?: () => boolean | Promise<boolean>;
93
- /** Injected for tests. */
94
- fetch?: typeof globalThis.fetch;
95
- /** Called by the workspace screen's "Initialize workspace" button. */
96
- onProvision?: () => Promise<unknown>;
97
- /** Where the "open the demo" escape hatch points. Omit to hide it. */
98
- demoHref?: string | null;
99
- /** Replace the default markup wholesale while keeping the state machine. */
100
- render?: AirAppGateRenderer;
31
+ /** Shown in the gate's prose, e.g. "Kelly CRM". The one per-app value. */
32
+ appName: string;
33
+ /**
34
+ * Where to mount. A selector, an element, or omitted to create and prepend
35
+ * `#busabaseAirAppGate` to `<body>`.
36
+ */
37
+ mount?: string | HTMLElement;
38
+ /** Prefix for the gateway routes; `""` means `/auth/status`, `/auth/start`, … */
39
+ authBasePath?: string;
40
+ /**
41
+ * Whether this run owes a gate at all. Return `false` for a Busabase-hosted
42
+ * AirApp (the ambient session owns auth) or for a demo/offline mode.
43
+ *
44
+ * **Pass this.** Omitted, `pass()` falls back to probing `/auth/status` and
45
+ * treating an unreachable or non-JSON answer as "hosted" — which works, but
46
+ * infers something the host already states outright. A Busabase-hosted AirApp
47
+ * is identified by the `BUSABASE_AIRAPP_RUNTIME` env var Busabase injects into
48
+ * the process it spawns, surfaced to the browser by the app's own server;
49
+ * never by hostname, iframe nesting, or path, since a hosted AirApp can be
50
+ * served from localhost and a standalone run can be reached over a dev tunnel.
51
+ */
52
+ shouldGate?: () => boolean | Promise<boolean>;
53
+ /** Injected for tests. */
54
+ fetch?: typeof globalThis.fetch;
55
+ /** Called by the workspace screen's "Initialize workspace" button. */
56
+ onProvision?: () => Promise<unknown>;
57
+ /** Where the "open the demo" escape hatch points. Omit to hide it. */
58
+ demoHref?: string | null;
59
+ /** Replace the default markup wholesale while keeping the state machine. */
60
+ render?: AirAppGateRenderer;
101
61
  }
102
62
  interface AirAppGateRenderer {
103
- connect(view: AirAppConnectView): string;
104
- space(view: AirAppSpaceView): string;
105
- workspace(view: AirAppWorkspaceView): string;
63
+ connect(view: AirAppConnectView): string;
64
+ space(view: AirAppSpaceView): string;
65
+ workspace(view: AirAppWorkspaceView): string;
106
66
  }
107
67
  interface AirAppConnectView {
108
- appName: string;
109
- cloudBaseUrl: string;
110
- /** Set when the operator is here because the session lapsed, not first-run. */
111
- reconnect: boolean;
112
- /** `?oauth_error=` from the callback redirect. Untrusted. */
113
- oauthError: string;
114
- authBasePath: string;
68
+ appName: string;
69
+ cloudBaseUrl: string;
70
+ /** Set when the operator is here because the session lapsed, not first-run. */
71
+ reconnect: boolean;
72
+ /** `?oauth_error=` from the callback redirect. Untrusted. */
73
+ oauthError: string;
74
+ authBasePath: string;
115
75
  }
116
76
  interface AirAppSpaceView {
117
- appName: string;
118
- baseUrl: string;
119
- spaces: {
120
- id: string;
121
- name: string;
122
- }[];
77
+ appName: string;
78
+ baseUrl: string;
79
+ spaces: {
80
+ id: string;
81
+ name: string;
82
+ }[];
123
83
  }
124
84
  interface AirAppWorkspaceView extends AirAppSetupDescription {
125
- appName: string;
126
- demoHref: string | null;
85
+ appName: string;
86
+ demoHref: string | null;
127
87
  }
128
88
  /** HTML-escape. Every interpolation below goes through this. */
129
89
  declare const escapeHtml: (value: unknown) => string;
@@ -131,20 +91,20 @@ declare const escapeHtml: (value: unknown) => string;
131
91
  declare const defaultAirAppGateRenderer: AirAppGateRenderer;
132
92
  declare const DEFAULT_CLOUD_BASE_URL = "https://busabase.com";
133
93
  interface AirAppConnectGate {
134
- /**
135
- * Resolve the gate before the app shell mounts. `true` means the app may
136
- * load data; `false` means a screen is up and waiting on the operator — call
137
- * again after `onReady` fires.
138
- */
139
- pass(options?: {
140
- onReady?: () => void;
141
- }): Promise<boolean>;
142
- /** Show the workspace screen for a setup error thrown while loading data. */
143
- renderSetupRequired(error: unknown, onRetry: () => void): void;
144
- /** Take the gate down and give scrolling back to the page. */
145
- close(): void;
146
- /** Fetch the gateway's status without rendering anything. */
147
- status(): Promise<BusabaseAirAppAuthStatus | null>;
94
+ /**
95
+ * Resolve the gate before the app shell mounts. `true` means the app may
96
+ * load data; `false` means a screen is up and waiting on the operator — call
97
+ * again after `onReady` fires.
98
+ */
99
+ pass(options?: {
100
+ onReady?: () => void;
101
+ }): Promise<boolean>;
102
+ /** Show the workspace screen for a setup error thrown while loading data. */
103
+ renderSetupRequired(error: unknown, onRetry: () => void): void;
104
+ /** Take the gate down and give scrolling back to the page. */
105
+ close(): void;
106
+ /** Fetch the gateway's status without rendering anything. */
107
+ status(): Promise<BusabaseAirAppAuthStatus | null>;
148
108
  }
149
109
  /**
150
110
  * Build a gate bound to one app.
@@ -153,5 +113,5 @@ interface AirAppConnectGate {
153
113
  * construct at module scope.
154
114
  */
155
115
  declare function createAirAppConnectGate(options: AirAppGateOptions): AirAppConnectGate;
156
-
157
- export { type AirAppConnectGate, type AirAppConnectView, type AirAppGateOptions, type AirAppGateRenderer, type AirAppGateScreen, type AirAppSetupDescription, type AirAppSpaceView, type AirAppWorkspaceView, BusabaseAirAppAuthStatus, DEFAULT_CLOUD_BASE_URL, createAirAppConnectGate, defaultAirAppGateRenderer, describeAirAppSetupError, escapeHtml, selectAirAppGateScreen };
116
+ //#endregion
117
+ export { AirAppConnectGate, AirAppConnectView, AirAppGateOptions, AirAppGateRenderer, AirAppGateScreen, AirAppSetupDescription, AirAppSpaceView, AirAppWorkspaceView, type BusabaseAirAppAuthStatus, DEFAULT_CLOUD_BASE_URL, createAirAppConnectGate, defaultAirAppGateRenderer, describeAirAppSetupError, escapeHtml, selectAirAppGateScreen };