@bagelink/sdk 0.0.1286 → 0.0.1288

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/index.mjs CHANGED
@@ -1,46 +1,655 @@
1
- import 'axios';
2
- export { B as Bagel, f as formatAPIErrorMessage, i as openAPI } from './shared/sdk.BJ23wlaP.mjs';
3
- import 'node:fs';
4
- import 'node:path';
5
- import 'node:process';
6
- import 'node:fs/promises';
7
- import 'util';
8
- import 'path';
9
- import 'tty';
10
- import 'os';
11
- import 'fs';
12
- import 'module';
13
- import 'assert';
14
- import 'url';
15
- import 'node:url';
16
- import 'crypto';
17
- import 'events';
18
- import 'node:util';
19
- import 'node:assert';
20
- import 'process';
21
- import 'fs/promises';
22
- import 'v8';
23
- import 'node:perf_hooks';
24
- import 'node:module';
25
- import 'node:crypto';
26
- import 'child_process';
27
- import 'node:child_process';
28
- import 'node:http';
29
- import 'node:https';
30
- import 'net';
31
- import 'http';
32
- import 'stream';
33
- import 'node:os';
34
- import 'node:net';
35
- import 'node:dns';
36
- import 'node:readline';
37
- import 'node:buffer';
38
- import 'node:events';
39
- import 'node:v8';
40
- import 'node:worker_threads';
41
- import 'zlib';
42
- import 'buffer';
43
- import 'https';
44
- import 'tls';
45
- import 'node:querystring';
46
- import 'node:zlib';
1
+ import axios$1 from 'axios';
2
+
3
+ function toCamelCase(str) {
4
+ return str?.replaceAll(/[-._\s]+(.)?/g, (_, c) => c?.toUpperCase() || "").replace(/^./, (str2) => str2.toLowerCase()) || str || "";
5
+ }
6
+ function toPascalCase(str) {
7
+ return str?.replaceAll(/[-_\s]+(.)?/g, (_, c) => c?.toUpperCase() || "").replace(/^./, (str2) => str2.toUpperCase()) || str || "";
8
+ }
9
+ function formatType(typeName) {
10
+ typeName = typeName.replaceAll("-", "").replaceAll(/post|put$/gi, "").replaceAll(/^body_/gi, "");
11
+ return toPascalCase(typeName);
12
+ }
13
+ function resolveReference(ref) {
14
+ const t = ref.split("/").pop();
15
+ if (!t) return "any";
16
+ return formatType(t);
17
+ }
18
+ function schemaToType(schema) {
19
+ if (!schema) return "any";
20
+ if (schema.anyOf) {
21
+ let _t = schema.anyOf.map((s) => schemaToType(s)).filter((p) => p !== "any").join(" | ");
22
+ if (_t === "" || _t === "null") _t = "any";
23
+ return _t;
24
+ }
25
+ if (schema.allOf) {
26
+ return schema.allOf.map((s) => schemaToType(s)).filter((p) => p !== "any").join(" & ");
27
+ }
28
+ if (schema.$ref) return resolveReference(schema.$ref);
29
+ switch (schema.type) {
30
+ case "object":
31
+ return "{ [key: string]: any }";
32
+ case "string":
33
+ return "string";
34
+ case "integer":
35
+ return "number";
36
+ case "number":
37
+ return "number";
38
+ case "boolean":
39
+ return "boolean";
40
+ case "array":
41
+ return `${schemaToType(schema.items)}[]`;
42
+ case "undefined":
43
+ return "undefined";
44
+ case "null":
45
+ return "null";
46
+ case void 0:
47
+ return "any";
48
+ default:
49
+ console.log("Unknown type", schema.type);
50
+ return "any";
51
+ }
52
+ }
53
+ function isOptional(schema) {
54
+ const type = schemaToType(schema);
55
+ const splitType = type.split(/\s+\|\s+/);
56
+ const includesNull = splitType.includes("null");
57
+ const includesUndefined = splitType.includes("undefined");
58
+ return includesNull || includesUndefined || schema.default !== void 0;
59
+ }
60
+ function cleanOptionals(str) {
61
+ return str.split(" | ").filter((t) => t !== "null" && t !== "undefined").join(" | ");
62
+ }
63
+ function formatVarType({
64
+ varName,
65
+ schema,
66
+ required = false,
67
+ defaultValue
68
+ }) {
69
+ let type = schemaToType(schema);
70
+ type = cleanOptionals(type);
71
+ let defaultStr = "";
72
+ if (defaultValue) {
73
+ if (typeof defaultValue === "string") {
74
+ defaultStr = ` = '${defaultValue}'`;
75
+ } else if (typeof defaultValue === "object") {
76
+ defaultStr = ` = ${JSON.stringify(defaultValue)}`;
77
+ } else {
78
+ defaultStr = ` = ${defaultValue}`;
79
+ }
80
+ }
81
+ let optionalStr = !required && isOptional(schema) ? "?" : "";
82
+ if (defaultStr) optionalStr = "";
83
+ return `${varName}${optionalStr}: ${type}${defaultStr}`;
84
+ }
85
+ function cleanPath(path) {
86
+ return path.split("/").filter((p) => p && !/\{|\}/.test(p)).join("/");
87
+ }
88
+
89
+ const allTypes = [];
90
+ const primitiveTypes = [
91
+ "string",
92
+ "number",
93
+ "boolean",
94
+ "null",
95
+ "void",
96
+ "any",
97
+ "Record<string, any>",
98
+ "undefined",
99
+ "{ [key: string]: any }"
100
+ ];
101
+ function collectTypeForImportStatement(typeName) {
102
+ typeName = typeName.trim().replace("[]", "");
103
+ if (typeName.includes("|")) {
104
+ typeName.split("|").forEach((singleType) => {
105
+ collectTypeForImportStatement(singleType);
106
+ });
107
+ return;
108
+ }
109
+ const isPrimitive = primitiveTypes.includes(typeName);
110
+ typeName = formatType(typeName);
111
+ if (!typeName || isPrimitive) return;
112
+ if (!allTypes.includes(typeName)) allTypes.push(typeName);
113
+ }
114
+ function schemaToTypeWithCollection(schema) {
115
+ const type = schemaToType(schema);
116
+ collectTypeForImportStatement(type);
117
+ return type;
118
+ }
119
+ function getResponseType(response) {
120
+ const mediaTypeObject = response.content?.["application/json"];
121
+ if (!mediaTypeObject || !mediaTypeObject.schema) return;
122
+ const responseType = schemaToTypeWithCollection(mediaTypeObject.schema);
123
+ return responseType;
124
+ }
125
+ function generateResponseType(responses) {
126
+ if (!responses) return "";
127
+ const types = [];
128
+ for (const [statusCode, response] of Object.entries(responses)) {
129
+ if (statusCode.startsWith("2")) {
130
+ const responseType = getResponseType(response);
131
+ if (responseType && responseType !== "any") {
132
+ types.push(responseType);
133
+ }
134
+ }
135
+ }
136
+ return types.join(" | ");
137
+ }
138
+ function generateAxiosFunction(method, formattedPath, allParams, responseTypeStr, parameters, requestBodyPayload) {
139
+ if (allParams === "undefined") allParams = "";
140
+ let axiosFunction = `async (${allParams})${responseTypeStr} => {`;
141
+ if (requestBodyPayload === "formData") {
142
+ const paramStr = parameters?.config?.params ? `params: {${parameters.config.params}}` : "";
143
+ axiosFunction += `
144
+ const formData = new FormData()
145
+ formData.append('upload', file)
146
+ return axios.${method}(${formattedPath}, formData, {
147
+ headers: { 'Content-Type': 'multipart/form-data' },
148
+ onUploadProgress: options?.onUploadProgress${paramStr ? `,
149
+ ${paramStr}` : ""}
150
+ })`;
151
+ } else {
152
+ const paramStr = parameters?.config?.params ? `, { params: {${parameters.config.params}} }` : "";
153
+ const bodyVar = requestBodyPayload ? `${requestBodyPayload}` : "{}";
154
+ axiosFunction += `return axios.${method}(${formattedPath}${["get", "delete"].includes(method) ? paramStr : `, ${bodyVar}${paramStr}`})`;
155
+ }
156
+ axiosFunction += "}";
157
+ return axiosFunction;
158
+ }
159
+ const pathParamRegex = /\{([^}]+)\}/g;
160
+ function getParamsFromPath(path) {
161
+ const params = path.match(pathParamRegex)?.map((p) => p.slice(1, -1));
162
+ return params;
163
+ }
164
+ function formatPathWithParams(path) {
165
+ const params = getParamsFromPath(path);
166
+ const formattedPath = params ? `\`${path.replace(pathParamRegex, (v) => `$${toCamelCase(v)}`)}\`` : `'${path}'`;
167
+ return formattedPath;
168
+ }
169
+ function generateRequestBody(requestBody) {
170
+ if (!requestBody?.content)
171
+ return { requestBodyParam: "", requestBodyPayload: "" };
172
+ const { content } = requestBody;
173
+ const multipartFormData = content["multipart/form-data"] || {};
174
+ if (multipartFormData.schema?.$ref?.includes("Body_upload_files")) {
175
+ return {
176
+ requestBodyParam: "file: File, options?: UploadOptions & { dirPath?: string, tags?: string[] }",
177
+ requestBodyPayload: "formData"
178
+ };
179
+ }
180
+ const jsonContent = requestBody.content["application/json"];
181
+ if (!jsonContent || !jsonContent.schema) {
182
+ return { requestBodyParam: "", requestBodyPayload: "" };
183
+ }
184
+ const bodySchema = jsonContent.schema;
185
+ const requestBodyType = schemaToType(bodySchema);
186
+ collectTypeForImportStatement(requestBodyType);
187
+ const requestBodyPayload = toCamelCase(bodySchema.title) || toCamelCase(requestBodyType) || "requestBody";
188
+ const requestBodyParam = formatVarType({
189
+ varName: requestBodyPayload,
190
+ schema: bodySchema,
191
+ defaultValue: bodySchema.default
192
+ });
193
+ return { requestBodyParam, requestBodyPayload };
194
+ }
195
+ function combineAllParams(parameters, requestBodyParam) {
196
+ let allParamsArray = [];
197
+ if (parameters && parameters.params)
198
+ allParamsArray = parameters.params.split(",").map((p) => p.trim());
199
+ if (requestBodyParam) allParamsArray.push(requestBodyParam.trim());
200
+ allParamsArray = allParamsArray.filter((p) => p).sort((a, b) => (a.includes("?") ? 1 : -1) - (b.includes("?") ? 1 : -1));
201
+ return allParamsArray.join(", ");
202
+ }
203
+ function generateFunctionParameters(params, isFileUpload = false) {
204
+ if (!params?.length) return {};
205
+ if (isFileUpload) {
206
+ return {
207
+ config: {
208
+ params: "dir_path: options?.dirPath, tags: options?.tags"
209
+ },
210
+ params: ""
211
+ // Empty string to ensure file is the first parameter
212
+ };
213
+ }
214
+ const functionParams = [];
215
+ const paramList = [];
216
+ for (const param of params) {
217
+ const paramType = schemaToType(param.schema);
218
+ collectTypeForImportStatement(paramType);
219
+ const paramName = param.name;
220
+ const varName = toCamelCase(param.name);
221
+ if (param.in === "path" || param.in === "query" || param.in === "header") {
222
+ functionParams.push(
223
+ formatVarType({
224
+ varName,
225
+ schema: param.schema,
226
+ required: param.required,
227
+ defaultValue: param.schema.default
228
+ })
229
+ );
230
+ }
231
+ if (param.in === "query" || param.in === "header") {
232
+ paramList.push(
233
+ paramName === varName ? paramName : `'${paramName}': ${varName}`
234
+ );
235
+ }
236
+ }
237
+ return {
238
+ params: functionParams.join(", "),
239
+ config: paramList.length ? { params: paramList.join(", ") } : {}
240
+ };
241
+ }
242
+ function generateFunctionForOperation(method, path, operation) {
243
+ if (!operation) return "";
244
+ const isFileUpload = operation.requestBody?.content["multipart/form-data"]?.schema?.$ref?.includes("Body_upload_files");
245
+ const parameters = generateFunctionParameters(
246
+ operation.parameters,
247
+ isFileUpload
248
+ );
249
+ const { requestBodyParam, requestBodyPayload } = generateRequestBody(
250
+ operation.requestBody
251
+ );
252
+ const allParams = isFileUpload ? "file: File, options?: UploadOptions & { dirPath?: string, tags?: string[] }" : combineAllParams(parameters, requestBodyParam);
253
+ const responseType = generateResponseType(operation.responses);
254
+ const responseTypeStr = responseType ? `: Promise<AxiosResponse<${responseType}>>` : "";
255
+ return generateAxiosFunction(
256
+ method,
257
+ formatPathWithParams(path),
258
+ allParams,
259
+ responseTypeStr,
260
+ parameters,
261
+ requestBodyPayload
262
+ );
263
+ }
264
+ const generateRandomString = () => Math.random().toString(36).slice(7);
265
+ const DOUBLE_QUOTE_REGEX = /"([^"]+)":/g;
266
+ function fileTemplate(tsString, typeForImport, baseURL) {
267
+ const templateCode = `import ax from 'axios';
268
+ import type { AxiosResponse } from 'axios';
269
+ import type {${typeForImport.join(", ")}} from './types.d';
270
+
271
+ interface UploadOptions {
272
+ onUploadProgress?: (progressEvent: any) => void
273
+ dirPath?: string
274
+ tags?: string[]
275
+ }
276
+
277
+ export const axios = ax.create({baseURL:${baseURL}});
278
+ ${tsString}`;
279
+ return templateCode.replace(DOUBLE_QUOTE_REGEX, "$1:");
280
+ }
281
+ const functionsInventory = {};
282
+ const pathOperations = [];
283
+ function hasConflict(path, method) {
284
+ const cleanPathName = path.split("/").filter((p) => p && !/\{|\}/.test(p)).join("/");
285
+ const matchingPaths = pathOperations.filter(
286
+ (p) => p.path === cleanPathName && p.method === method
287
+ );
288
+ pathOperations.push({ path: cleanPathName, method });
289
+ return matchingPaths.length > 0;
290
+ }
291
+ function createFunctionPlaceholder(path, method, operation) {
292
+ const funcID = generateRandomString();
293
+ functionsInventory[funcID] = generateFunctionForOperation(
294
+ method,
295
+ path,
296
+ operation
297
+ );
298
+ return funcID;
299
+ }
300
+ function handlePathSegment(path, operation, existingObj = {}) {
301
+ const methods = Object.keys(operation);
302
+ const obj = {};
303
+ for (const method of methods) {
304
+ let functionName = method.toLowerCase();
305
+ if (hasConflict(path, method)) {
306
+ const params = getParamsFromPath(path);
307
+ functionName += params ? `By${toPascalCase(params.pop() || "")}` : "All";
308
+ }
309
+ obj[functionName] = createFunctionPlaceholder(
310
+ path,
311
+ method,
312
+ operation[method]
313
+ );
314
+ }
315
+ return { ...obj, ...existingObj };
316
+ }
317
+ function generateFunctions(paths, baseUrl) {
318
+ let tsString = "";
319
+ const body = {};
320
+ const allPathsClean = Object.keys(paths).map(cleanPath);
321
+ for (const [path, operation] of Object.entries(paths)) {
322
+ const splitPath = path.split("/").filter((p) => p && !/\{|\}/.test(p));
323
+ splitPath.reduce((acc, key, index, array) => {
324
+ const objFuncKey = toCamelCase(key);
325
+ if (!objFuncKey) return acc;
326
+ const methods = Object.keys(operation);
327
+ if (index === array.length - 1 && methods.length === 1 && allPathsClean.filter((p) => p === cleanPath(path)).length === 1) {
328
+ const method = methods[0];
329
+ const opp = { ...operation }[method];
330
+ acc[objFuncKey] = createFunctionPlaceholder(path, methods[0], opp);
331
+ } else if (index === array.length - 1) {
332
+ acc[objFuncKey] = handlePathSegment(path, operation, acc[objFuncKey]);
333
+ } else if (!acc[objFuncKey] || typeof acc[objFuncKey] !== "object") {
334
+ acc[objFuncKey] = {};
335
+ }
336
+ return acc[objFuncKey];
337
+ }, body);
338
+ }
339
+ for (const [parent, object] of Object.entries(body)) {
340
+ tsString += `export const ${parent} = ${JSON.stringify(object, void 0, 2)};
341
+ `;
342
+ }
343
+ Object.entries(functionsInventory).forEach(([key, value]) => {
344
+ tsString = tsString.replace(`"${key}"`, value);
345
+ });
346
+ tsString = fileTemplate(tsString, allTypes, baseUrl);
347
+ return tsString;
348
+ }
349
+
350
+ function generateTypes(schemas) {
351
+ return Object.entries(schemas).map(([typeName, schema]) => {
352
+ typeName = formatType(typeName);
353
+ if (schema.enum) {
354
+ return `export type ${typeName} = ${schema.enum.map((item) => `'${item}'`).join(" | ")};
355
+ `;
356
+ }
357
+ if (schema.type === "array" && schema.items) {
358
+ return `export type ${typeName} = ${schemaToType(schema.items)}[];
359
+ `;
360
+ }
361
+ if (!schema.properties) {
362
+ return "";
363
+ }
364
+ const properties = Object.entries(schema.properties).map(([key, value]) => {
365
+ const varType = formatVarType({ varName: key, schema: value });
366
+ return ` ${varType}`;
367
+ }).join(";\n ");
368
+ return `export type ${typeName} = {
369
+ ${properties};
370
+ };
371
+ `;
372
+ }).join("\n");
373
+ }
374
+
375
+ const basicAuthHeader = { Authorization: "Basic YmFnZWxfdXNlcm5hbWU6Tm90U2VjdXJlQGJhZ2Vs" };
376
+ const index = async (openApiUrl, baseUrl) => {
377
+ try {
378
+ const { data: openApi } = await axios$1.get(openApiUrl, { headers: basicAuthHeader });
379
+ const schemas = openApi.components?.schemas;
380
+ if (!schemas) throw new Error("No schemas found in OpenAPI document");
381
+ const types = generateTypes(schemas);
382
+ const { paths } = openApi;
383
+ if (!paths) throw new Error("No paths found in OpenAPI document");
384
+ const code = generateFunctions(paths, baseUrl);
385
+ return { types, code };
386
+ } catch (error) {
387
+ throw new Error(error);
388
+ }
389
+ };
390
+
391
+ function formatAPIErrorMessage(error) {
392
+ if (!error || !error.response) {
393
+ return "Network error occurred. Please check your connection.";
394
+ }
395
+ const { status, data } = error.response;
396
+ if (data?.detail && Array.isArray(data.detail)) {
397
+ return data.detail.map((err) => {
398
+ const fieldPath = err.loc.slice(1).join(".");
399
+ const field = fieldPath.split(".").map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
400
+ let message = err.msg.replace(/^(?:field|value|string|none) required$/i, "is required").replace(/^value is not a valid/i, "must be a valid").replace(/^ensure this value/i, "this value must").replace(/^str type expected$/i, "must be text").replace(/^value could not be parsed to/i, "must be a").replace(/^ensure this value has at least/i, "must have at least").replace(/^ensure this value has at most/i, "must have at most").replace(/^invalid datetime format/i, "must be a valid date/time").replace(/^value is not a valid email address/i, "must be a valid email address").replace(/^value is not a valid integer/i, "must be a whole number").replace(/^value is not a valid float/i, "must be a valid number");
401
+ return `${field} ${message.toLowerCase()}`;
402
+ }).join("\n");
403
+ }
404
+ switch (status) {
405
+ case 401:
406
+ return "Authentication required. Please log in.";
407
+ case 403:
408
+ return "You do not have permission to perform this action.";
409
+ case 404:
410
+ return "The requested resource was not found.";
411
+ case 429:
412
+ return "Too many requests. Please try again later.";
413
+ case 500:
414
+ return "An internal server error occurred. Please try again later.";
415
+ }
416
+ if (data?.detail && typeof data.detail === "string") {
417
+ return data.detail;
418
+ }
419
+ if (data?.message) {
420
+ return data.message;
421
+ }
422
+ return `An error occurred (Status ${status}): ${error.message || "Unknown error"}`;
423
+ }
424
+
425
+ const axios = axios$1.create({
426
+ withCredentials: true
427
+ });
428
+ class DataRequest {
429
+ data_table;
430
+ bagel;
431
+ itemID;
432
+ _filter = {};
433
+ constructor(table, bagel) {
434
+ this.data_table = table;
435
+ this.bagel = bagel;
436
+ this.itemID = "";
437
+ }
438
+ async post(item) {
439
+ if (!this.data_table) throw new Error("Data table not set");
440
+ const { data } = await axios.post(`/data/${this.data_table}`, item);
441
+ return data;
442
+ }
443
+ filter(filter) {
444
+ this._filter = filter;
445
+ return this;
446
+ }
447
+ async get() {
448
+ if (!this.data_table) throw new Error("Data table not set");
449
+ const filterStr = Object.keys(this._filter).length > 0 ? `?filter={${Object.entries(this._filter).map(([k, v]) => `${k}:${v}`).join(",")}}` : "";
450
+ const url = `/data/${this.data_table}${this.itemID ? `/${this.itemID}` : ""}${filterStr}`;
451
+ try {
452
+ const { data } = await axios.get(url);
453
+ return data;
454
+ } catch (err) {
455
+ console.log(err);
456
+ this.bagel.onError?.(err);
457
+ return void 0;
458
+ }
459
+ }
460
+ item(id) {
461
+ this.itemID = id;
462
+ return this;
463
+ }
464
+ async delete() {
465
+ if (!this.data_table) throw new Error("Data table not set");
466
+ const { data } = await axios.delete(
467
+ `/data/${this.data_table}/${this.itemID}`
468
+ );
469
+ return data;
470
+ }
471
+ async put(updatedItem) {
472
+ const { data_table, itemID } = this;
473
+ if (!data_table) throw new Error("Data table not set");
474
+ if (!itemID) throw new Error("Item ID not set");
475
+ const { data } = await axios.put(
476
+ `/data/${data_table}/${itemID}`,
477
+ updatedItem
478
+ );
479
+ return data;
480
+ }
481
+ }
482
+ function responses(key) {
483
+ const res = {
484
+ LOGIN_BAD_CREDENTIALS: "Invalid username or password",
485
+ RESET_PASSWORD_BAD_TOKEN: "This reset password link is invalid or expired."
486
+ };
487
+ return res[key] || key;
488
+ }
489
+ class BagelAuth {
490
+ constructor(bagel) {
491
+ this.bagel = bagel;
492
+ this.bagel = bagel;
493
+ }
494
+ user = void 0;
495
+ async validateUser() {
496
+ try {
497
+ const { data: usr } = await axios.get("/users/me", {
498
+ withCredentials: true
499
+ });
500
+ this.user = usr;
501
+ return usr;
502
+ } catch {
503
+ }
504
+ }
505
+ async resetPassword(ctx) {
506
+ return this.bagel.post("auth/reset-password", ctx).catch((err) => {
507
+ throw responses(err.response?.data?.detail);
508
+ });
509
+ }
510
+ async forgotPassword(email) {
511
+ try {
512
+ await this.bagel.post("auth/forgot-password", { email });
513
+ } catch (err) {
514
+ throw responses(err?.response?.data?.detail);
515
+ }
516
+ }
517
+ async login(user) {
518
+ const formData = new FormData();
519
+ formData.append("username", user.email || "");
520
+ formData.append("password", user.password || "");
521
+ console.log("Logging in");
522
+ try {
523
+ await axios.post("/auth/cookie/login", formData, {
524
+ headers: {
525
+ "withCredentials": true,
526
+ "Content-Type": "multipart/form-data"
527
+ }
528
+ });
529
+ axios.defaults.withCredentials = true;
530
+ return this.validateUser();
531
+ } catch (err) {
532
+ throw responses(err.response?.data?.detail || "LOGIN_BAD_CREDENTIALS");
533
+ }
534
+ }
535
+ async logout() {
536
+ try {
537
+ await axios.post("/auth/cookie/logout");
538
+ } catch (err) {
539
+ this.bagel.onError?.(err);
540
+ console.log(err);
541
+ }
542
+ this.user = void 0;
543
+ }
544
+ async acceptInvite(token, user) {
545
+ await axios.post(`/auth/accept-invite/${token}`, user);
546
+ await this.login(user);
547
+ }
548
+ async register(user, errors) {
549
+ try {
550
+ await axios.post("/auth/register", user);
551
+ return this.login(user);
552
+ } catch (err) {
553
+ console.error(err);
554
+ errors.email = err.response.data.detail;
555
+ throw err;
556
+ }
557
+ }
558
+ }
559
+ class Bagel {
560
+ host;
561
+ fileBaseUrl;
562
+ onError;
563
+ constructor({ host, fileBaseUrl, onError }) {
564
+ this.host = host?.replace(/\/$/, "");
565
+ this.fileBaseUrl = fileBaseUrl?.replace(/\/$/, "");
566
+ if (!this.host) {
567
+ return this;
568
+ }
569
+ axios.defaults.baseURL = this.host;
570
+ this.onError = onError;
571
+ }
572
+ read_table = void 0;
573
+ data(table) {
574
+ return new DataRequest(table, this);
575
+ }
576
+ auth = new BagelAuth(this);
577
+ _endpointCleaner(endpoint) {
578
+ const url = `${endpoint.replace(/^\//, "").replaceAll(/\/$/g, "")}`;
579
+ return url;
580
+ }
581
+ async api(endpoint, query) {
582
+ if (query) {
583
+ const queryParams = Object.entries(query).map(([key, value]) => `${key}=${value}`).join("&");
584
+ endpoint = `${endpoint}?${queryParams}`;
585
+ }
586
+ return axios.get(`/api/${endpoint}`).then(({ data }) => data);
587
+ }
588
+ async get(endpoint, query) {
589
+ this._setAuthorization();
590
+ endpoint = this._endpointCleaner(endpoint);
591
+ if (/undefined|null/.test(endpoint)) throw new Error(`Invalid endpoint: ${endpoint}`);
592
+ if (query) {
593
+ const queryParams = Object.entries(query).filter(([_, value]) => !!value).map(([key, value]) => `${key}=${value}`).join("&");
594
+ if (queryParams) endpoint = `${endpoint}?${queryParams}`;
595
+ }
596
+ const url = `/${endpoint}`;
597
+ return axios.get(url).then(({ data }) => data).catch((err) => {
598
+ this.onError?.(err);
599
+ throw err;
600
+ });
601
+ }
602
+ async delete(endpoint) {
603
+ this._setAuthorization();
604
+ endpoint = this._endpointCleaner(endpoint);
605
+ return axios.delete(`/${endpoint}`).then(({ data }) => data).catch((err) => {
606
+ this.onError?.(err);
607
+ throw err;
608
+ });
609
+ }
610
+ async put(endpoint, payload) {
611
+ endpoint = this._endpointCleaner(endpoint);
612
+ this._setAuthorization();
613
+ return axios.put(`/${endpoint}`, payload).then(({ data }) => data).catch((err) => {
614
+ this.onError?.(err);
615
+ throw err;
616
+ });
617
+ }
618
+ async patch(endpoint, payload = {}) {
619
+ endpoint = this._endpointCleaner(endpoint);
620
+ return axios.patch(`/${endpoint}`, payload).then(({ data }) => data).catch((err) => {
621
+ this.onError?.(err);
622
+ throw err;
623
+ });
624
+ }
625
+ _setAuthorization() {
626
+ const Authorization = localStorage.getItem("access_token");
627
+ if (Authorization) {
628
+ axios.defaults.headers.common.Authorization = `Bearer ${Authorization}`;
629
+ }
630
+ }
631
+ async post(endpoint, payload = {}) {
632
+ this._setAuthorization();
633
+ endpoint = this._endpointCleaner(endpoint);
634
+ return axios.post(`/${endpoint}`, payload).then(({ data }) => data).catch((err) => {
635
+ this.onError?.(err);
636
+ throw err;
637
+ });
638
+ }
639
+ async uploadFile(file, options) {
640
+ this._setAuthorization();
641
+ const formData = new FormData();
642
+ formData.append("file", file);
643
+ let url = "/static_files/upload";
644
+ if (options?.topic) url = `/static_files/upload?topic=${options.topic}`;
645
+ const { data } = await axios.post(url, formData, {
646
+ headers: {
647
+ "Content-Type": "multipart/form-data"
648
+ },
649
+ onUploadProgress: options?.onUploadProgress
650
+ });
651
+ return data;
652
+ }
653
+ }
654
+
655
+ export { Bagel, formatAPIErrorMessage, index as openAPI };