@apteva/web-sdk 0.1.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.
package/CHANGELOG.md ADDED
@@ -0,0 +1,14 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0 — 2026-05-13
4
+
5
+ Initial release.
6
+
7
+ - `ApteveClient` — base client with session-cookie + Bearer + `?api_key=` auth carriers, `credentials: include` for cross-origin cookie flow, configurable timeout, `onUnauthorized` hook.
8
+ - `client.auth` namespace — `register`, `login`, `logout`, `me`, `status`, `changePassword`, `listKeys`, `createKey`, `deleteKey`.
9
+ - `client.app(name)` — typed handle for any installed app: `get/post/put/patch/del` for HTTP routes + `tool(name, args)` for MCP calls. Generic type parameter for response shape.
10
+ - `unwrapMCP` — exposed standalone for callers that want to handle the JSON-RPC envelope themselves.
11
+ - Window helpers — `readAptevaInjection`, `pickKioskKey`, `pickBaseURL` for UIs hosted as static apps on apteva-server itself.
12
+ - `client.sseURL` + `client.app(...).mcpURL` builders for `EventSource` / `<iframe>` / external clients that can't go through `fetch`.
13
+ - `ApteveError` with `.status`, `.body`, `.code`, `.isUnauthorized()`, `.isNotFound()`.
14
+ - 43 tests covering carriers, auth, app HTTP/MCP, envelope unwrap, window helpers.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Apteva
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,143 @@
1
+ # @apteva/web-sdk
2
+
3
+ Browser SDK for calling [apteva-server](https://github.com/apteva/server). Framework-agnostic. ~3 KB minified + gzipped.
4
+
5
+ - **Auth** — session cookies, `Authorization: Bearer`, `X-API-Key`, `?api_key=` query — pick any, the SDK handles them.
6
+ - **App data** — `client.app("crm").get("/contacts")` reverse-proxies through `/api/apps/<name>/*`.
7
+ - **App tools** — `client.app("crm").tool("contacts_search", {…})` posts an MCP `tools/call`, unwraps the JSON-RPC envelope, returns the tool's natural shape.
8
+ - **Static-app mode** — when the UI is hosted by apteva-server itself (`runtime.kind: static`), `pickBaseURL` and `pickKioskKey` read the `<script>window.__APTEVA_APP__</script>` block the server injects.
9
+
10
+ ## Install
11
+
12
+ ```sh
13
+ bun add @apteva/web-sdk
14
+ # or
15
+ npm install @apteva/web-sdk
16
+ ```
17
+
18
+ ## Quick start
19
+
20
+ ```ts
21
+ import { ApteveClient } from "@apteva/web-sdk";
22
+
23
+ const apteva = new ApteveClient({
24
+ baseURL: "https://agents.example.com",
25
+ // Optional. Omit to rely on the session cookie (after auth.login).
26
+ apiKey: process.env.NEXT_PUBLIC_APTEVA_KEY,
27
+ });
28
+
29
+ // Sign in (sets the session cookie on the apteva-server domain).
30
+ const me = await apteva.auth.login("you@example.com", "hunter2");
31
+
32
+ // Read from any installed app's HTTP routes.
33
+ const health = await apteva.app("flexylead").get("/healthz");
34
+
35
+ // Call an MCP tool — the envelope is unwrapped for you.
36
+ type Lead = { id: number; name: string; status: string };
37
+ const { leads } = await apteva.app("flexylead").tool<{ leads: Lead[] }>(
38
+ "leads_list",
39
+ { limit: 25 },
40
+ );
41
+ ```
42
+
43
+ ## Auth carriers
44
+
45
+ The SDK sends `credentials: "include"` on every request, so a session cookie set by `auth.login` flows automatically — same-origin always, cross-origin when the apteva-server's `CORS_ORIGIN` allowlists your domain (the default `permissive` mode echoes any origin).
46
+
47
+ You can layer on an API key by setting `apiKey` in the constructor or calling `client.setApiKey(...)` at runtime. Bearer-wins-over-cookie on the wire.
48
+
49
+ ```ts
50
+ const apteva = new ApteveClient({
51
+ baseURL: "...",
52
+ apiKey: "sk-...", // optional
53
+ onUnauthorized: () => router.push("/login"), // fires once per 401
54
+ timeoutMs: 30_000, // default, 0 disables
55
+ });
56
+ ```
57
+
58
+ ## App HTTP routes
59
+
60
+ `client.app(name)` returns a handle with `get / post / put / patch / del` that route to `/api/apps/<name>/<path>`. Same auth, same proxy, same error model.
61
+
62
+ ```ts
63
+ await apteva.app("storage").post("/upload", { ... });
64
+ const file = await apteva.app("storage").get<File>("/files/42");
65
+ ```
66
+
67
+ ## MCP tools
68
+
69
+ `client.app(name).tool(toolName, args)` does the round-trip through `/api/apps/<name>/mcp`:
70
+
71
+ ```ts
72
+ const result = await apteva.app("tables").tool<{ rows: Row[]; total: number }>(
73
+ "rows_search",
74
+ { table: "leads", limit: 50 },
75
+ );
76
+ ```
77
+
78
+ If the MCP call returns a JSON-RPC error, the SDK throws `ApteveError(-1, message, code)` — same `catch` block as HTTP errors.
79
+
80
+ For lower-level usage, `client.callTool(appName, toolName, args)` and the standalone `unwrapMCP(envelope)` are both exported.
81
+
82
+ ## Error handling
83
+
84
+ Every non-2xx response and every MCP error throws an `ApteveError`:
85
+
86
+ ```ts
87
+ try {
88
+ await apteva.app("crm").tool("contacts_get", { id: 999 });
89
+ } catch (err) {
90
+ if (err instanceof ApteveError) {
91
+ if (err.isUnauthorized()) ... // 401
92
+ if (err.isNotFound()) ... // 404
93
+ if (err.status === -1) ... // MCP-level error
94
+ console.error(err.body);
95
+ }
96
+ }
97
+ ```
98
+
99
+ Network failures (no DNS, refused connection) surface as `ApteveError(0, "...")`. Timeouts surface as `ApteveError(0, "request timeout after Xms")`.
100
+
101
+ ## Hosted on apteva-server itself
102
+
103
+ If your UI is installed as a `runtime.kind: static` app, apteva-server injects a config block. The SDK picks it up:
104
+
105
+ ```ts
106
+ import { ApteveClient, pickBaseURL, pickKioskKey } from "@apteva/web-sdk";
107
+
108
+ const apteva = new ApteveClient({
109
+ baseURL: pickBaseURL(), // window.__APTEVA_APP__.api_base
110
+ apiKey: pickKioskKey(), // ?api_key=... > install config > undefined
111
+ });
112
+ ```
113
+
114
+ The same code also works fine when hosted externally (Vercel, etc.) — `pickBaseURL` returns `""` (same-origin) when nothing is injected, and `pickKioskKey` returns `undefined` (fall back to cookie auth).
115
+
116
+ ## SSE / EventSource
117
+
118
+ Browsers can't set headers on `EventSource`, so an API key has to ride as `?api_key=`. The SDK has a helper:
119
+
120
+ ```ts
121
+ const url = apteva.sseURL("/api/events", { project_id: "abc" });
122
+ // → https://agents.example.com/api/events?project_id=abc&api_key=sk-...
123
+ new EventSource(url);
124
+ ```
125
+
126
+ ## TypeScript
127
+
128
+ Ships `.d.ts` types. `client.app<DefaultShape>(name).get<R>(path)` lets you type either per-call or per-app.
129
+
130
+ ## Example
131
+
132
+ A complete React 19 + Tailwind v4 dashboard that signs in, reads leads from the Tables app, and browses arbitrary tables lives in [`examples/dashboard/`](./examples/dashboard) in the repo. Run with:
133
+
134
+ ```sh
135
+ cd examples/dashboard
136
+ bun install
137
+ API_BASE=http://localhost:5280 bun run build
138
+ bun run serve
139
+ ```
140
+
141
+ ## License
142
+
143
+ MIT
@@ -0,0 +1,52 @@
1
+ import type { ApteveClientOptions, AuthStatus, MCPCallResponse, User } from "./types.js";
2
+ export declare class ApteveClient {
3
+ private readonly baseURL;
4
+ private apiKey?;
5
+ private readonly fetchImpl;
6
+ private readonly onUnauthorized?;
7
+ private readonly timeoutMs;
8
+ constructor(opts: ApteveClientOptions);
9
+ setApiKey(key: string | undefined): void;
10
+ getApiKey(): string | undefined;
11
+ readonly auth: {
12
+ register: (email: string, password: string, name?: string) => Promise<{
13
+ user: User;
14
+ }>;
15
+ login: (email: string, password: string) => Promise<User>;
16
+ logout: () => Promise<void>;
17
+ me: () => Promise<User>;
18
+ status: () => Promise<AuthStatus>;
19
+ changePassword: (current: string, next: string) => Promise<void>;
20
+ listKeys: () => Promise<{
21
+ id: number;
22
+ name: string;
23
+ created_at: string;
24
+ }[]>;
25
+ createKey: (name: string) => Promise<{
26
+ id: number;
27
+ key: string;
28
+ }>;
29
+ deleteKey: (id: number) => Promise<void>;
30
+ };
31
+ app<T = unknown>(name: string): AppHandle<T>;
32
+ callTool<R>(appName: string, toolName: string, args: Record<string, unknown>): Promise<R>;
33
+ get<R>(path: string, init?: RequestInit): Promise<R>;
34
+ post<R>(path: string, body?: unknown, init?: RequestInit): Promise<R>;
35
+ put<R>(path: string, body?: unknown, init?: RequestInit): Promise<R>;
36
+ patch<R>(path: string, body?: unknown, init?: RequestInit): Promise<R>;
37
+ del<R>(path: string, init?: RequestInit): Promise<R>;
38
+ sseURL(path: string, params?: Record<string, string | number | undefined>): string;
39
+ private request;
40
+ }
41
+ export declare function unwrapMCP<R>(env: MCPCallResponse<unknown>): R;
42
+ export interface AppHandle<TDefault = unknown> {
43
+ readonly name: string;
44
+ get<R = TDefault>(path: string): Promise<R>;
45
+ post<R = TDefault>(path: string, body?: unknown): Promise<R>;
46
+ put<R = TDefault>(path: string, body?: unknown): Promise<R>;
47
+ patch<R = TDefault>(path: string, body?: unknown): Promise<R>;
48
+ del<R = TDefault>(path: string): Promise<R>;
49
+ tool<R = TDefault>(name: string, args?: Record<string, unknown>): Promise<R>;
50
+ mcpURL(queryParams?: Record<string, string>): string;
51
+ }
52
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/dist/client.js ADDED
@@ -0,0 +1,194 @@
1
+ import { ApteveError } from "./errors.js";
2
+ const DEFAULT_TIMEOUT_MS = 30_000;
3
+ export class ApteveClient {
4
+ baseURL;
5
+ apiKey;
6
+ fetchImpl;
7
+ onUnauthorized;
8
+ timeoutMs;
9
+ constructor(opts) {
10
+ this.baseURL = opts.baseURL.replace(/\/+$/, "");
11
+ this.apiKey = opts.apiKey;
12
+ this.fetchImpl = opts.fetch ?? globalThis.fetch.bind(globalThis);
13
+ this.onUnauthorized = opts.onUnauthorized;
14
+ this.timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
15
+ }
16
+ // Swap the API key at runtime (e.g. after the user mints a fresh
17
+ // one in settings). Pass undefined to fall back to cookie auth.
18
+ setApiKey(key) {
19
+ this.apiKey = key;
20
+ }
21
+ getApiKey() {
22
+ return this.apiKey;
23
+ }
24
+ // Auth surface. Maps 1:1 onto /api/auth/*. login() sets a cookie
25
+ // on the server side that subsequent requests pick up automatically
26
+ // when credentials: "include" is sent.
27
+ auth = {
28
+ register: (email, password, name) => this.post("/api/auth/register", { email, password, name }),
29
+ login: (email, password) => this.post("/api/auth/login", { email, password }),
30
+ logout: () => this.post("/api/auth/logout", {}),
31
+ me: () => this.get("/api/auth/me"),
32
+ status: () => this.get("/api/auth/status"),
33
+ changePassword: (current, next) => this.post("/api/auth/password", { current, next }),
34
+ listKeys: () => this.get("/api/auth/keys"),
35
+ createKey: (name) => this.post("/api/auth/keys", { name }),
36
+ deleteKey: (id) => this.del(`/api/auth/keys/${id}`),
37
+ };
38
+ // Build a handle for one installed app. The returned object knows
39
+ // both the HTTP route surface (/api/apps/<name>/<route>) and the
40
+ // MCP tool surface (/api/apps/<name>/mcp). T is the default return
41
+ // type for typed route helpers — defaults to unknown so callers
42
+ // either pass a per-call generic or stick to `unknown`.
43
+ app(name) {
44
+ const base = `/api/apps/${encodeURIComponent(name)}`;
45
+ return {
46
+ name,
47
+ get: (path) => this.get(base + path),
48
+ post: (path, body) => this.post(base + path, body),
49
+ put: (path, body) => this.put(base + path, body),
50
+ patch: (path, body) => this.patch(base + path, body),
51
+ del: (path) => this.del(base + path),
52
+ tool: (toolName, args = {}) => this.callTool(name, toolName, args),
53
+ mcpURL: (queryParams) => {
54
+ const u = new URL(this.baseURL + base + "/mcp", "http://_");
55
+ if (queryParams) {
56
+ for (const [k, v] of Object.entries(queryParams)) {
57
+ u.searchParams.set(k, v);
58
+ }
59
+ }
60
+ return this.baseURL ? this.baseURL + u.pathname + u.search : u.pathname + u.search;
61
+ },
62
+ };
63
+ }
64
+ // Lower-level direct MCP call. Most callers should use
65
+ // client.app("name").tool("name", args) which routes through this.
66
+ async callTool(appName, toolName, args) {
67
+ const path = `/api/apps/${encodeURIComponent(appName)}/mcp`;
68
+ const body = {
69
+ jsonrpc: "2.0",
70
+ id: 1,
71
+ method: "tools/call",
72
+ params: { name: toolName, arguments: args },
73
+ };
74
+ const env = await this.post(path, body);
75
+ return unwrapMCP(env);
76
+ }
77
+ // --- raw HTTP helpers (exposed so consumers can hit endpoints the
78
+ // SDK doesn't yet wrap) ---
79
+ get(path, init) {
80
+ return this.request("GET", path, undefined, init);
81
+ }
82
+ post(path, body, init) {
83
+ return this.request("POST", path, body, init);
84
+ }
85
+ put(path, body, init) {
86
+ return this.request("PUT", path, body, init);
87
+ }
88
+ patch(path, body, init) {
89
+ return this.request("PATCH", path, body, init);
90
+ }
91
+ del(path, init) {
92
+ return this.request("DELETE", path, undefined, init);
93
+ }
94
+ // Build a fully-qualified URL for an SSE endpoint (EventSource can't
95
+ // send custom headers, so an API key has to ride as ?api_key=).
96
+ // Cookie auth works on same-origin without query-string fallback.
97
+ sseURL(path, params) {
98
+ const url = new URL(this.baseURL + path, "http://_");
99
+ if (params) {
100
+ for (const [k, v] of Object.entries(params)) {
101
+ if (v !== undefined && v !== "")
102
+ url.searchParams.set(k, String(v));
103
+ }
104
+ }
105
+ if (this.apiKey && !url.searchParams.has("api_key")) {
106
+ url.searchParams.set("api_key", this.apiKey);
107
+ }
108
+ return this.baseURL ? this.baseURL + url.pathname + url.search : url.pathname + url.search;
109
+ }
110
+ // --- internals ---
111
+ async request(method, path, body, init) {
112
+ const url = this.baseURL + path;
113
+ const headers = new Headers(init?.headers);
114
+ if (!headers.has("Accept"))
115
+ headers.set("Accept", "application/json");
116
+ if (body !== undefined && !headers.has("Content-Type")) {
117
+ headers.set("Content-Type", "application/json");
118
+ }
119
+ if (this.apiKey && !headers.has("Authorization")) {
120
+ headers.set("Authorization", `Bearer ${this.apiKey}`);
121
+ }
122
+ const ac = this.timeoutMs > 0 ? new AbortController() : undefined;
123
+ const timer = ac
124
+ ? setTimeout(() => ac.abort(), this.timeoutMs)
125
+ : undefined;
126
+ let res;
127
+ try {
128
+ res = await this.fetchImpl(url, {
129
+ method,
130
+ credentials: "include",
131
+ ...init,
132
+ headers,
133
+ body: body === undefined ? init?.body : JSON.stringify(body),
134
+ signal: ac?.signal ?? init?.signal,
135
+ });
136
+ }
137
+ catch (err) {
138
+ if (timer)
139
+ clearTimeout(timer);
140
+ if (err instanceof Error && err.name === "AbortError") {
141
+ throw new ApteveError(0, `request timeout after ${this.timeoutMs}ms`);
142
+ }
143
+ throw new ApteveError(0, err instanceof Error ? err.message : String(err));
144
+ }
145
+ if (timer)
146
+ clearTimeout(timer);
147
+ if (res.status === 401) {
148
+ this.onUnauthorized?.();
149
+ const text = await readBody(res);
150
+ throw new ApteveError(401, text || "unauthorized");
151
+ }
152
+ if (!res.ok) {
153
+ const text = await readBody(res);
154
+ throw new ApteveError(res.status, text || res.statusText);
155
+ }
156
+ const ct = res.headers.get("Content-Type") ?? "";
157
+ if (res.status === 204)
158
+ return undefined;
159
+ if (ct.includes("application/json")) {
160
+ return (await res.json());
161
+ }
162
+ return (await res.text());
163
+ }
164
+ }
165
+ async function readBody(res) {
166
+ try {
167
+ return await res.text();
168
+ }
169
+ catch {
170
+ return "";
171
+ }
172
+ }
173
+ // Strip the MCP JSON-RPC envelope so callers see the tool's natural
174
+ // return shape. Mirrors app-sdk/caller.go::CallAppResult. Three cases:
175
+ // 1. envelope.error → throw ApteveError(-1, message, code)
176
+ // 2. envelope.result.content[0].text → JSON.parse(text), return it
177
+ // 3. envelope has neither (the platform already short-circuited an
178
+ // unwrapped response) → cast and return
179
+ export function unwrapMCP(env) {
180
+ if (env && env.error) {
181
+ throw new ApteveError(-1, env.error.message, env.error.code);
182
+ }
183
+ const text = env?.result?.content?.[0]?.text;
184
+ if (typeof text !== "string") {
185
+ return env;
186
+ }
187
+ try {
188
+ return JSON.parse(text);
189
+ }
190
+ catch (err) {
191
+ throw new ApteveError(-1, `MCP response was not valid JSON: ${err instanceof Error ? err.message : String(err)}`);
192
+ }
193
+ }
194
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ export declare class ApteveError extends Error {
2
+ status: number;
3
+ body: string;
4
+ code?: number;
5
+ constructor(status: number, body: string, code?: number);
6
+ isUnauthorized(): boolean;
7
+ isNotFound(): boolean;
8
+ }
9
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAKA,qBAAa,WAAY,SAAQ,KAAK;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;gBAEF,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM;IAQvD,cAAc,IAAI,OAAO;IAIzB,UAAU,IAAI,OAAO;CAGtB"}
package/dist/errors.js ADDED
@@ -0,0 +1,24 @@
1
+ // Thrown for every non-2xx HTTP response and every MCP-level error
2
+ // from /api/apps/<name>/mcp. status is the HTTP status (or 0 for
3
+ // network/transport failures, or -1 for JSON-RPC errors that came
4
+ // back inside a 200 envelope). body is the raw response body (text)
5
+ // or the JSON-RPC error.message — whichever was available.
6
+ export class ApteveError extends Error {
7
+ status;
8
+ body;
9
+ code;
10
+ constructor(status, body, code) {
11
+ super(`HTTP ${status}: ${body}`);
12
+ this.name = "ApteveError";
13
+ this.status = status;
14
+ this.body = body;
15
+ this.code = code;
16
+ }
17
+ isUnauthorized() {
18
+ return this.status === 401;
19
+ }
20
+ isNotFound() {
21
+ return this.status === 404;
22
+ }
23
+ }
24
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,iEAAiE;AACjE,kEAAkE;AAClE,oEAAoE;AACpE,2DAA2D;AAC3D,MAAM,OAAO,WAAY,SAAQ,KAAK;IACpC,MAAM,CAAS;IACf,IAAI,CAAS;IACb,IAAI,CAAU;IAEd,YAAY,MAAc,EAAE,IAAY,EAAE,IAAa;QACrD,KAAK,CAAC,QAAQ,MAAM,KAAK,IAAI,EAAE,CAAC,CAAC;QACjC,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;QAC1B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAED,cAAc;QACZ,OAAO,IAAI,CAAC,MAAM,KAAK,GAAG,CAAC;IAC7B,CAAC;IAED,UAAU;QACR,OAAO,IAAI,CAAC,MAAM,KAAK,GAAG,CAAC;IAC7B,CAAC;CACF"}
@@ -0,0 +1,6 @@
1
+ export { ApteveClient, unwrapMCP } from "./client.js";
2
+ export type { AppHandle } from "./client.js";
3
+ export { ApteveError } from "./errors.js";
4
+ export { readAptevaInjection, pickKioskKey, pickBaseURL, } from "./window.js";
5
+ export type { ApteveClientOptions, AuthCarrier, AuthBranding, AuthStatus, AptevaAppInjection, MCPCallRequest, MCPCallResponse, User, } from "./types.js";
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACtD,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EACL,mBAAmB,EACnB,YAAY,EACZ,WAAW,GACZ,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,mBAAmB,EACnB,WAAW,EACX,YAAY,EACZ,UAAU,EACV,kBAAkB,EAClB,cAAc,EACd,eAAe,EACf,IAAI,GACL,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export { ApteveClient, unwrapMCP } from "./client.js";
2
+ export { ApteveError } from "./errors.js";
3
+ export { readAptevaInjection, pickKioskKey, pickBaseURL, } from "./window.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAEtD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EACL,mBAAmB,EACnB,YAAY,EACZ,WAAW,GACZ,MAAM,aAAa,CAAC"}
@@ -0,0 +1,69 @@
1
+ export interface User {
2
+ user_id?: number;
3
+ id?: number;
4
+ email?: string;
5
+ name?: string;
6
+ role?: string;
7
+ onboarding_complete?: boolean;
8
+ }
9
+ export interface AuthStatus {
10
+ authenticated: boolean;
11
+ user?: User;
12
+ needs_setup?: boolean;
13
+ }
14
+ export interface AuthBranding {
15
+ title_template?: string;
16
+ logo?: string;
17
+ theme_css?: string;
18
+ }
19
+ export interface AptevaAppInjection {
20
+ base?: string;
21
+ api_base?: string;
22
+ app_name?: string;
23
+ install_id?: number;
24
+ default_project?: string;
25
+ kiosk_api_key?: string;
26
+ branding?: AuthBranding;
27
+ installed_apps?: string[];
28
+ }
29
+ declare global {
30
+ interface Window {
31
+ __APTEVA_APP__?: AptevaAppInjection;
32
+ __API_BASE__?: string;
33
+ __DEFAULT_PROJECT__?: string;
34
+ }
35
+ }
36
+ export type AuthCarrier = "cookie" | "apiKey";
37
+ export interface ApteveClientOptions {
38
+ baseURL: string;
39
+ apiKey?: string;
40
+ fetch?: typeof fetch;
41
+ onUnauthorized?: () => void;
42
+ timeoutMs?: number;
43
+ }
44
+ export interface MCPCallRequest {
45
+ jsonrpc: "2.0";
46
+ id: number | string;
47
+ method: "tools/call";
48
+ params: {
49
+ name: string;
50
+ arguments: Record<string, unknown>;
51
+ };
52
+ }
53
+ export interface MCPCallResponse<T = unknown> {
54
+ jsonrpc: "2.0";
55
+ id: number | string;
56
+ result?: {
57
+ content: Array<{
58
+ type: "text";
59
+ text: string;
60
+ }>;
61
+ isError?: boolean;
62
+ };
63
+ error?: {
64
+ code: number;
65
+ message: string;
66
+ data?: T;
67
+ };
68
+ }
69
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,IAAI;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,MAAM,WAAW,UAAU;IACzB,aAAa,EAAE,OAAO,CAAC;IACvB,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAKD,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,cAAc,CAAC,EAAE,kBAAkB,CAAC;QACpC,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,mBAAmB,CAAC,EAAE,MAAM,CAAC;KAC9B;CACF;AAMD,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE9C,MAAM,WAAW,mBAAmB;IAIlC,OAAO,EAAE,MAAM,CAAC;IAGhB,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IAIrB,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAE5B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAID,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,KAAK,CAAC;IACf,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;IACpB,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACpC,CAAC;CACH;AAED,MAAM,WAAW,eAAe,CAAC,CAAC,GAAG,OAAO;IAC1C,OAAO,EAAE,KAAK,CAAC;IACf,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE;QACP,OAAO,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QAC/C,OAAO,CAAC,EAAE,OAAO,CAAC;KACnB,CAAC;IACF,KAAK,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,CAAC,CAAA;KAAE,CAAC;CACrD"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,5 @@
1
+ import type { AptevaAppInjection } from "./types.js";
2
+ export declare function readAptevaInjection(): AptevaAppInjection | undefined;
3
+ export declare function pickKioskKey(fallback?: string): string | undefined;
4
+ export declare function pickBaseURL(explicit?: string): string;
5
+ //# sourceMappingURL=window.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"window.d.ts","sourceRoot":"","sources":["../src/window.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAQrD,wBAAgB,mBAAmB,IAAI,kBAAkB,GAAG,SAAS,CAGpE;AAQD,wBAAgB,YAAY,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAWlE;AAOD,wBAAgB,WAAW,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAUrD"}
package/dist/window.js ADDED
@@ -0,0 +1,60 @@
1
+ // Returns the apteva-server injection block if this UI is being served
2
+ // as a static app on the platform itself (apps_static.go writes a
3
+ // <script>window.__APTEVA_APP__ = …</script> into the served HTML).
4
+ // Returns undefined in any other environment (Vercel-hosted UI, Node,
5
+ // SSR pre-hydrate, jsdom without seeding). Safe to call during module
6
+ // init — guards against `window` being absent.
7
+ export function readAptevaInjection() {
8
+ if (typeof window === "undefined")
9
+ return undefined;
10
+ return window.__APTEVA_APP__;
11
+ }
12
+ // Picks the API key to authenticate with, in precedence order:
13
+ // 1. ?api_key=… in the URL — shareable kiosk links override everything
14
+ // 2. install-config kiosk_api_key from window.__APTEVA_APP__
15
+ // 3. explicit fallback passed by the caller (e.g. process.env.X)
16
+ // Returns undefined when none are set; the caller then falls back to
17
+ // cookie auth.
18
+ export function pickKioskKey(fallback) {
19
+ if (typeof window !== "undefined") {
20
+ try {
21
+ const url = new URL(window.location.href);
22
+ const k = url.searchParams.get("api_key");
23
+ if (k)
24
+ return k;
25
+ }
26
+ catch { }
27
+ const inj = window.__APTEVA_APP__;
28
+ if (inj?.kiosk_api_key)
29
+ return inj.kiosk_api_key;
30
+ }
31
+ return fallback;
32
+ }
33
+ // Resolves the base URL the client should hit. Precedence:
34
+ // 1. explicit arg — caller wins
35
+ // 2. window.__API_BASE__ — legacy injection still respected
36
+ // 3. window.__APTEVA_APP__.api_base
37
+ // 4. same-origin "" — fetch() falls back to the current document origin
38
+ export function pickBaseURL(explicit) {
39
+ if (explicit)
40
+ return explicit;
41
+ if (typeof window !== "undefined") {
42
+ if (typeof window.__API_BASE__ === "string" && window.__API_BASE__) {
43
+ return originFromApiBase(window.__API_BASE__);
44
+ }
45
+ const inj = window.__APTEVA_APP__;
46
+ if (inj?.api_base)
47
+ return originFromApiBase(inj.api_base);
48
+ }
49
+ return "";
50
+ }
51
+ // __API_BASE__ is historically "/api"; the SDK adds /api itself, so we
52
+ // strip a trailing /api so concatenation doesn't double-suffix.
53
+ function originFromApiBase(s) {
54
+ if (s === "/api")
55
+ return "";
56
+ if (s.endsWith("/api"))
57
+ return s.slice(0, -4);
58
+ return s;
59
+ }
60
+ //# sourceMappingURL=window.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"window.js","sourceRoot":"","sources":["../src/window.ts"],"names":[],"mappings":"AAEA,uEAAuE;AACvE,kEAAkE;AAClE,oEAAoE;AACpE,sEAAsE;AACtE,sEAAsE;AACtE,+CAA+C;AAC/C,MAAM,UAAU,mBAAmB;IACjC,IAAI,OAAO,MAAM,KAAK,WAAW;QAAE,OAAO,SAAS,CAAC;IACpD,OAAO,MAAM,CAAC,cAAc,CAAC;AAC/B,CAAC;AAED,+DAA+D;AAC/D,yEAAyE;AACzE,+DAA+D;AAC/D,mEAAmE;AACnE,qEAAqE;AACrE,eAAe;AACf,MAAM,UAAU,YAAY,CAAC,QAAiB;IAC5C,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;QAClC,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC1C,MAAM,CAAC,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YAC1C,IAAI,CAAC;gBAAE,OAAO,CAAC,CAAC;QAClB,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;QACV,MAAM,GAAG,GAAG,MAAM,CAAC,cAAc,CAAC;QAClC,IAAI,GAAG,EAAE,aAAa;YAAE,OAAO,GAAG,CAAC,aAAa,CAAC;IACnD,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,2DAA2D;AAC3D,kCAAkC;AAClC,8DAA8D;AAC9D,sCAAsC;AACtC,0EAA0E;AAC1E,MAAM,UAAU,WAAW,CAAC,QAAiB;IAC3C,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC9B,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;QAClC,IAAI,OAAO,MAAM,CAAC,YAAY,KAAK,QAAQ,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;YACnE,OAAO,iBAAiB,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QAChD,CAAC;QACD,MAAM,GAAG,GAAG,MAAM,CAAC,cAAc,CAAC;QAClC,IAAI,GAAG,EAAE,QAAQ;YAAE,OAAO,iBAAiB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC5D,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,uEAAuE;AACvE,gEAAgE;AAChE,SAAS,iBAAiB,CAAC,CAAS;IAClC,IAAI,CAAC,KAAK,MAAM;QAAE,OAAO,EAAE,CAAC;IAC5B,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC9C,OAAO,CAAC,CAAC;AACX,CAAC"}
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "@apteva/web-sdk",
3
+ "version": "0.1.0",
4
+ "description": "Browser SDK for apteva-server. Handles auth (session cookie + API key + ?api_key=), wraps the /api/apps/<name>/* HTTP and MCP proxy, normalizes the MCP JSON-RPC envelope, and surfaces window.__APTEVA_APP__ when the UI is hosted on apteva-server itself. Framework-agnostic.",
5
+ "license": "MIT",
6
+ "author": "Apteva",
7
+ "homepage": "https://github.com/apteva/web-sdk",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/apteva/web-sdk"
11
+ },
12
+ "bugs": {
13
+ "url": "https://github.com/apteva/web-sdk/issues"
14
+ },
15
+ "keywords": [
16
+ "apteva",
17
+ "sdk",
18
+ "mcp",
19
+ "agents",
20
+ "auth",
21
+ "browser"
22
+ ],
23
+ "engines": {
24
+ "node": ">=18"
25
+ },
26
+ "type": "module",
27
+ "main": "./dist/index.js",
28
+ "types": "./dist/index.d.ts",
29
+ "sideEffects": false,
30
+ "exports": {
31
+ ".": {
32
+ "types": "./dist/index.d.ts",
33
+ "import": "./dist/index.js",
34
+ "default": "./dist/index.js"
35
+ },
36
+ "./package.json": "./package.json"
37
+ },
38
+ "files": [
39
+ "dist",
40
+ "README.md",
41
+ "LICENSE",
42
+ "CHANGELOG.md"
43
+ ],
44
+ "publishConfig": {
45
+ "access": "public"
46
+ },
47
+ "scripts": {
48
+ "build": "tsc -p tsconfig.build.json",
49
+ "test": "bun test",
50
+ "typecheck": "tsc --noEmit",
51
+ "prepublishOnly": "bun run typecheck && bun test && bun run build"
52
+ },
53
+ "devDependencies": {
54
+ "@types/bun": "^1.1.0",
55
+ "typescript": "^5.4.0"
56
+ }
57
+ }