@bodhiapp/bodhi-js-core 0.0.30 → 0.0.32
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/dist/bodhi-core.cjs.js +4 -4
- package/dist/bodhi-core.esm.js +431 -284
- package/dist/cli/setup-modal.js +1 -1
- package/dist/direct-client-base.d.ts +12 -6
- package/dist/facade-client-base.d.ts +12 -1
- package/dist/index.d.ts +1 -0
- package/dist/interface.d.ts +28 -0
- package/dist/mcp-fetch.d.ts +23 -0
- package/dist/mcp.cjs.js +1 -0
- package/dist/mcp.d.ts +19 -0
- package/dist/mcp.esm.js +18 -0
- package/dist/openai-client-compat.d.ts +1 -13
- package/dist/types/auth.d.ts +3 -0
- package/dist/types/index.cjs.js +1 -1
- package/dist/types/index.d.ts +4 -1
- package/dist/types/index.esm.js +67 -46
- package/dist/types/storage.d.ts +31 -0
- package/package.json +22 -6
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { AccessRequestStatusResponse, CreateAccessRequest, CreateAccessRequestResponse, DeploymentMode, PingResponse } from '@bodhiapp/ts-client';
|
|
2
2
|
import { ApiResponse } from '@bodhiapp/bodhi-browser-types';
|
|
3
|
-
import { IDirectClient } from './interface';
|
|
3
|
+
import { IDirectClient, StreamTextResult } from './interface';
|
|
4
4
|
import { Logger } from './logger';
|
|
5
5
|
import { Chat, Models, Embeddings, Mcps } from './openai-client-compat';
|
|
6
6
|
import { OAuthEndpoints, RefreshTokenResponse } from './oauth';
|
|
7
7
|
import { StorageKeys } from './storage';
|
|
8
|
-
import { AuthState, BackendServerState, ClientState, DirectState, InitParams, LogLevel, SerializedDirectState, StateChangeCallback } from './types';
|
|
8
|
+
import { AuthState, BackendServerState, ClientState, DirectState, IStorage, InitialTokens, InitParams, LogLevel, SerializedDirectState, StateChangeCallback } from './types';
|
|
9
9
|
/**
|
|
10
10
|
* DirectClientBase - Abstract base class for DirectClient implementations
|
|
11
11
|
*
|
|
@@ -42,6 +42,8 @@ export interface DirectClientBaseConfig {
|
|
|
42
42
|
logLevel: LogLevel;
|
|
43
43
|
loggerPrefix: string;
|
|
44
44
|
apiTimeoutMs?: number;
|
|
45
|
+
storage?: IStorage;
|
|
46
|
+
initialTokens?: InitialTokens;
|
|
45
47
|
}
|
|
46
48
|
/**
|
|
47
49
|
* DirectClientBase - Abstract base implementing common HTTP/streaming logic
|
|
@@ -52,11 +54,13 @@ export declare abstract class DirectClientBase implements IDirectClient {
|
|
|
52
54
|
protected authClientId: string;
|
|
53
55
|
protected authServerUrl: string;
|
|
54
56
|
protected authEndpoints: OAuthEndpoints;
|
|
57
|
+
protected storage: IStorage | null;
|
|
55
58
|
protected storageKeys: StorageKeys;
|
|
56
59
|
protected state: DirectState;
|
|
57
60
|
private onStateChange;
|
|
58
61
|
private refreshPromise;
|
|
59
62
|
private apiTimeoutMs;
|
|
63
|
+
private initialTokens;
|
|
60
64
|
private _chat;
|
|
61
65
|
private _models;
|
|
62
66
|
private _embeddings;
|
|
@@ -90,6 +94,7 @@ export declare abstract class DirectClientBase implements IDirectClient {
|
|
|
90
94
|
*/
|
|
91
95
|
getServerState(): Promise<BackendServerState>;
|
|
92
96
|
stream<TReq = unknown, TRes = unknown>(method: string, endpoint: string, body?: TReq, headers?: Record<string, string>, authenticated?: boolean): AsyncGenerator<TRes>;
|
|
97
|
+
streamText(method: string, endpoint: string, body?: unknown, headers?: Record<string, string>, authenticated?: boolean): Promise<StreamTextResult>;
|
|
93
98
|
get chat(): Chat;
|
|
94
99
|
get models(): Models;
|
|
95
100
|
get embeddings(): Embeddings;
|
|
@@ -113,9 +118,9 @@ export declare abstract class DirectClientBase implements IDirectClient {
|
|
|
113
118
|
timeoutMs?: number;
|
|
114
119
|
}): Promise<AccessRequestStatusResponse>;
|
|
115
120
|
abstract login(): Promise<AuthState>;
|
|
116
|
-
abstract logout(): Promise<AuthState>;
|
|
117
121
|
protected abstract performOAuthPkce(scope: string): Promise<AuthState>;
|
|
118
122
|
getAuthState(): Promise<AuthState>;
|
|
123
|
+
logout(): Promise<AuthState>;
|
|
119
124
|
protected _getAccessTokenRaw(): Promise<string | null>;
|
|
120
125
|
/**
|
|
121
126
|
* Try to refresh access token using refresh token
|
|
@@ -133,8 +138,9 @@ export declare abstract class DirectClientBase implements IDirectClient {
|
|
|
133
138
|
protected exchangeCodeForTokens(code: string): Promise<void>;
|
|
134
139
|
protected revokeRefreshToken(): Promise<void>;
|
|
135
140
|
protected clearAuthStorage(): Promise<void>;
|
|
136
|
-
|
|
137
|
-
protected
|
|
138
|
-
protected
|
|
141
|
+
private _bootstrapInitialTokens;
|
|
142
|
+
protected _storageGet(key: string): Promise<string | null>;
|
|
143
|
+
protected _storageSet(items: Record<string, string | number>): Promise<void>;
|
|
144
|
+
protected _storageRemove(keys: string[]): Promise<void>;
|
|
139
145
|
protected abstract _getRedirectUri(): string;
|
|
140
146
|
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { AccessRequestStatusResponse, CreateAccessRequest, CreateAccessRequestResponse, PingResponse } from '@bodhiapp/ts-client';
|
|
2
2
|
import { ApiResponse } from '@bodhiapp/bodhi-browser-types';
|
|
3
|
-
import { IConnectionClient, IExtensionClient } from './interface';
|
|
3
|
+
import { IConnectionClient, IExtensionClient, StreamTextResult } from './interface';
|
|
4
4
|
import { Logger } from './logger';
|
|
5
5
|
import { BodhiClientUserPrefsManager } from './storage';
|
|
6
6
|
import { Chat, Models, Embeddings, Mcps } from './openai-client-compat';
|
|
7
|
+
import { McpTransportConfig } from './mcp-fetch';
|
|
7
8
|
import { AuthState, BackendServerState, ClientState, ConnectionMode, DirectState, ExtensionState, InitParams, LoginOptions, SerializedClientState, SerializedDirectState, SerializedExtensionState, StateChange, StateChangeCallback } from './types';
|
|
8
9
|
/**
|
|
9
10
|
* Base facade client with common delegation logic
|
|
@@ -112,10 +113,20 @@ export declare abstract class BaseFacadeClient<TConfig, TExtClient extends IExte
|
|
|
112
113
|
pingApi(): Promise<ApiResponse<PingResponse>>;
|
|
113
114
|
getServerState(): Promise<BackendServerState>;
|
|
114
115
|
stream<TReq = unknown, TRes = unknown>(method: string, endpoint: string, body?: TReq, headers?: Record<string, string>, authenticated?: boolean): AsyncGenerator<TRes>;
|
|
116
|
+
streamText(method: string, endpoint: string, body?: unknown, headers?: Record<string, string>, authenticated?: boolean): Promise<StreamTextResult>;
|
|
115
117
|
get chat(): Chat;
|
|
116
118
|
get models(): Models;
|
|
117
119
|
get embeddings(): Embeddings;
|
|
118
120
|
get mcps(): Mcps;
|
|
121
|
+
/**
|
|
122
|
+
* Create transport config for MCP StreamableHTTPClientTransport.
|
|
123
|
+
* Handles connection mode transparently — direct mode uses standard fetch with
|
|
124
|
+
* Bearer token, extension mode routes through the extension's message passing.
|
|
125
|
+
*
|
|
126
|
+
* @param mcp_path - Relative proxy path from Mcp.path (e.g. '/bodhi/v1/apps/mcps/{id}/mcp')
|
|
127
|
+
* @returns McpTransportConfig with url and fetch function for StreamableHTTPClientTransport
|
|
128
|
+
*/
|
|
129
|
+
createMcpTransportConfig(mcp_path: string): McpTransportConfig;
|
|
119
130
|
getConnectionMode(): ConnectionMode | null;
|
|
120
131
|
setConnectionMode(mode: ConnectionMode): Promise<ClientState>;
|
|
121
132
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -20,4 +20,5 @@ export * from './oauth';
|
|
|
20
20
|
export * from './direct-client-base';
|
|
21
21
|
export * from './facade-client-base';
|
|
22
22
|
export * from './openai-client-compat';
|
|
23
|
+
export { createDirectMcpFetch, createExtensionMcpFetch } from './mcp-fetch';
|
|
23
24
|
export { BUILD_MODE as CORE_BUILD_MODE } from './build-info';
|
package/dist/interface.d.ts
CHANGED
|
@@ -2,6 +2,17 @@ import { AccessRequestStatusResponse, CreateAccessRequest, CreateAccessRequestRe
|
|
|
2
2
|
import { ApiResponse } from '@bodhiapp/bodhi-browser-types';
|
|
3
3
|
import { AuthState, BackendServerState, ClientState, ConnectionMode, DirectState, ExtensionState, InitParams, LoginOptions, StateChangeCallback } from './types';
|
|
4
4
|
import { Chat, Models, Embeddings, Mcps } from './openai-client-compat';
|
|
5
|
+
import { McpTransportConfig } from './mcp-fetch';
|
|
6
|
+
/**
|
|
7
|
+
* Result of a raw text streaming request
|
|
8
|
+
* Unlike stream() which parses SSE/JSON, streamText() forwards raw response text
|
|
9
|
+
* without any parsing. Non-2xx responses are returned as data (not thrown).
|
|
10
|
+
*/
|
|
11
|
+
export interface StreamTextResult {
|
|
12
|
+
status: number;
|
|
13
|
+
headers: Record<string, string>;
|
|
14
|
+
body: AsyncGenerator<string>;
|
|
15
|
+
}
|
|
5
16
|
/**
|
|
6
17
|
* ConnectionClient - Base interface for all client implementations
|
|
7
18
|
*
|
|
@@ -68,6 +79,17 @@ export interface IConnectionClient<IParams = unknown, SerialState = unknown> {
|
|
|
68
79
|
* @returns AsyncGenerator yielding response chunks
|
|
69
80
|
*/
|
|
70
81
|
stream<TReq = unknown, TRes = unknown>(method: string, endpoint: string, body?: TReq, headers?: Record<string, string>, authenticated?: boolean): AsyncGenerator<TRes>;
|
|
82
|
+
/**
|
|
83
|
+
* Raw text streaming request
|
|
84
|
+
* - DirectClient: fetch + ReadableStream without SSE parsing
|
|
85
|
+
* - IExtensionClient: window.bodhiext.sendStreamText or chrome.runtime equivalent
|
|
86
|
+
*
|
|
87
|
+
* Returns status, headers, and async generator of raw text chunks.
|
|
88
|
+
* Non-2xx responses are returned as data (not thrown).
|
|
89
|
+
*
|
|
90
|
+
* @returns Promise<StreamTextResult> with status, headers, and body generator
|
|
91
|
+
*/
|
|
92
|
+
streamText(method: string, endpoint: string, body?: unknown, headers?: Record<string, string>, authenticated?: boolean): Promise<StreamTextResult>;
|
|
71
93
|
/**
|
|
72
94
|
* Login via OAuth
|
|
73
95
|
* - IExtensionClient: Delegates to extension (chrome.identity or browser redirect)
|
|
@@ -240,6 +262,12 @@ export type UIClient = IConnectionClient<InitParams> & {
|
|
|
240
262
|
* @throws Error if connection mode is not 'extension'
|
|
241
263
|
*/
|
|
242
264
|
sendExtRequest<TParams = void, TRes = unknown>(action: string, params?: TParams): Promise<TRes>;
|
|
265
|
+
/**
|
|
266
|
+
* Create transport config for MCP StreamableHTTPClientTransport.
|
|
267
|
+
* Handles connection mode transparently.
|
|
268
|
+
* @param mcp_path - Relative proxy path from Mcp.path (e.g. '/bodhi/v1/apps/mcps/{id}/mcp')
|
|
269
|
+
*/
|
|
270
|
+
createMcpTransportConfig(mcp_path: string): McpTransportConfig;
|
|
243
271
|
};
|
|
244
272
|
/**
|
|
245
273
|
* Web-specific UIClient interface with OAuth callback handling
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { StreamTextResult } from './interface';
|
|
2
|
+
/**
|
|
3
|
+
* Standard fetch signature compatible with @modelcontextprotocol/sdk's FetchLike
|
|
4
|
+
*/
|
|
5
|
+
export type McpFetchLike = (url: string | URL, init?: RequestInit) => Promise<Response>;
|
|
6
|
+
/**
|
|
7
|
+
* Configuration returned by createMcpTransportConfig for creating MCP transports
|
|
8
|
+
*/
|
|
9
|
+
export interface McpTransportConfig {
|
|
10
|
+
url: URL;
|
|
11
|
+
fetch: McpFetchLike;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Creates a FetchLike for direct mode — standard fetch with Bearer token injection.
|
|
15
|
+
*/
|
|
16
|
+
export declare function createDirectMcpFetch(getToken: () => Promise<string | null>): McpFetchLike;
|
|
17
|
+
/**
|
|
18
|
+
* Creates a FetchLike for extension mode — routes HTTP through the Bodhi SDK client's
|
|
19
|
+
* streamText method which forwards raw response text without any parsing.
|
|
20
|
+
*/
|
|
21
|
+
export declare function createExtensionMcpFetch(client: {
|
|
22
|
+
streamText(method: string, endpoint: string, body?: unknown, headers?: Record<string, string>, authenticated?: boolean): Promise<StreamTextResult>;
|
|
23
|
+
}): McpFetchLike;
|
package/dist/mcp.cjs.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("@modelcontextprotocol/sdk/client/index.js"),s=require("@modelcontextprotocol/sdk/client/streamableHttp.js");async function l(r,a,e){const t=r.createMcpTransportConfig(a),n=new s.StreamableHTTPClientTransport(t.url,{fetch:t.fetch}),c=new o.Client({name:e?.name??"bodhi-mcp-client",version:e?.version??"1.0.0"});try{await c.connect(n)}catch(i){throw await n.close().catch(()=>{}),i}return c}exports.createMcpClient=l;
|
package/dist/mcp.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
2
|
+
import { McpTransportConfig } from './mcp-fetch';
|
|
3
|
+
/** Any client that provides createMcpTransportConfig (UIClient, CliClient, etc.) */
|
|
4
|
+
export interface McpTransportProvider {
|
|
5
|
+
createMcpTransportConfig(mcp_path: string): McpTransportConfig;
|
|
6
|
+
}
|
|
7
|
+
export interface CreateMcpClientOptions {
|
|
8
|
+
name?: string;
|
|
9
|
+
version?: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Create a connected MCP Client for a given proxy path.
|
|
13
|
+
*
|
|
14
|
+
* @param client - Any Bodhi client with createMcpTransportConfig (UIClient, CliClient, etc.)
|
|
15
|
+
* @param mcp_path - MCP proxy path from Mcp.path (e.g. '/bodhi/v1/apps/mcps/{id}/mcp')
|
|
16
|
+
* @param options - Optional client name and version
|
|
17
|
+
* @returns Connected @modelcontextprotocol/sdk Client ready for listTools(), callTool(), etc.
|
|
18
|
+
*/
|
|
19
|
+
export declare function createMcpClient(client: McpTransportProvider, mcp_path: string, options?: CreateMcpClientOptions): Promise<Client>;
|
package/dist/mcp.esm.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Client as i } from "@modelcontextprotocol/sdk/client/index.js";
|
|
2
|
+
import { StreamableHTTPClientTransport as m } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
3
|
+
async function l(r, o, t) {
|
|
4
|
+
const e = r.createMcpTransportConfig(o), n = new m(e.url, { fetch: e.fetch }), c = new i({
|
|
5
|
+
name: t?.name ?? "bodhi-mcp-client",
|
|
6
|
+
version: t?.version ?? "1.0.0"
|
|
7
|
+
});
|
|
8
|
+
try {
|
|
9
|
+
await c.connect(n);
|
|
10
|
+
} catch (a) {
|
|
11
|
+
throw await n.close().catch(() => {
|
|
12
|
+
}), a;
|
|
13
|
+
}
|
|
14
|
+
return c;
|
|
15
|
+
}
|
|
16
|
+
export {
|
|
17
|
+
l as createMcpClient
|
|
18
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CreateChatCompletionRequest, CreateChatCompletionResponse, CreateChatCompletionStreamResponse, CreateEmbeddingRequest, CreateEmbeddingResponse, Model, ListMcpsResponse
|
|
1
|
+
import { CreateChatCompletionRequest, CreateChatCompletionResponse, CreateChatCompletionStreamResponse, CreateEmbeddingRequest, CreateEmbeddingResponse, Model, ListMcpsResponse } from '@bodhiapp/ts-client';
|
|
2
2
|
import { ApiResponse } from '@bodhiapp/bodhi-browser-types';
|
|
3
3
|
/**
|
|
4
4
|
* Minimal client interface required by resource classes
|
|
@@ -68,16 +68,4 @@ export declare class Mcps extends APIResource {
|
|
|
68
68
|
* List available MCP servers
|
|
69
69
|
*/
|
|
70
70
|
list(): Promise<ListMcpsResponse>;
|
|
71
|
-
/**
|
|
72
|
-
* List tools for a specific MCP server
|
|
73
|
-
*/
|
|
74
|
-
listTools(mcpId: string): Promise<McpToolsResponse>;
|
|
75
|
-
/**
|
|
76
|
-
* Refresh tools for a specific MCP server
|
|
77
|
-
*/
|
|
78
|
-
refreshTools(mcpId: string): Promise<McpToolsResponse>;
|
|
79
|
-
/**
|
|
80
|
-
* Execute a tool on an MCP server
|
|
81
|
-
*/
|
|
82
|
-
executeTool(mcpId: string, toolName: string, params: Record<string, unknown>): Promise<unknown>;
|
|
83
71
|
}
|
package/dist/types/auth.d.ts
CHANGED
package/dist/types/index.cjs.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=require("@bodhiapp/bodhi-browser-types"),y=(e,r,t)=>{const n=r?.error?.message||`HTTP ${e}`;return new i.BodhiApiError(e,r,n,t)},o=(e,r)=>new i.BodhiError(e,r);function p(e){throw e==="denied"?o("access_request_denied","Access request was denied"):e==="expired"?o("access_request_expired","Access request expired"):o("access_request_failed",`Access request failed: ${e}`)}const s={NOT_REACHABLE:{message:"server is not reachable on given url",type:"network_error"},SERVER_NOT_READY:{message:"server is not in ready state, configure to complete setup",type:"extension_error"}},E={status:"not-reachable",version:null,error:s.NOT_REACHABLE},u={status:"pending-extension-ready",version:null,error:null},d={status:"not-connected",version:null,error:null};function c(e){return e.status==="ready"}function
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=require("@bodhiapp/bodhi-browser-types"),y=(e,r,t)=>{const n=r?.error?.message||`HTTP ${e}`;return new i.BodhiApiError(e,r,n,t)},o=(e,r)=>new i.BodhiError(e,r);function p(e){throw e==="denied"?o("access_request_denied","Access request was denied"):e==="expired"?o("access_request_expired","Access request expired"):o("access_request_failed",`Access request failed: ${e}`)}const s={NOT_REACHABLE:{message:"server is not reachable on given url",type:"network_error"},SERVER_NOT_READY:{message:"server is not in ready state, configure to complete setup",type:"extension_error"}},E={status:"not-reachable",version:null,error:s.NOT_REACHABLE},u={status:"pending-extension-ready",version:null,error:null},d={status:"not-connected",version:null,error:null};function c(e){return e.status==="ready"}function f(e,r="unknown",t=s.SERVER_NOT_READY,n,A){return{status:e,version:r,error:t,deployment:n??null,client_id:A??null}}function a(e){return e.type==="extension"}function l(e){return e.type==="direct"}function I(e){return typeof e.server=="object"&&e.server.status!=="not-connected"&&c(e.server)}function R(e){return e.url!==null}const O={type:"direct",url:null,server:d};function v(e,r="unknown"){return{type:"direct",server:{status:"ready",version:r,error:null},url:e}}function D(e){return{type:"direct",server:E,url:e}}function h(e,r){return{type:"direct",server:r,url:e}}const _={type:"extension",extension:"not-initialized",extensionId:null,server:u},S={type:"extension",extension:"not-found",extensionId:null,server:u};function x(e){return e.extension==="ready"&&e.server.status!=="pending-extension-ready"&&c(e.server)}function T(e){return e.extension==="ready"}function C(){return _}function g(){return S}function b(e){return a(e)?T(e):R(e)}function B(e){return e.server}function L(e){return a(e)?e.extensionId??void 0:void 0}function w(e){return l(e)?e.url??void 0:void 0}function k(e){return e.status==="authenticated"}function q(e){return e.status==="loading"}function m(e){return e.status==="error"}const P={status:"idle",user:null,accessToken:null,error:null,refreshToken:null,expiresAt:null,isTokenRefresh:!1};class V{constructor(){this.store=new Map}async get(r){return this.store.get(r)??null}async set(r){Object.entries(r).forEach(([t,n])=>{this.store.set(t,String(n))})}async remove(r){r.forEach(t=>this.store.delete(t))}}const H=()=>{};function j(e,r){return{kind:"event",type:e,payload:r}}function N(e,r,t){return{kind:"response",type:r,requestId:e,payload:t}}function K(e,r){return{kind:"error",requestId:e,error:r}}function U(e,r){const t=r[e.type];if(!t)return null;const n=t(e.payload);return N(e.requestId,e.type,n)}Object.defineProperty(exports,"BodhiApiError",{enumerable:!0,get:()=>i.BodhiApiError});Object.defineProperty(exports,"BodhiError",{enumerable:!0,get:()=>i.BodhiError});Object.defineProperty(exports,"unwrapResponse",{enumerable:!0,get:()=>i.unwrapResponse});exports.BACKEND_SERVER_NOT_CONNECTED=d;exports.BACKEND_SERVER_NOT_REACHABLE=E;exports.DIRECT_STATE_NOT_INITIALIZED=O;exports.EXTENSION_STATE_NOT_FOUND=S;exports.EXTENSION_STATE_NOT_INITIALIZED=_;exports.INITIAL_AUTH_STATE=P;exports.InMemoryStorage=V;exports.NOOP_STATE_CALLBACK=H;exports.PENDING_EXTENSION_READY=u;exports.SERVER_ERROR_CODES=s;exports.backendServerNotReady=f;exports.buildError=K;exports.buildEvent=j;exports.buildResponse=N;exports.createApiError=y;exports.createDirectStateNotReachable=D;exports.createDirectStateNotReady=h;exports.createDirectStateReady=v;exports.createExtensionStateNotFound=g;exports.createExtensionStateNotInitialized=C;exports.createOperationError=o;exports.getBackendServerState=B;exports.getExtensionId=L;exports.getServerUrl=w;exports.handleRequest=U;exports.isAuthError=m;exports.isAuthLoading=q;exports.isAuthenticated=k;exports.isClientReady=b;exports.isDirectClientReady=R;exports.isDirectServerReady=I;exports.isDirectState=l;exports.isExtensionClientReady=T;exports.isExtensionServerReady=x;exports.isExtensionState=a;exports.isServerReady=c;exports.throwAccessRequestDenialError=p;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ export type { BackendServerState, ClientState, ConnectionMode, DirectState, Exte
|
|
|
10
10
|
export { INITIAL_AUTH_STATE, isAuthError, isAuthLoading, isAuthenticated } from './auth';
|
|
11
11
|
export type { AuthError, AuthState, AuthStatus } from './auth';
|
|
12
12
|
export type { Tokens, UserInfo } from './user-info';
|
|
13
|
-
export type { UserScope } from '@bodhiapp/ts-client';
|
|
13
|
+
export type { FlowType, RequestedResourcesV1, UserScope } from '@bodhiapp/ts-client';
|
|
14
14
|
export type { ClientConfig, DiscoveryResult, LogLevel } from './config';
|
|
15
15
|
export type LoginProgressStage = 'requesting' | 'reviewing' | 'authenticating';
|
|
16
16
|
export type LoginProgressCallback = (stage: LoginProgressStage) => void;
|
|
@@ -24,6 +24,9 @@ export interface LoginOptions {
|
|
|
24
24
|
pollTimeoutMs?: number;
|
|
25
25
|
}
|
|
26
26
|
export type { BrowserInfo, OSInfo } from './platform';
|
|
27
|
+
export { InMemoryStorage } from './storage';
|
|
28
|
+
export type { IStorage, InitialTokens } from './storage';
|
|
27
29
|
export { NOOP_STATE_CALLBACK } from './callback';
|
|
28
30
|
export type { AuthStateChange, ClientStateChange, StateChange, StateChangeCallback, } from './callback';
|
|
29
31
|
export { buildError, buildEvent, buildResponse, handleRequest } from '../onboarding/protocol-utils';
|
|
32
|
+
export type { McpFetchLike, McpTransportConfig } from '../mcp-fetch';
|
package/dist/types/index.esm.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { BodhiApiError as
|
|
2
|
-
import { BodhiApiError as
|
|
1
|
+
import { BodhiApiError as d, BodhiError as l } from "@bodhiapp/bodhi-browser-types";
|
|
2
|
+
import { BodhiApiError as M, BodhiError as Z, unwrapResponse as $ } from "@bodhiapp/bodhi-browser-types";
|
|
3
3
|
const v = (e, r, n) => {
|
|
4
4
|
const t = r?.error?.message || `HTTP ${e}`;
|
|
5
|
-
return new
|
|
5
|
+
return new d(e, r, t, n);
|
|
6
6
|
}, o = (e, r) => new l(e, r);
|
|
7
7
|
function S(e) {
|
|
8
8
|
throw e === "denied" ? o("access_request_denied", "Access request was denied") : e === "expired" ? o("access_request_expired", "Access request expired") : o("access_request_failed", `Access request failed: ${e}`);
|
|
@@ -24,7 +24,7 @@ const i = {
|
|
|
24
24
|
status: "pending-extension-ready",
|
|
25
25
|
version: null,
|
|
26
26
|
error: null
|
|
27
|
-
},
|
|
27
|
+
}, f = {
|
|
28
28
|
status: "not-connected",
|
|
29
29
|
version: null,
|
|
30
30
|
error: null
|
|
@@ -32,39 +32,39 @@ const i = {
|
|
|
32
32
|
function u(e) {
|
|
33
33
|
return e.status === "ready";
|
|
34
34
|
}
|
|
35
|
-
function
|
|
35
|
+
function h(e, r = "unknown", n = i.SERVER_NOT_READY, t, a) {
|
|
36
36
|
return {
|
|
37
37
|
status: e,
|
|
38
38
|
version: r,
|
|
39
39
|
error: n,
|
|
40
40
|
deployment: t ?? null,
|
|
41
|
-
client_id:
|
|
41
|
+
client_id: a ?? null
|
|
42
42
|
};
|
|
43
43
|
}
|
|
44
44
|
function c(e) {
|
|
45
45
|
return e.type === "extension";
|
|
46
46
|
}
|
|
47
|
-
function
|
|
47
|
+
function _(e) {
|
|
48
48
|
return e.type === "direct";
|
|
49
49
|
}
|
|
50
|
-
function
|
|
50
|
+
function x(e) {
|
|
51
51
|
return typeof e.server == "object" && e.server.status !== "not-connected" && u(e.server);
|
|
52
52
|
}
|
|
53
53
|
function p(e) {
|
|
54
54
|
return e.url !== null;
|
|
55
55
|
}
|
|
56
|
-
const
|
|
56
|
+
const I = {
|
|
57
57
|
type: "direct",
|
|
58
58
|
url: null,
|
|
59
|
-
server:
|
|
59
|
+
server: f
|
|
60
60
|
};
|
|
61
61
|
function O(e, r = "unknown") {
|
|
62
62
|
return { type: "direct", server: { status: "ready", version: r, error: null }, url: e };
|
|
63
63
|
}
|
|
64
|
-
function
|
|
64
|
+
function D(e) {
|
|
65
65
|
return { type: "direct", server: E, url: e };
|
|
66
66
|
}
|
|
67
|
-
function
|
|
67
|
+
function g(e, r) {
|
|
68
68
|
return { type: "direct", server: r, url: e };
|
|
69
69
|
}
|
|
70
70
|
const R = {
|
|
@@ -72,26 +72,26 @@ const R = {
|
|
|
72
72
|
extension: "not-initialized",
|
|
73
73
|
extensionId: null,
|
|
74
74
|
server: s
|
|
75
|
-
},
|
|
75
|
+
}, y = {
|
|
76
76
|
type: "extension",
|
|
77
77
|
extension: "not-found",
|
|
78
78
|
extensionId: null,
|
|
79
79
|
server: s
|
|
80
80
|
};
|
|
81
|
-
function
|
|
81
|
+
function C(e) {
|
|
82
82
|
return e.extension === "ready" && e.server.status !== "pending-extension-ready" && u(e.server);
|
|
83
83
|
}
|
|
84
|
-
function
|
|
84
|
+
function A(e) {
|
|
85
85
|
return e.extension === "ready";
|
|
86
86
|
}
|
|
87
|
-
function
|
|
87
|
+
function w() {
|
|
88
88
|
return R;
|
|
89
89
|
}
|
|
90
|
-
function
|
|
91
|
-
return
|
|
90
|
+
function k() {
|
|
91
|
+
return y;
|
|
92
92
|
}
|
|
93
|
-
function
|
|
94
|
-
return c(e) ?
|
|
93
|
+
function B(e) {
|
|
94
|
+
return c(e) ? A(e) : p(e);
|
|
95
95
|
}
|
|
96
96
|
function q(e) {
|
|
97
97
|
return e.server;
|
|
@@ -100,7 +100,7 @@ function L(e) {
|
|
|
100
100
|
return c(e) ? e.extensionId ?? void 0 : void 0;
|
|
101
101
|
}
|
|
102
102
|
function b(e) {
|
|
103
|
-
return
|
|
103
|
+
return _(e) ? e.url ?? void 0 : void 0;
|
|
104
104
|
}
|
|
105
105
|
function m(e) {
|
|
106
106
|
return e.status === "authenticated";
|
|
@@ -115,62 +115,83 @@ const K = {
|
|
|
115
115
|
status: "idle",
|
|
116
116
|
user: null,
|
|
117
117
|
accessToken: null,
|
|
118
|
-
error: null
|
|
119
|
-
|
|
118
|
+
error: null,
|
|
119
|
+
refreshToken: null,
|
|
120
|
+
expiresAt: null,
|
|
121
|
+
isTokenRefresh: !1
|
|
120
122
|
};
|
|
121
|
-
|
|
123
|
+
class P {
|
|
124
|
+
constructor() {
|
|
125
|
+
this.store = /* @__PURE__ */ new Map();
|
|
126
|
+
}
|
|
127
|
+
async get(r) {
|
|
128
|
+
return this.store.get(r) ?? null;
|
|
129
|
+
}
|
|
130
|
+
async set(r) {
|
|
131
|
+
Object.entries(r).forEach(([n, t]) => {
|
|
132
|
+
this.store.set(n, String(t));
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
async remove(r) {
|
|
136
|
+
r.forEach((n) => this.store.delete(n));
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
const U = () => {
|
|
140
|
+
};
|
|
141
|
+
function X(e, r) {
|
|
122
142
|
return { kind: "event", type: e, payload: r };
|
|
123
143
|
}
|
|
124
144
|
function T(e, r, n) {
|
|
125
145
|
return { kind: "response", type: r, requestId: e, payload: n };
|
|
126
146
|
}
|
|
127
|
-
function
|
|
147
|
+
function Y(e, r) {
|
|
128
148
|
return { kind: "error", requestId: e, error: r };
|
|
129
149
|
}
|
|
130
|
-
function
|
|
150
|
+
function j(e, r) {
|
|
131
151
|
const n = r[e.type];
|
|
132
152
|
if (!n) return null;
|
|
133
153
|
const t = n(e.payload);
|
|
134
154
|
return T(e.requestId, e.type, t);
|
|
135
155
|
}
|
|
136
156
|
export {
|
|
137
|
-
|
|
157
|
+
f as BACKEND_SERVER_NOT_CONNECTED,
|
|
138
158
|
E as BACKEND_SERVER_NOT_REACHABLE,
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
159
|
+
M as BodhiApiError,
|
|
160
|
+
Z as BodhiError,
|
|
161
|
+
I as DIRECT_STATE_NOT_INITIALIZED,
|
|
162
|
+
y as EXTENSION_STATE_NOT_FOUND,
|
|
143
163
|
R as EXTENSION_STATE_NOT_INITIALIZED,
|
|
144
164
|
K as INITIAL_AUTH_STATE,
|
|
145
|
-
P as
|
|
165
|
+
P as InMemoryStorage,
|
|
166
|
+
U as NOOP_STATE_CALLBACK,
|
|
146
167
|
s as PENDING_EXTENSION_READY,
|
|
147
168
|
i as SERVER_ERROR_CODES,
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
169
|
+
h as backendServerNotReady,
|
|
170
|
+
Y as buildError,
|
|
171
|
+
X as buildEvent,
|
|
151
172
|
T as buildResponse,
|
|
152
173
|
v as createApiError,
|
|
153
|
-
|
|
154
|
-
|
|
174
|
+
D as createDirectStateNotReachable,
|
|
175
|
+
g as createDirectStateNotReady,
|
|
155
176
|
O as createDirectStateReady,
|
|
156
|
-
|
|
157
|
-
|
|
177
|
+
k as createExtensionStateNotFound,
|
|
178
|
+
w as createExtensionStateNotInitialized,
|
|
158
179
|
o as createOperationError,
|
|
159
180
|
q as getBackendServerState,
|
|
160
181
|
L as getExtensionId,
|
|
161
182
|
b as getServerUrl,
|
|
162
|
-
|
|
183
|
+
j as handleRequest,
|
|
163
184
|
V as isAuthError,
|
|
164
185
|
H as isAuthLoading,
|
|
165
186
|
m as isAuthenticated,
|
|
166
|
-
|
|
187
|
+
B as isClientReady,
|
|
167
188
|
p as isDirectClientReady,
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
189
|
+
x as isDirectServerReady,
|
|
190
|
+
_ as isDirectState,
|
|
191
|
+
A as isExtensionClientReady,
|
|
192
|
+
C as isExtensionServerReady,
|
|
172
193
|
c as isExtensionState,
|
|
173
194
|
u as isServerReady,
|
|
174
195
|
S as throwAccessRequestDenialError,
|
|
175
|
-
|
|
196
|
+
$ as unwrapResponse
|
|
176
197
|
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pluggable storage interface and implementations for token persistence
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Storage adapter interface for token persistence.
|
|
6
|
+
* Implementations: LocalStorageAdapter (web), ChromeSessionStorageAdapter (ext), InMemoryStorage (CLI/headless)
|
|
7
|
+
*/
|
|
8
|
+
export interface IStorage {
|
|
9
|
+
get(key: string): Promise<string | null>;
|
|
10
|
+
set(items: Record<string, string | number>): Promise<void>;
|
|
11
|
+
remove(keys: string[]): Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* In-memory storage adapter for CLI/headless use cases.
|
|
15
|
+
* Tokens live only in process memory — use onStateChange callback for external persistence.
|
|
16
|
+
*/
|
|
17
|
+
export declare class InMemoryStorage implements IStorage {
|
|
18
|
+
private store;
|
|
19
|
+
get(key: string): Promise<string | null>;
|
|
20
|
+
set(items: Record<string, string | number>): Promise<void>;
|
|
21
|
+
remove(keys: string[]): Promise<void>;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Pre-existing tokens for injection during client initialization.
|
|
25
|
+
* Used by CLI/headless hosts that obtain OAuth tokens independently.
|
|
26
|
+
*/
|
|
27
|
+
export interface InitialTokens {
|
|
28
|
+
accessToken: string;
|
|
29
|
+
refreshToken?: string;
|
|
30
|
+
expiresAt?: number;
|
|
31
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bodhiapp/bodhi-js-core",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.32",
|
|
4
4
|
"description": "Core types and interfaces for Bodhi Browser SDK",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/bodhi-core.cjs.js",
|
|
@@ -24,6 +24,11 @@
|
|
|
24
24
|
"types": "./dist/api/index.d.ts",
|
|
25
25
|
"import": "./dist/api/index.esm.js",
|
|
26
26
|
"require": "./dist/api/index.cjs.js"
|
|
27
|
+
},
|
|
28
|
+
"./mcp": {
|
|
29
|
+
"types": "./dist/mcp.d.ts",
|
|
30
|
+
"import": "./dist/mcp.esm.js",
|
|
31
|
+
"require": "./dist/mcp.cjs.js"
|
|
27
32
|
}
|
|
28
33
|
},
|
|
29
34
|
"files": [
|
|
@@ -53,16 +58,26 @@
|
|
|
53
58
|
"build:prod": "npm run copy-deps && npm run build-cli && vite build --mode production",
|
|
54
59
|
"lint": "eslint . --ext .js,.jsx,.ts,.tsx && prettier --check .",
|
|
55
60
|
"lint:fix": "prettier --write . && eslint . --ext .js,.jsx,.ts,.tsx --fix",
|
|
56
|
-
"typecheck": "tsc --noEmit"
|
|
61
|
+
"typecheck": "tsc --noEmit",
|
|
62
|
+
"test": "vitest run"
|
|
63
|
+
},
|
|
64
|
+
"peerDependencies": {
|
|
65
|
+
"@modelcontextprotocol/sdk": "^1.0.0"
|
|
66
|
+
},
|
|
67
|
+
"peerDependenciesMeta": {
|
|
68
|
+
"@modelcontextprotocol/sdk": {
|
|
69
|
+
"optional": true
|
|
70
|
+
}
|
|
57
71
|
},
|
|
58
72
|
"dependencies": {
|
|
59
|
-
"@bodhiapp/bodhi-browser-types": "0.0.
|
|
60
|
-
"@bodhiapp/setup-modal-types": "0.0.
|
|
61
|
-
"@bodhiapp/ts-client": "0.1.
|
|
73
|
+
"@bodhiapp/bodhi-browser-types": "0.0.32",
|
|
74
|
+
"@bodhiapp/setup-modal-types": "0.0.32",
|
|
75
|
+
"@bodhiapp/ts-client": "0.1.26",
|
|
62
76
|
"ua-parser-js": "^1.0.40"
|
|
63
77
|
},
|
|
64
78
|
"devDependencies": {
|
|
65
79
|
"@eslint/js": "^9.23.0",
|
|
80
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
66
81
|
"@types/node": "^20.19.10",
|
|
67
82
|
"@types/ua-parser-js": "^0.7.39",
|
|
68
83
|
"@typescript-eslint/eslint-plugin": "8.28.0",
|
|
@@ -76,6 +91,7 @@
|
|
|
76
91
|
"tslib": "^2.6.2",
|
|
77
92
|
"typescript": "^5.8.3",
|
|
78
93
|
"vite": "^7.1.12",
|
|
79
|
-
"vite-plugin-dts": "^4.5.4"
|
|
94
|
+
"vite-plugin-dts": "^4.5.4",
|
|
95
|
+
"vitest": "^4.1.2"
|
|
80
96
|
}
|
|
81
97
|
}
|