@brokr/sdk 1.0.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/dist/auth.js +175 -0
- package/dist/auth.mjs +151 -0
- package/dist/brokr_runtime.py +333 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +568 -0
- package/dist/index.mjs +558 -0
- package/dist/management.js +92 -0
- package/dist/management.mjs +66 -0
- package/dist/react.js +264 -0
- package/dist/react.mjs +225 -0
- package/dist/runtime.js +512 -0
- package/dist/runtime.mjs +501 -0
- package/dist/src/auth.d.ts +70 -0
- package/dist/src/auth.d.ts.map +1 -0
- package/dist/src/management.d.ts +68 -0
- package/dist/src/management.d.ts.map +1 -0
- package/dist/src/react/auth.d.ts +50 -0
- package/dist/src/react/auth.d.ts.map +1 -0
- package/dist/src/runtime.d.ts +217 -0
- package/dist/src/runtime.d.ts.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/types.d.ts +135 -0
- package/dist/types.d.ts.map +1 -0
- package/package.json +79 -0
package/dist/runtime.js
ADDED
|
@@ -0,0 +1,512 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __esm = (fn, res) => function __init() {
|
|
7
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
8
|
+
};
|
|
9
|
+
var __export = (target, all) => {
|
|
10
|
+
for (var name in all)
|
|
11
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
12
|
+
};
|
|
13
|
+
var __copyProps = (to, from, except, desc) => {
|
|
14
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
15
|
+
for (let key of __getOwnPropNames(from))
|
|
16
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
17
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
18
|
+
}
|
|
19
|
+
return to;
|
|
20
|
+
};
|
|
21
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
22
|
+
|
|
23
|
+
// src/auth.ts
|
|
24
|
+
var auth_exports = {};
|
|
25
|
+
__export(auth_exports, {
|
|
26
|
+
BrokrAuthClient: () => BrokrAuthClient,
|
|
27
|
+
authMiddleware: () => authMiddleware
|
|
28
|
+
});
|
|
29
|
+
function parseCookies(cookieHeader) {
|
|
30
|
+
const cookies = /* @__PURE__ */ new Map();
|
|
31
|
+
for (const pair of cookieHeader.split(";")) {
|
|
32
|
+
const eqIdx = pair.indexOf("=");
|
|
33
|
+
if (eqIdx === -1) continue;
|
|
34
|
+
const name = pair.slice(0, eqIdx).trim();
|
|
35
|
+
const value = pair.slice(eqIdx + 1).trim();
|
|
36
|
+
if (name) cookies.set(name, value);
|
|
37
|
+
}
|
|
38
|
+
return cookies;
|
|
39
|
+
}
|
|
40
|
+
function authMiddleware(options) {
|
|
41
|
+
const { protectedRoutes = [], publicOnlyRoutes = [] } = options;
|
|
42
|
+
return async function middleware(request) {
|
|
43
|
+
const url = new URL(request.url);
|
|
44
|
+
const pathname = url.pathname;
|
|
45
|
+
const isProtected = protectedRoutes.some((route) => pathname.startsWith(route));
|
|
46
|
+
const isPublicOnly = publicOnlyRoutes.some((route) => pathname.startsWith(route));
|
|
47
|
+
if (!isProtected && !isPublicOnly) return void 0;
|
|
48
|
+
const cookieHeader = request.headers.get("cookie") ?? "";
|
|
49
|
+
const cookies = parseCookies(cookieHeader);
|
|
50
|
+
const hasSession = cookies.has("better-auth.session_token");
|
|
51
|
+
if (isProtected && !hasSession) {
|
|
52
|
+
return Response.redirect(new URL("/sign-in", request.url).toString(), 302);
|
|
53
|
+
}
|
|
54
|
+
if (isPublicOnly && hasSession) {
|
|
55
|
+
return Response.redirect(new URL("/", request.url).toString(), 302);
|
|
56
|
+
}
|
|
57
|
+
return void 0;
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
var BrokrAuthClient;
|
|
61
|
+
var init_auth = __esm({
|
|
62
|
+
"src/auth.ts"() {
|
|
63
|
+
"use strict";
|
|
64
|
+
init_runtime();
|
|
65
|
+
BrokrAuthClient = class {
|
|
66
|
+
constructor(token, gatewayUrl, appUrl) {
|
|
67
|
+
this._token = token;
|
|
68
|
+
this._gatewayUrl = gatewayUrl;
|
|
69
|
+
this._appUrl = appUrl ?? (typeof process !== "undefined" ? process.env.BETTER_AUTH_URL : void 0);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Get current user from an incoming request's cookies.
|
|
73
|
+
* Calls the local Better Auth API (runs inside your app).
|
|
74
|
+
*/
|
|
75
|
+
async currentUser(request) {
|
|
76
|
+
const session = await this.getSession(request);
|
|
77
|
+
return session?.user ?? null;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Get the full session (user + metadata) from an incoming request.
|
|
81
|
+
* Calls the local Better Auth API.
|
|
82
|
+
*/
|
|
83
|
+
async getSession(request) {
|
|
84
|
+
const appUrl = this._appUrl;
|
|
85
|
+
if (!appUrl) {
|
|
86
|
+
throw new BrokrError(
|
|
87
|
+
"[brokr] BETTER_AUTH_URL is not set. Auth may not be provisioned.",
|
|
88
|
+
"AUTH_NOT_CONFIGURED",
|
|
89
|
+
"auth"
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
const cookieHeader = request.headers.get("cookie") ?? "";
|
|
93
|
+
if (!cookieHeader) return null;
|
|
94
|
+
const res = await fetch(`${appUrl}/api/auth/get-session`, {
|
|
95
|
+
method: "GET",
|
|
96
|
+
headers: { cookie: cookieHeader }
|
|
97
|
+
});
|
|
98
|
+
if (!res.ok) return null;
|
|
99
|
+
const data = await res.json();
|
|
100
|
+
if (!data?.user || !data?.session) return null;
|
|
101
|
+
return {
|
|
102
|
+
user: {
|
|
103
|
+
id: data.user.id,
|
|
104
|
+
email: data.user.email,
|
|
105
|
+
name: data.user.name ?? null,
|
|
106
|
+
avatarUrl: data.user.image ?? null,
|
|
107
|
+
emailVerified: data.user.emailVerified ? /* @__PURE__ */ new Date() : null
|
|
108
|
+
},
|
|
109
|
+
sessionId: data.session.id,
|
|
110
|
+
expiresAt: new Date(data.session.expiresAt)
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Generate an OAuth authorization URL.
|
|
115
|
+
*/
|
|
116
|
+
async getOAuthUrl(provider, options) {
|
|
117
|
+
const appUrl = this._appUrl;
|
|
118
|
+
if (!appUrl) {
|
|
119
|
+
throw new BrokrError("[brokr] BETTER_AUTH_URL is not set.", "AUTH_NOT_CONFIGURED", "auth");
|
|
120
|
+
}
|
|
121
|
+
const redirectTo = options?.redirectTo ?? "/";
|
|
122
|
+
if (!redirectTo.startsWith("/") || redirectTo.startsWith("//")) {
|
|
123
|
+
throw new BrokrError("[brokr] redirectTo must be a relative path (start with /)", "INVALID_REDIRECT", "auth");
|
|
124
|
+
}
|
|
125
|
+
const params = new URLSearchParams({ callbackURL: redirectTo });
|
|
126
|
+
return { redirectUrl: `${appUrl}/api/auth/sign-in/social?provider=${provider}&${params}` };
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Send a magic link email (requires email capability).
|
|
130
|
+
*/
|
|
131
|
+
async sendMagicLink(email, options) {
|
|
132
|
+
const appUrl = this._appUrl;
|
|
133
|
+
if (!appUrl) {
|
|
134
|
+
throw new BrokrError("[brokr] BETTER_AUTH_URL is not set.", "AUTH_NOT_CONFIGURED", "auth");
|
|
135
|
+
}
|
|
136
|
+
const res = await fetch(`${appUrl}/api/auth/magic-link/send`, {
|
|
137
|
+
method: "POST",
|
|
138
|
+
headers: { "Content-Type": "application/json" },
|
|
139
|
+
body: JSON.stringify({ email, callbackURL: options?.redirectTo ?? "/" })
|
|
140
|
+
});
|
|
141
|
+
if (!res.ok) {
|
|
142
|
+
const data = await res.json().catch(() => ({}));
|
|
143
|
+
throw new BrokrError(
|
|
144
|
+
data.message ?? `[brokr] Failed to send magic link (HTTP ${res.status})`,
|
|
145
|
+
"AUTH_MAGIC_LINK_FAILED",
|
|
146
|
+
"auth"
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
// src/runtime.ts
|
|
155
|
+
var runtime_exports = {};
|
|
156
|
+
__export(runtime_exports, {
|
|
157
|
+
BrokrAIClient: () => BrokrAIClient,
|
|
158
|
+
BrokrAuthError: () => BrokrAuthError,
|
|
159
|
+
BrokrEmailClient: () => BrokrEmailClient,
|
|
160
|
+
BrokrError: () => BrokrError,
|
|
161
|
+
BrokrNetworkError: () => BrokrNetworkError,
|
|
162
|
+
BrokrRateLimitError: () => BrokrRateLimitError,
|
|
163
|
+
BrokrRuntime: () => BrokrRuntime,
|
|
164
|
+
BrokrStorageClient: () => BrokrStorageClient,
|
|
165
|
+
GATEWAY_URL: () => GATEWAY_URL,
|
|
166
|
+
createBrokr: () => createBrokr,
|
|
167
|
+
models: () => models
|
|
168
|
+
});
|
|
169
|
+
module.exports = __toCommonJS(runtime_exports);
|
|
170
|
+
function resolveToken() {
|
|
171
|
+
return typeof process !== "undefined" ? process.env.BROKR_TOKEN : void 0;
|
|
172
|
+
}
|
|
173
|
+
function assertToken(token, capability) {
|
|
174
|
+
if (!token) {
|
|
175
|
+
let hint = "brokr env pull --stack <name>";
|
|
176
|
+
try {
|
|
177
|
+
if (typeof process !== "undefined") {
|
|
178
|
+
const fs = require("fs");
|
|
179
|
+
const path = require("path");
|
|
180
|
+
const brokrFile = path.join(process.cwd(), ".brokr");
|
|
181
|
+
if (fs.existsSync(brokrFile)) {
|
|
182
|
+
const data = JSON.parse(fs.readFileSync(brokrFile, "utf8"));
|
|
183
|
+
if (data?.stackName) hint = `brokr env pull --stack ${data.stackName}`;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
} catch {
|
|
187
|
+
}
|
|
188
|
+
throw new BrokrAuthError(
|
|
189
|
+
`[brokr] BROKR_TOKEN is not set.
|
|
190
|
+
Run: ${hint}`,
|
|
191
|
+
"BROKR_TOKEN_MISSING"
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
async function gatewayFetch(gatewayUrl, token, path, body, capability) {
|
|
196
|
+
let res;
|
|
197
|
+
try {
|
|
198
|
+
res = await fetch(`${gatewayUrl}${path}`, {
|
|
199
|
+
method: "POST",
|
|
200
|
+
headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}` },
|
|
201
|
+
body: JSON.stringify(body)
|
|
202
|
+
});
|
|
203
|
+
} catch (err) {
|
|
204
|
+
throw new BrokrNetworkError(
|
|
205
|
+
`[brokr] Could not reach Brokr gateway. Check your network.
|
|
206
|
+
${err instanceof Error ? err.message : String(err)}`,
|
|
207
|
+
capability
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
if (res.status === 429) {
|
|
211
|
+
const retryAfter = parseInt(res.headers.get("Retry-After") ?? "60", 10);
|
|
212
|
+
const data = await res.json().catch(() => ({}));
|
|
213
|
+
throw new BrokrRateLimitError(
|
|
214
|
+
data.error ?? `[brokr] Rate limited (retry after ${retryAfter}s)`,
|
|
215
|
+
retryAfter,
|
|
216
|
+
capability
|
|
217
|
+
);
|
|
218
|
+
}
|
|
219
|
+
if (res.status === 401) {
|
|
220
|
+
throw new BrokrAuthError("[brokr] Invalid or expired BROKR_TOKEN.", "BROKR_TOKEN_INVALID");
|
|
221
|
+
}
|
|
222
|
+
if (!res.ok) {
|
|
223
|
+
const data = await res.json().catch(() => ({}));
|
|
224
|
+
throw new BrokrError(
|
|
225
|
+
data.error ?? `[brokr] ${capability} request failed (HTTP ${res.status})`,
|
|
226
|
+
data.code ?? `${capability.toUpperCase()}_FAILED`,
|
|
227
|
+
capability
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
return res.json();
|
|
231
|
+
}
|
|
232
|
+
function createBrokr(options) {
|
|
233
|
+
return new BrokrRuntime(options);
|
|
234
|
+
}
|
|
235
|
+
var GATEWAY_URL, BrokrError, BrokrAuthError, BrokrRateLimitError, BrokrNetworkError, models, BrokrAIClient, BrokrStorageClient, BrokrEmailClient, BrokrRuntime;
|
|
236
|
+
var init_runtime = __esm({
|
|
237
|
+
"src/runtime.ts"() {
|
|
238
|
+
GATEWAY_URL = "https://api.brokr.sh";
|
|
239
|
+
BrokrError = class extends Error {
|
|
240
|
+
constructor(message, code, capability, retryable = false) {
|
|
241
|
+
super(message);
|
|
242
|
+
this.code = code;
|
|
243
|
+
this.capability = capability;
|
|
244
|
+
this.retryable = retryable;
|
|
245
|
+
this.name = "BrokrError";
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
BrokrAuthError = class extends BrokrError {
|
|
249
|
+
constructor(message, code) {
|
|
250
|
+
super(message, code, "auth", false);
|
|
251
|
+
this.name = "BrokrAuthError";
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
BrokrRateLimitError = class extends BrokrError {
|
|
255
|
+
constructor(message, retryAfter, capability) {
|
|
256
|
+
super(message, "RATE_LIMITED", capability, true);
|
|
257
|
+
this.retryAfter = retryAfter;
|
|
258
|
+
this.name = "BrokrRateLimitError";
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
BrokrNetworkError = class extends BrokrError {
|
|
262
|
+
constructor(message, capability) {
|
|
263
|
+
super(message, "NETWORK_ERROR", capability, true);
|
|
264
|
+
this.name = "BrokrNetworkError";
|
|
265
|
+
}
|
|
266
|
+
};
|
|
267
|
+
models = {
|
|
268
|
+
/** Cheapest and fastest model (Deepseek Chat). */
|
|
269
|
+
FAST: "deepseek-chat",
|
|
270
|
+
/** Most capable model. */
|
|
271
|
+
SMART: "claude-sonnet-4-20250514",
|
|
272
|
+
/** Default balanced model (Deepseek Chat). */
|
|
273
|
+
BALANCED: "deepseek-chat"
|
|
274
|
+
};
|
|
275
|
+
BrokrAIClient = class {
|
|
276
|
+
constructor(_token, _gatewayUrl) {
|
|
277
|
+
this._token = _token;
|
|
278
|
+
this._gatewayUrl = _gatewayUrl;
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Send a chat completion request.
|
|
282
|
+
*
|
|
283
|
+
* @example
|
|
284
|
+
* ```typescript
|
|
285
|
+
* const reply = await brokr.ai.chat([
|
|
286
|
+
* { role: 'user', content: 'Explain quantum computing in one sentence.' }
|
|
287
|
+
* ]);
|
|
288
|
+
* console.log(reply.content);
|
|
289
|
+
* ```
|
|
290
|
+
*/
|
|
291
|
+
async chat(messages, options) {
|
|
292
|
+
assertToken(this._token, "ai");
|
|
293
|
+
const data = await gatewayFetch(this._gatewayUrl, this._token, "/v1/chat/completions", {
|
|
294
|
+
messages,
|
|
295
|
+
model: options?.model,
|
|
296
|
+
max_tokens: options?.maxTokens,
|
|
297
|
+
temperature: options?.temperature
|
|
298
|
+
}, "ai");
|
|
299
|
+
return {
|
|
300
|
+
content: data.choices?.[0]?.message?.content ?? "",
|
|
301
|
+
model: data.model ?? "",
|
|
302
|
+
usage: {
|
|
303
|
+
promptTokens: data.usage?.prompt_tokens ?? 0,
|
|
304
|
+
completionTokens: data.usage?.completion_tokens ?? 0
|
|
305
|
+
}
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Stream a chat completion. Yields text strings directly.
|
|
310
|
+
*
|
|
311
|
+
* @example
|
|
312
|
+
* ```typescript
|
|
313
|
+
* for await (const text of brokr.ai.stream(messages)) {
|
|
314
|
+
* process.stdout.write(text);
|
|
315
|
+
* }
|
|
316
|
+
* ```
|
|
317
|
+
*/
|
|
318
|
+
async *stream(messages, options) {
|
|
319
|
+
assertToken(this._token, "ai");
|
|
320
|
+
let res;
|
|
321
|
+
try {
|
|
322
|
+
res = await fetch(`${this._gatewayUrl}/v1/chat/completions`, {
|
|
323
|
+
method: "POST",
|
|
324
|
+
headers: { "Content-Type": "application/json", Authorization: `Bearer ${this._token}` },
|
|
325
|
+
body: JSON.stringify({ messages, stream: true, model: options?.model, max_tokens: options?.maxTokens })
|
|
326
|
+
});
|
|
327
|
+
} catch (err) {
|
|
328
|
+
throw new BrokrNetworkError(
|
|
329
|
+
`[brokr] Could not reach Brokr gateway.
|
|
330
|
+
${err instanceof Error ? err.message : String(err)}`,
|
|
331
|
+
"ai"
|
|
332
|
+
);
|
|
333
|
+
}
|
|
334
|
+
if (res.status === 429) {
|
|
335
|
+
const retryAfter = parseInt(res.headers.get("Retry-After") ?? "60", 10);
|
|
336
|
+
throw new BrokrRateLimitError("[brokr] AI rate limited.", retryAfter, "ai");
|
|
337
|
+
}
|
|
338
|
+
if (res.status === 401) {
|
|
339
|
+
throw new BrokrAuthError("[brokr] Invalid or expired BROKR_TOKEN.", "BROKR_TOKEN_INVALID");
|
|
340
|
+
}
|
|
341
|
+
if (!res.ok || !res.body) {
|
|
342
|
+
throw new BrokrError(`[brokr] AI stream failed (HTTP ${res.status})`, "AI_STREAM_FAILED", "ai");
|
|
343
|
+
}
|
|
344
|
+
const reader = res.body.getReader();
|
|
345
|
+
const decoder = new TextDecoder();
|
|
346
|
+
let buffer = "";
|
|
347
|
+
while (true) {
|
|
348
|
+
const { done, value } = await reader.read();
|
|
349
|
+
if (done) break;
|
|
350
|
+
buffer += decoder.decode(value, { stream: true });
|
|
351
|
+
const lines = buffer.split("\n");
|
|
352
|
+
buffer = lines.pop() ?? "";
|
|
353
|
+
for (const line of lines) {
|
|
354
|
+
if (!line.startsWith("data: ")) continue;
|
|
355
|
+
const payload = line.slice(6).trim();
|
|
356
|
+
if (payload === "[DONE]") return;
|
|
357
|
+
try {
|
|
358
|
+
const parsed = JSON.parse(payload);
|
|
359
|
+
const delta = parsed.choices?.[0]?.delta?.content ?? "";
|
|
360
|
+
if (delta) yield delta;
|
|
361
|
+
} catch {
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* OpenAI-SDK compatible base URL.
|
|
368
|
+
*
|
|
369
|
+
* @example
|
|
370
|
+
* ```typescript
|
|
371
|
+
* const openai = new OpenAI({ baseURL: brokr.ai.baseURL, apiKey: brokr.ai.apiKey });
|
|
372
|
+
* ```
|
|
373
|
+
*/
|
|
374
|
+
get baseURL() {
|
|
375
|
+
return `${this._gatewayUrl}/v1`;
|
|
376
|
+
}
|
|
377
|
+
/** Use as `apiKey` with the official OpenAI SDK to route through Brokr's gateway. */
|
|
378
|
+
get apiKey() {
|
|
379
|
+
assertToken(this._token, "ai");
|
|
380
|
+
return this._token;
|
|
381
|
+
}
|
|
382
|
+
};
|
|
383
|
+
BrokrStorageClient = class {
|
|
384
|
+
constructor(_token, _gatewayUrl) {
|
|
385
|
+
this._token = _token;
|
|
386
|
+
this._gatewayUrl = _gatewayUrl;
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* Get a presigned upload URL for browser-direct or streaming uploads.
|
|
390
|
+
*
|
|
391
|
+
* @example
|
|
392
|
+
* ```typescript
|
|
393
|
+
* const { url, key } = await brokr.storage.getUploadUrl('avatar.png', 'image/png');
|
|
394
|
+
* await fetch(url, { method: 'PUT', body: file });
|
|
395
|
+
* ```
|
|
396
|
+
*/
|
|
397
|
+
async getUploadUrl(filename, contentType = "application/octet-stream") {
|
|
398
|
+
assertToken(this._token, "storage");
|
|
399
|
+
return gatewayFetch(
|
|
400
|
+
this._gatewayUrl,
|
|
401
|
+
this._token,
|
|
402
|
+
"/v1/storage/sign-upload",
|
|
403
|
+
{ filename, contentType },
|
|
404
|
+
"storage"
|
|
405
|
+
);
|
|
406
|
+
}
|
|
407
|
+
/**
|
|
408
|
+
* Upload data to R2. Returns the stable object key.
|
|
409
|
+
*
|
|
410
|
+
* @example
|
|
411
|
+
* ```typescript
|
|
412
|
+
* const { key } = await brokr.storage.upload(fileBuffer, 'photo.jpg', 'image/jpeg');
|
|
413
|
+
* ```
|
|
414
|
+
*/
|
|
415
|
+
async upload(data, filename, contentType = "application/octet-stream") {
|
|
416
|
+
const { url, key } = await this.getUploadUrl(filename, contentType);
|
|
417
|
+
const putRes = await fetch(url, {
|
|
418
|
+
method: "PUT",
|
|
419
|
+
headers: { "Content-Type": contentType },
|
|
420
|
+
body: data
|
|
421
|
+
});
|
|
422
|
+
if (!putRes.ok) {
|
|
423
|
+
throw new BrokrError(`[brokr] Upload failed (HTTP ${putRes.status})`, "STORAGE_UPLOAD_FAILED", "storage");
|
|
424
|
+
}
|
|
425
|
+
return { key };
|
|
426
|
+
}
|
|
427
|
+
/**
|
|
428
|
+
* Get a presigned download URL for a stored object.
|
|
429
|
+
*
|
|
430
|
+
* @example
|
|
431
|
+
* ```typescript
|
|
432
|
+
* const { url } = await brokr.storage.url('photos/avatar.jpg');
|
|
433
|
+
* // use url in <img src={url} /> or redirect
|
|
434
|
+
* ```
|
|
435
|
+
*/
|
|
436
|
+
async url(key, options) {
|
|
437
|
+
assertToken(this._token, "storage");
|
|
438
|
+
return gatewayFetch(
|
|
439
|
+
this._gatewayUrl,
|
|
440
|
+
this._token,
|
|
441
|
+
"/v1/storage/sign-download",
|
|
442
|
+
{ key, expiresIn: options?.expiresIn },
|
|
443
|
+
"storage"
|
|
444
|
+
);
|
|
445
|
+
}
|
|
446
|
+
/** @deprecated Use `url()` instead. */
|
|
447
|
+
async getUrl(key, options) {
|
|
448
|
+
return this.url(key, options);
|
|
449
|
+
}
|
|
450
|
+
};
|
|
451
|
+
BrokrEmailClient = class {
|
|
452
|
+
constructor(_token, _gatewayUrl) {
|
|
453
|
+
this._token = _token;
|
|
454
|
+
this._gatewayUrl = _gatewayUrl;
|
|
455
|
+
}
|
|
456
|
+
/**
|
|
457
|
+
* Send an email. The from address and API credentials are resolved server-side.
|
|
458
|
+
*
|
|
459
|
+
* @example
|
|
460
|
+
* ```typescript
|
|
461
|
+
* await brokr.email.send({
|
|
462
|
+
* to: 'user@example.com',
|
|
463
|
+
* subject: 'Welcome!',
|
|
464
|
+
* html: '<h1>Welcome to the app</h1>',
|
|
465
|
+
* });
|
|
466
|
+
* ```
|
|
467
|
+
*/
|
|
468
|
+
async send(params) {
|
|
469
|
+
assertToken(this._token, "email");
|
|
470
|
+
return gatewayFetch(
|
|
471
|
+
this._gatewayUrl,
|
|
472
|
+
this._token,
|
|
473
|
+
"/v1/email/send",
|
|
474
|
+
params,
|
|
475
|
+
"email"
|
|
476
|
+
);
|
|
477
|
+
}
|
|
478
|
+
};
|
|
479
|
+
BrokrRuntime = class {
|
|
480
|
+
constructor(options) {
|
|
481
|
+
this._token = options?.token ?? resolveToken();
|
|
482
|
+
this._gatewayUrl = options?.gatewayUrl ?? GATEWAY_URL;
|
|
483
|
+
this.ai = new BrokrAIClient(this._token, this._gatewayUrl);
|
|
484
|
+
this.storage = new BrokrStorageClient(this._token, this._gatewayUrl);
|
|
485
|
+
this.email = new BrokrEmailClient(this._token, this._gatewayUrl);
|
|
486
|
+
}
|
|
487
|
+
/** Auth client — lazily initialized to avoid pulling in auth deps when not needed. */
|
|
488
|
+
get auth() {
|
|
489
|
+
if (!this._auth) {
|
|
490
|
+
const { BrokrAuthClient: BrokrAuthClient2 } = (init_auth(), __toCommonJS(auth_exports));
|
|
491
|
+
this._auth = new BrokrAuthClient2(this._token, this._gatewayUrl);
|
|
492
|
+
}
|
|
493
|
+
return this._auth;
|
|
494
|
+
}
|
|
495
|
+
};
|
|
496
|
+
}
|
|
497
|
+
});
|
|
498
|
+
init_runtime();
|
|
499
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
500
|
+
0 && (module.exports = {
|
|
501
|
+
BrokrAIClient,
|
|
502
|
+
BrokrAuthError,
|
|
503
|
+
BrokrEmailClient,
|
|
504
|
+
BrokrError,
|
|
505
|
+
BrokrNetworkError,
|
|
506
|
+
BrokrRateLimitError,
|
|
507
|
+
BrokrRuntime,
|
|
508
|
+
BrokrStorageClient,
|
|
509
|
+
GATEWAY_URL,
|
|
510
|
+
createBrokr,
|
|
511
|
+
models
|
|
512
|
+
});
|