@bagelink/sdk 0.0.1123 → 0.0.1129
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.cjs +83 -46
- package/dist/index.mjs +83 -46
- package/package.json +1 -1
- package/src/openAPITools/functionGenerator.ts +10 -10
- package/src/openAPITools/utils.ts +18 -17
package/dist/index.cjs
CHANGED
|
@@ -6,27 +6,36 @@ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'defau
|
|
|
6
6
|
|
|
7
7
|
const axios__default = /*#__PURE__*/_interopDefaultCompat(axios$1);
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
function toCamelCase(str) {
|
|
10
|
+
return str?.replaceAll(/[-._\s]+(.)?/g, (_, c) => c?.toUpperCase() || "").replace(/^./, (str2) => str2.toLowerCase()) || str || "";
|
|
11
|
+
}
|
|
12
|
+
function toPascalCase(str) {
|
|
13
|
+
return str?.replaceAll(/[-_\s]+(.)?/g, (_, c) => c?.toUpperCase() || "").replace(/^./, (str2) => str2.toUpperCase()) || str || "";
|
|
14
|
+
}
|
|
11
15
|
function formatType(typeName) {
|
|
12
|
-
typeName = typeName.replaceAll("-", "").replaceAll(/
|
|
16
|
+
typeName = typeName.replaceAll("-", "").replaceAll(/post|put$/gi, "").replaceAll(/^body_/gi, "");
|
|
13
17
|
return toPascalCase(typeName);
|
|
14
18
|
}
|
|
15
19
|
function resolveReference(ref) {
|
|
16
20
|
const t = ref.split("/").pop();
|
|
17
|
-
if (!t)
|
|
21
|
+
if (!t)
|
|
22
|
+
return "any";
|
|
18
23
|
return formatType(t);
|
|
19
24
|
}
|
|
20
25
|
function schemaToType(schema) {
|
|
21
|
-
if (!schema)
|
|
26
|
+
if (!schema)
|
|
27
|
+
return "any";
|
|
22
28
|
if (schema.anyOf) {
|
|
23
29
|
let _t = schema.anyOf.map((s) => schemaToType(s)).filter((p) => p !== "any").join(" | ");
|
|
24
|
-
if (_t === "" || _t === "null")
|
|
30
|
+
if (_t === "" || _t === "null")
|
|
31
|
+
_t = "any";
|
|
25
32
|
return _t;
|
|
26
33
|
}
|
|
27
|
-
if (schema.allOf)
|
|
34
|
+
if (schema.allOf) {
|
|
28
35
|
return schema.allOf.map((s) => schemaToType(s)).filter((p) => p !== "any").join(" & ");
|
|
29
|
-
|
|
36
|
+
}
|
|
37
|
+
if (schema.$ref)
|
|
38
|
+
return resolveReference(schema.$ref);
|
|
30
39
|
switch (schema.type) {
|
|
31
40
|
case "object":
|
|
32
41
|
return "{ [key: string]: any }";
|
|
@@ -44,7 +53,7 @@ function schemaToType(schema) {
|
|
|
44
53
|
return "undefined";
|
|
45
54
|
case "null":
|
|
46
55
|
return "null";
|
|
47
|
-
case
|
|
56
|
+
case void 0:
|
|
48
57
|
return "any";
|
|
49
58
|
default:
|
|
50
59
|
console.log("Unknown type", schema.type);
|
|
@@ -56,16 +65,17 @@ function isOptional(schema) {
|
|
|
56
65
|
const splitType = type.split(/\s+\|\s+/);
|
|
57
66
|
const includesNull = splitType.includes("null");
|
|
58
67
|
const includesUndefined = splitType.includes("undefined");
|
|
59
|
-
return includesNull || includesUndefined || schema.default !==
|
|
68
|
+
return includesNull || includesUndefined || schema.default !== void 0;
|
|
69
|
+
}
|
|
70
|
+
function cleanOptionals(str) {
|
|
71
|
+
return str.split(" | ").filter((t) => t !== "null" && t !== "undefined").join(" | ");
|
|
60
72
|
}
|
|
61
|
-
const cleanOptionals = (str) => str.split(" | ").filter((t) => t !== "null" && t !== "undefined").join(" | ");
|
|
62
73
|
function formatVarType({
|
|
63
74
|
varName,
|
|
64
75
|
schema,
|
|
65
76
|
required = false,
|
|
66
77
|
defaultValue
|
|
67
78
|
}) {
|
|
68
|
-
if (varName === "personId") console.log({ varName, schema, required, defaultValue });
|
|
69
79
|
let type = schemaToType(schema);
|
|
70
80
|
type = cleanOptionals(type);
|
|
71
81
|
let defaultStr = "";
|
|
@@ -77,7 +87,8 @@ function formatVarType({
|
|
|
77
87
|
}
|
|
78
88
|
}
|
|
79
89
|
let optionalStr = !required && isOptional(schema) ? "?" : "";
|
|
80
|
-
if (defaultStr)
|
|
90
|
+
if (defaultStr)
|
|
91
|
+
optionalStr = "";
|
|
81
92
|
return `${varName}${optionalStr}: ${type}${defaultStr}`;
|
|
82
93
|
}
|
|
83
94
|
function cleanPath(path) {
|
|
@@ -106,18 +117,22 @@ function collectTypeForImportStatement(typeName) {
|
|
|
106
117
|
}
|
|
107
118
|
const isPrimitive = primitiveTypes.includes(typeName);
|
|
108
119
|
typeName = formatType(typeName);
|
|
109
|
-
if (!typeName || isPrimitive)
|
|
110
|
-
|
|
120
|
+
if (!typeName || isPrimitive)
|
|
121
|
+
return;
|
|
122
|
+
if (!allTypes.includes(typeName))
|
|
123
|
+
allTypes.push(typeName);
|
|
111
124
|
}
|
|
112
125
|
function getResponseType(response) {
|
|
113
126
|
const mediaTypeObject = response.content?.["application/json"];
|
|
114
|
-
if (!mediaTypeObject || !mediaTypeObject.schema)
|
|
127
|
+
if (!mediaTypeObject || !mediaTypeObject.schema)
|
|
128
|
+
return;
|
|
115
129
|
const responseType = schemaToType(mediaTypeObject.schema);
|
|
116
130
|
collectTypeForImportStatement(responseType);
|
|
117
131
|
return responseType;
|
|
118
132
|
}
|
|
119
133
|
function generateResponseType(responses) {
|
|
120
|
-
if (!responses)
|
|
134
|
+
if (!responses)
|
|
135
|
+
return "";
|
|
121
136
|
const types = [];
|
|
122
137
|
for (const [statusCode, response] of Object.entries(responses)) {
|
|
123
138
|
if (statusCode.startsWith("2")) {
|
|
@@ -130,7 +145,8 @@ function generateResponseType(responses) {
|
|
|
130
145
|
return types.join(" | ");
|
|
131
146
|
}
|
|
132
147
|
function generateAxiosFunction(method, formattedPath, allParams, responseTypeStr, parameters, requestBodyPayload) {
|
|
133
|
-
if (allParams === "undefined")
|
|
148
|
+
if (allParams === "undefined")
|
|
149
|
+
allParams = "";
|
|
134
150
|
let axiosFunction = `async (${allParams})${responseTypeStr} => {`;
|
|
135
151
|
if (requestBodyPayload === "formData") {
|
|
136
152
|
const paramStr = parameters?.config?.params ? `params: {${parameters.config.params}}` : "";
|
|
@@ -190,12 +206,14 @@ function combineAllParams(parameters, requestBodyParam) {
|
|
|
190
206
|
let allParamsArray = [];
|
|
191
207
|
if (parameters && parameters.params)
|
|
192
208
|
allParamsArray = parameters.params.split(",").map((p) => p.trim());
|
|
193
|
-
if (requestBodyParam)
|
|
209
|
+
if (requestBodyParam)
|
|
210
|
+
allParamsArray.push(requestBodyParam.trim());
|
|
194
211
|
allParamsArray = allParamsArray.filter((p) => p).sort((a, b) => (a.includes("?") ? 1 : -1) - (b.includes("?") ? 1 : -1));
|
|
195
212
|
return allParamsArray.join(", ");
|
|
196
213
|
}
|
|
197
214
|
function generateFunctionParameters(params, isFileUpload = false) {
|
|
198
|
-
if (!params?.length)
|
|
215
|
+
if (!params?.length)
|
|
216
|
+
return {};
|
|
199
217
|
if (isFileUpload) {
|
|
200
218
|
return {
|
|
201
219
|
config: {
|
|
@@ -234,7 +252,8 @@ function generateFunctionParameters(params, isFileUpload = false) {
|
|
|
234
252
|
};
|
|
235
253
|
}
|
|
236
254
|
function generateFunctionForOperation(method, path, operation) {
|
|
237
|
-
if (!operation)
|
|
255
|
+
if (!operation)
|
|
256
|
+
return "";
|
|
238
257
|
const isFileUpload = operation.requestBody?.content["multipart/form-data"]?.schema?.$ref?.includes("Body_upload_files");
|
|
239
258
|
const parameters = generateFunctionParameters(
|
|
240
259
|
operation.parameters,
|
|
@@ -316,7 +335,8 @@ function generateFunctions(paths, baseUrl) {
|
|
|
316
335
|
const splitPath = path.split("/").filter((p) => p && !/\{|\}/.test(p));
|
|
317
336
|
splitPath.reduce((acc, key, index, array) => {
|
|
318
337
|
const objFuncKey = toCamelCase(key);
|
|
319
|
-
if (!objFuncKey)
|
|
338
|
+
if (!objFuncKey)
|
|
339
|
+
return acc;
|
|
320
340
|
const methods = Object.keys(operation);
|
|
321
341
|
if (index === array.length - 1 && methods.length === 1 && allPathsClean.filter((p) => p === cleanPath(path)).length === 1) {
|
|
322
342
|
const method = methods[0];
|
|
@@ -331,7 +351,7 @@ function generateFunctions(paths, baseUrl) {
|
|
|
331
351
|
}, body);
|
|
332
352
|
}
|
|
333
353
|
for (const [parent, object] of Object.entries(body)) {
|
|
334
|
-
tsString += `export const ${parent} = ${JSON.stringify(object,
|
|
354
|
+
tsString += `export const ${parent} = ${JSON.stringify(object, void 0, 2)};
|
|
335
355
|
`;
|
|
336
356
|
}
|
|
337
357
|
Object.entries(functionsInventory).forEach(([key, value]) => {
|
|
@@ -348,7 +368,8 @@ function generateTypes(schemas) {
|
|
|
348
368
|
return `export type ${typeName} = ${schema.enum.map((item) => `'${item}'`).join(" | ")};
|
|
349
369
|
`;
|
|
350
370
|
}
|
|
351
|
-
if (!schema.properties)
|
|
371
|
+
if (!schema.properties)
|
|
372
|
+
return "";
|
|
352
373
|
const properties = Object.entries(schema.properties).map(([key, value]) => {
|
|
353
374
|
const varType = formatVarType({ varName: key, schema: value });
|
|
354
375
|
return ` ${varType}`;
|
|
@@ -365,10 +386,12 @@ const index = async (openApiUrl, baseUrl) => {
|
|
|
365
386
|
try {
|
|
366
387
|
const { data: openApi } = await axios__default.get(openApiUrl, { headers: basicAuthHeader });
|
|
367
388
|
const schemas = openApi.components?.schemas;
|
|
368
|
-
if (!schemas)
|
|
389
|
+
if (!schemas)
|
|
390
|
+
throw new Error("No schemas found in OpenAPI document");
|
|
369
391
|
const types = generateTypes(schemas);
|
|
370
392
|
const { paths } = openApi;
|
|
371
|
-
if (!paths)
|
|
393
|
+
if (!paths)
|
|
394
|
+
throw new Error("No paths found in OpenAPI document");
|
|
372
395
|
const code = generateFunctions(paths, baseUrl);
|
|
373
396
|
return { types, code };
|
|
374
397
|
} catch (error) {
|
|
@@ -376,21 +399,28 @@ const index = async (openApiUrl, baseUrl) => {
|
|
|
376
399
|
}
|
|
377
400
|
};
|
|
378
401
|
|
|
402
|
+
var __defProp = Object.defineProperty;
|
|
403
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
404
|
+
var __publicField = (obj, key, value) => {
|
|
405
|
+
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
406
|
+
return value;
|
|
407
|
+
};
|
|
379
408
|
const axios = axios__default.create({
|
|
380
409
|
withCredentials: true
|
|
381
410
|
});
|
|
382
411
|
class DataRequest {
|
|
383
|
-
data_table;
|
|
384
|
-
bagel;
|
|
385
|
-
itemID;
|
|
386
|
-
_filter = {};
|
|
387
412
|
constructor(table, bagel) {
|
|
413
|
+
__publicField(this, "data_table");
|
|
414
|
+
__publicField(this, "bagel");
|
|
415
|
+
__publicField(this, "itemID");
|
|
416
|
+
__publicField(this, "_filter", {});
|
|
388
417
|
this.data_table = table;
|
|
389
418
|
this.bagel = bagel;
|
|
390
419
|
this.itemID = "";
|
|
391
420
|
}
|
|
392
421
|
async post(item) {
|
|
393
|
-
if (!this.data_table)
|
|
422
|
+
if (!this.data_table)
|
|
423
|
+
throw new Error("Data table not set");
|
|
394
424
|
const { data } = await axios.post(`/data/${this.data_table}`, item);
|
|
395
425
|
return data;
|
|
396
426
|
}
|
|
@@ -399,7 +429,8 @@ class DataRequest {
|
|
|
399
429
|
return this;
|
|
400
430
|
}
|
|
401
431
|
async get() {
|
|
402
|
-
if (!this.data_table)
|
|
432
|
+
if (!this.data_table)
|
|
433
|
+
throw new Error("Data table not set");
|
|
403
434
|
const filterStr = Object.keys(this._filter).length > 0 ? `?filter={${Object.entries(this._filter).map(([k, v]) => `${k}:${v}`).join(",")}}` : "";
|
|
404
435
|
const url = `/data/${this.data_table}${this.itemID ? `/${this.itemID}` : ""}${filterStr}`;
|
|
405
436
|
try {
|
|
@@ -408,7 +439,7 @@ class DataRequest {
|
|
|
408
439
|
} catch (err) {
|
|
409
440
|
console.log(err);
|
|
410
441
|
this.bagel.onError?.(err);
|
|
411
|
-
return
|
|
442
|
+
return void 0;
|
|
412
443
|
}
|
|
413
444
|
}
|
|
414
445
|
item(id) {
|
|
@@ -416,7 +447,8 @@ class DataRequest {
|
|
|
416
447
|
return this;
|
|
417
448
|
}
|
|
418
449
|
async delete() {
|
|
419
|
-
if (!this.data_table)
|
|
450
|
+
if (!this.data_table)
|
|
451
|
+
throw new Error("Data table not set");
|
|
420
452
|
const { data } = await axios.delete(
|
|
421
453
|
`/data/${this.data_table}/${this.itemID}`
|
|
422
454
|
);
|
|
@@ -424,8 +456,10 @@ class DataRequest {
|
|
|
424
456
|
}
|
|
425
457
|
async put(updatedItem) {
|
|
426
458
|
const { data_table, itemID } = this;
|
|
427
|
-
if (!data_table)
|
|
428
|
-
|
|
459
|
+
if (!data_table)
|
|
460
|
+
throw new Error("Data table not set");
|
|
461
|
+
if (!itemID)
|
|
462
|
+
throw new Error("Item ID not set");
|
|
429
463
|
const { data } = await axios.put(
|
|
430
464
|
`/data/${data_table}/${itemID}`,
|
|
431
465
|
updatedItem
|
|
@@ -443,9 +477,9 @@ function responses(key) {
|
|
|
443
477
|
class BagelAuth {
|
|
444
478
|
constructor(bagel) {
|
|
445
479
|
this.bagel = bagel;
|
|
480
|
+
__publicField(this, "user");
|
|
446
481
|
this.bagel = bagel;
|
|
447
482
|
}
|
|
448
|
-
user = undefined;
|
|
449
483
|
async validateUser() {
|
|
450
484
|
try {
|
|
451
485
|
const { data: usr } = await axios.get("/users/me", {
|
|
@@ -493,7 +527,7 @@ class BagelAuth {
|
|
|
493
527
|
this.bagel.onError?.(err);
|
|
494
528
|
console.log(err);
|
|
495
529
|
}
|
|
496
|
-
this.user =
|
|
530
|
+
this.user = void 0;
|
|
497
531
|
}
|
|
498
532
|
async acceptInvite(token, user) {
|
|
499
533
|
await axios.post(`/auth/accept-invite/${token}`, user);
|
|
@@ -511,10 +545,12 @@ class BagelAuth {
|
|
|
511
545
|
}
|
|
512
546
|
}
|
|
513
547
|
class Bagel {
|
|
514
|
-
host;
|
|
515
|
-
fileBaseUrl;
|
|
516
|
-
onError;
|
|
517
548
|
constructor({ host, fileBaseUrl, onError }) {
|
|
549
|
+
__publicField(this, "host");
|
|
550
|
+
__publicField(this, "fileBaseUrl");
|
|
551
|
+
__publicField(this, "onError");
|
|
552
|
+
__publicField(this, "read_table");
|
|
553
|
+
__publicField(this, "auth", new BagelAuth(this));
|
|
518
554
|
this.host = host?.replace(/\/$/, "");
|
|
519
555
|
this.fileBaseUrl = fileBaseUrl?.replace(/\/$/, "");
|
|
520
556
|
if (!this.host) {
|
|
@@ -523,11 +559,9 @@ class Bagel {
|
|
|
523
559
|
axios.defaults.baseURL = this.host;
|
|
524
560
|
this.onError = onError;
|
|
525
561
|
}
|
|
526
|
-
read_table = undefined;
|
|
527
562
|
data(table) {
|
|
528
563
|
return new DataRequest(table, this);
|
|
529
564
|
}
|
|
530
|
-
auth = new BagelAuth(this);
|
|
531
565
|
_endpointCleaner(endpoint) {
|
|
532
566
|
const url = `${endpoint.replace(/^\//, "").replaceAll(/\/$/g, "")}`;
|
|
533
567
|
return url;
|
|
@@ -542,10 +576,12 @@ class Bagel {
|
|
|
542
576
|
async get(endpoint, query) {
|
|
543
577
|
this._setAuthorization();
|
|
544
578
|
endpoint = this._endpointCleaner(endpoint);
|
|
545
|
-
if (/undefined|null/.test(endpoint))
|
|
579
|
+
if (/undefined|null/.test(endpoint))
|
|
580
|
+
throw new Error(`Invalid endpoint: ${endpoint}`);
|
|
546
581
|
if (query) {
|
|
547
582
|
const queryParams = Object.entries(query).filter(([_, value]) => !!value).map(([key, value]) => `${key}=${value}`).join("&");
|
|
548
|
-
if (queryParams)
|
|
583
|
+
if (queryParams)
|
|
584
|
+
endpoint = `${endpoint}?${queryParams}`;
|
|
549
585
|
}
|
|
550
586
|
const url = `/${endpoint}`;
|
|
551
587
|
return axios.get(url).then(({ data }) => data).catch((err) => {
|
|
@@ -595,7 +631,8 @@ class Bagel {
|
|
|
595
631
|
const formData = new FormData();
|
|
596
632
|
formData.append("file", file);
|
|
597
633
|
let url = "/static_files/upload";
|
|
598
|
-
if (options?.topic)
|
|
634
|
+
if (options?.topic)
|
|
635
|
+
url = `/static_files/upload?topic=${options.topic}`;
|
|
599
636
|
const { data } = await axios.post(url, formData, {
|
|
600
637
|
headers: {
|
|
601
638
|
"Content-Type": "multipart/form-data"
|
package/dist/index.mjs
CHANGED
|
@@ -1,26 +1,35 @@
|
|
|
1
1
|
import axios$1 from 'axios';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
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
|
+
}
|
|
5
9
|
function formatType(typeName) {
|
|
6
|
-
typeName = typeName.replaceAll("-", "").replaceAll(/
|
|
10
|
+
typeName = typeName.replaceAll("-", "").replaceAll(/post|put$/gi, "").replaceAll(/^body_/gi, "");
|
|
7
11
|
return toPascalCase(typeName);
|
|
8
12
|
}
|
|
9
13
|
function resolveReference(ref) {
|
|
10
14
|
const t = ref.split("/").pop();
|
|
11
|
-
if (!t)
|
|
15
|
+
if (!t)
|
|
16
|
+
return "any";
|
|
12
17
|
return formatType(t);
|
|
13
18
|
}
|
|
14
19
|
function schemaToType(schema) {
|
|
15
|
-
if (!schema)
|
|
20
|
+
if (!schema)
|
|
21
|
+
return "any";
|
|
16
22
|
if (schema.anyOf) {
|
|
17
23
|
let _t = schema.anyOf.map((s) => schemaToType(s)).filter((p) => p !== "any").join(" | ");
|
|
18
|
-
if (_t === "" || _t === "null")
|
|
24
|
+
if (_t === "" || _t === "null")
|
|
25
|
+
_t = "any";
|
|
19
26
|
return _t;
|
|
20
27
|
}
|
|
21
|
-
if (schema.allOf)
|
|
28
|
+
if (schema.allOf) {
|
|
22
29
|
return schema.allOf.map((s) => schemaToType(s)).filter((p) => p !== "any").join(" & ");
|
|
23
|
-
|
|
30
|
+
}
|
|
31
|
+
if (schema.$ref)
|
|
32
|
+
return resolveReference(schema.$ref);
|
|
24
33
|
switch (schema.type) {
|
|
25
34
|
case "object":
|
|
26
35
|
return "{ [key: string]: any }";
|
|
@@ -38,7 +47,7 @@ function schemaToType(schema) {
|
|
|
38
47
|
return "undefined";
|
|
39
48
|
case "null":
|
|
40
49
|
return "null";
|
|
41
|
-
case
|
|
50
|
+
case void 0:
|
|
42
51
|
return "any";
|
|
43
52
|
default:
|
|
44
53
|
console.log("Unknown type", schema.type);
|
|
@@ -50,16 +59,17 @@ function isOptional(schema) {
|
|
|
50
59
|
const splitType = type.split(/\s+\|\s+/);
|
|
51
60
|
const includesNull = splitType.includes("null");
|
|
52
61
|
const includesUndefined = splitType.includes("undefined");
|
|
53
|
-
return includesNull || includesUndefined || schema.default !==
|
|
62
|
+
return includesNull || includesUndefined || schema.default !== void 0;
|
|
63
|
+
}
|
|
64
|
+
function cleanOptionals(str) {
|
|
65
|
+
return str.split(" | ").filter((t) => t !== "null" && t !== "undefined").join(" | ");
|
|
54
66
|
}
|
|
55
|
-
const cleanOptionals = (str) => str.split(" | ").filter((t) => t !== "null" && t !== "undefined").join(" | ");
|
|
56
67
|
function formatVarType({
|
|
57
68
|
varName,
|
|
58
69
|
schema,
|
|
59
70
|
required = false,
|
|
60
71
|
defaultValue
|
|
61
72
|
}) {
|
|
62
|
-
if (varName === "personId") console.log({ varName, schema, required, defaultValue });
|
|
63
73
|
let type = schemaToType(schema);
|
|
64
74
|
type = cleanOptionals(type);
|
|
65
75
|
let defaultStr = "";
|
|
@@ -71,7 +81,8 @@ function formatVarType({
|
|
|
71
81
|
}
|
|
72
82
|
}
|
|
73
83
|
let optionalStr = !required && isOptional(schema) ? "?" : "";
|
|
74
|
-
if (defaultStr)
|
|
84
|
+
if (defaultStr)
|
|
85
|
+
optionalStr = "";
|
|
75
86
|
return `${varName}${optionalStr}: ${type}${defaultStr}`;
|
|
76
87
|
}
|
|
77
88
|
function cleanPath(path) {
|
|
@@ -100,18 +111,22 @@ function collectTypeForImportStatement(typeName) {
|
|
|
100
111
|
}
|
|
101
112
|
const isPrimitive = primitiveTypes.includes(typeName);
|
|
102
113
|
typeName = formatType(typeName);
|
|
103
|
-
if (!typeName || isPrimitive)
|
|
104
|
-
|
|
114
|
+
if (!typeName || isPrimitive)
|
|
115
|
+
return;
|
|
116
|
+
if (!allTypes.includes(typeName))
|
|
117
|
+
allTypes.push(typeName);
|
|
105
118
|
}
|
|
106
119
|
function getResponseType(response) {
|
|
107
120
|
const mediaTypeObject = response.content?.["application/json"];
|
|
108
|
-
if (!mediaTypeObject || !mediaTypeObject.schema)
|
|
121
|
+
if (!mediaTypeObject || !mediaTypeObject.schema)
|
|
122
|
+
return;
|
|
109
123
|
const responseType = schemaToType(mediaTypeObject.schema);
|
|
110
124
|
collectTypeForImportStatement(responseType);
|
|
111
125
|
return responseType;
|
|
112
126
|
}
|
|
113
127
|
function generateResponseType(responses) {
|
|
114
|
-
if (!responses)
|
|
128
|
+
if (!responses)
|
|
129
|
+
return "";
|
|
115
130
|
const types = [];
|
|
116
131
|
for (const [statusCode, response] of Object.entries(responses)) {
|
|
117
132
|
if (statusCode.startsWith("2")) {
|
|
@@ -124,7 +139,8 @@ function generateResponseType(responses) {
|
|
|
124
139
|
return types.join(" | ");
|
|
125
140
|
}
|
|
126
141
|
function generateAxiosFunction(method, formattedPath, allParams, responseTypeStr, parameters, requestBodyPayload) {
|
|
127
|
-
if (allParams === "undefined")
|
|
142
|
+
if (allParams === "undefined")
|
|
143
|
+
allParams = "";
|
|
128
144
|
let axiosFunction = `async (${allParams})${responseTypeStr} => {`;
|
|
129
145
|
if (requestBodyPayload === "formData") {
|
|
130
146
|
const paramStr = parameters?.config?.params ? `params: {${parameters.config.params}}` : "";
|
|
@@ -184,12 +200,14 @@ function combineAllParams(parameters, requestBodyParam) {
|
|
|
184
200
|
let allParamsArray = [];
|
|
185
201
|
if (parameters && parameters.params)
|
|
186
202
|
allParamsArray = parameters.params.split(",").map((p) => p.trim());
|
|
187
|
-
if (requestBodyParam)
|
|
203
|
+
if (requestBodyParam)
|
|
204
|
+
allParamsArray.push(requestBodyParam.trim());
|
|
188
205
|
allParamsArray = allParamsArray.filter((p) => p).sort((a, b) => (a.includes("?") ? 1 : -1) - (b.includes("?") ? 1 : -1));
|
|
189
206
|
return allParamsArray.join(", ");
|
|
190
207
|
}
|
|
191
208
|
function generateFunctionParameters(params, isFileUpload = false) {
|
|
192
|
-
if (!params?.length)
|
|
209
|
+
if (!params?.length)
|
|
210
|
+
return {};
|
|
193
211
|
if (isFileUpload) {
|
|
194
212
|
return {
|
|
195
213
|
config: {
|
|
@@ -228,7 +246,8 @@ function generateFunctionParameters(params, isFileUpload = false) {
|
|
|
228
246
|
};
|
|
229
247
|
}
|
|
230
248
|
function generateFunctionForOperation(method, path, operation) {
|
|
231
|
-
if (!operation)
|
|
249
|
+
if (!operation)
|
|
250
|
+
return "";
|
|
232
251
|
const isFileUpload = operation.requestBody?.content["multipart/form-data"]?.schema?.$ref?.includes("Body_upload_files");
|
|
233
252
|
const parameters = generateFunctionParameters(
|
|
234
253
|
operation.parameters,
|
|
@@ -310,7 +329,8 @@ function generateFunctions(paths, baseUrl) {
|
|
|
310
329
|
const splitPath = path.split("/").filter((p) => p && !/\{|\}/.test(p));
|
|
311
330
|
splitPath.reduce((acc, key, index, array) => {
|
|
312
331
|
const objFuncKey = toCamelCase(key);
|
|
313
|
-
if (!objFuncKey)
|
|
332
|
+
if (!objFuncKey)
|
|
333
|
+
return acc;
|
|
314
334
|
const methods = Object.keys(operation);
|
|
315
335
|
if (index === array.length - 1 && methods.length === 1 && allPathsClean.filter((p) => p === cleanPath(path)).length === 1) {
|
|
316
336
|
const method = methods[0];
|
|
@@ -325,7 +345,7 @@ function generateFunctions(paths, baseUrl) {
|
|
|
325
345
|
}, body);
|
|
326
346
|
}
|
|
327
347
|
for (const [parent, object] of Object.entries(body)) {
|
|
328
|
-
tsString += `export const ${parent} = ${JSON.stringify(object,
|
|
348
|
+
tsString += `export const ${parent} = ${JSON.stringify(object, void 0, 2)};
|
|
329
349
|
`;
|
|
330
350
|
}
|
|
331
351
|
Object.entries(functionsInventory).forEach(([key, value]) => {
|
|
@@ -342,7 +362,8 @@ function generateTypes(schemas) {
|
|
|
342
362
|
return `export type ${typeName} = ${schema.enum.map((item) => `'${item}'`).join(" | ")};
|
|
343
363
|
`;
|
|
344
364
|
}
|
|
345
|
-
if (!schema.properties)
|
|
365
|
+
if (!schema.properties)
|
|
366
|
+
return "";
|
|
346
367
|
const properties = Object.entries(schema.properties).map(([key, value]) => {
|
|
347
368
|
const varType = formatVarType({ varName: key, schema: value });
|
|
348
369
|
return ` ${varType}`;
|
|
@@ -359,10 +380,12 @@ const index = async (openApiUrl, baseUrl) => {
|
|
|
359
380
|
try {
|
|
360
381
|
const { data: openApi } = await axios$1.get(openApiUrl, { headers: basicAuthHeader });
|
|
361
382
|
const schemas = openApi.components?.schemas;
|
|
362
|
-
if (!schemas)
|
|
383
|
+
if (!schemas)
|
|
384
|
+
throw new Error("No schemas found in OpenAPI document");
|
|
363
385
|
const types = generateTypes(schemas);
|
|
364
386
|
const { paths } = openApi;
|
|
365
|
-
if (!paths)
|
|
387
|
+
if (!paths)
|
|
388
|
+
throw new Error("No paths found in OpenAPI document");
|
|
366
389
|
const code = generateFunctions(paths, baseUrl);
|
|
367
390
|
return { types, code };
|
|
368
391
|
} catch (error) {
|
|
@@ -370,21 +393,28 @@ const index = async (openApiUrl, baseUrl) => {
|
|
|
370
393
|
}
|
|
371
394
|
};
|
|
372
395
|
|
|
396
|
+
var __defProp = Object.defineProperty;
|
|
397
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
398
|
+
var __publicField = (obj, key, value) => {
|
|
399
|
+
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
400
|
+
return value;
|
|
401
|
+
};
|
|
373
402
|
const axios = axios$1.create({
|
|
374
403
|
withCredentials: true
|
|
375
404
|
});
|
|
376
405
|
class DataRequest {
|
|
377
|
-
data_table;
|
|
378
|
-
bagel;
|
|
379
|
-
itemID;
|
|
380
|
-
_filter = {};
|
|
381
406
|
constructor(table, bagel) {
|
|
407
|
+
__publicField(this, "data_table");
|
|
408
|
+
__publicField(this, "bagel");
|
|
409
|
+
__publicField(this, "itemID");
|
|
410
|
+
__publicField(this, "_filter", {});
|
|
382
411
|
this.data_table = table;
|
|
383
412
|
this.bagel = bagel;
|
|
384
413
|
this.itemID = "";
|
|
385
414
|
}
|
|
386
415
|
async post(item) {
|
|
387
|
-
if (!this.data_table)
|
|
416
|
+
if (!this.data_table)
|
|
417
|
+
throw new Error("Data table not set");
|
|
388
418
|
const { data } = await axios.post(`/data/${this.data_table}`, item);
|
|
389
419
|
return data;
|
|
390
420
|
}
|
|
@@ -393,7 +423,8 @@ class DataRequest {
|
|
|
393
423
|
return this;
|
|
394
424
|
}
|
|
395
425
|
async get() {
|
|
396
|
-
if (!this.data_table)
|
|
426
|
+
if (!this.data_table)
|
|
427
|
+
throw new Error("Data table not set");
|
|
397
428
|
const filterStr = Object.keys(this._filter).length > 0 ? `?filter={${Object.entries(this._filter).map(([k, v]) => `${k}:${v}`).join(",")}}` : "";
|
|
398
429
|
const url = `/data/${this.data_table}${this.itemID ? `/${this.itemID}` : ""}${filterStr}`;
|
|
399
430
|
try {
|
|
@@ -402,7 +433,7 @@ class DataRequest {
|
|
|
402
433
|
} catch (err) {
|
|
403
434
|
console.log(err);
|
|
404
435
|
this.bagel.onError?.(err);
|
|
405
|
-
return
|
|
436
|
+
return void 0;
|
|
406
437
|
}
|
|
407
438
|
}
|
|
408
439
|
item(id) {
|
|
@@ -410,7 +441,8 @@ class DataRequest {
|
|
|
410
441
|
return this;
|
|
411
442
|
}
|
|
412
443
|
async delete() {
|
|
413
|
-
if (!this.data_table)
|
|
444
|
+
if (!this.data_table)
|
|
445
|
+
throw new Error("Data table not set");
|
|
414
446
|
const { data } = await axios.delete(
|
|
415
447
|
`/data/${this.data_table}/${this.itemID}`
|
|
416
448
|
);
|
|
@@ -418,8 +450,10 @@ class DataRequest {
|
|
|
418
450
|
}
|
|
419
451
|
async put(updatedItem) {
|
|
420
452
|
const { data_table, itemID } = this;
|
|
421
|
-
if (!data_table)
|
|
422
|
-
|
|
453
|
+
if (!data_table)
|
|
454
|
+
throw new Error("Data table not set");
|
|
455
|
+
if (!itemID)
|
|
456
|
+
throw new Error("Item ID not set");
|
|
423
457
|
const { data } = await axios.put(
|
|
424
458
|
`/data/${data_table}/${itemID}`,
|
|
425
459
|
updatedItem
|
|
@@ -437,9 +471,9 @@ function responses(key) {
|
|
|
437
471
|
class BagelAuth {
|
|
438
472
|
constructor(bagel) {
|
|
439
473
|
this.bagel = bagel;
|
|
474
|
+
__publicField(this, "user");
|
|
440
475
|
this.bagel = bagel;
|
|
441
476
|
}
|
|
442
|
-
user = undefined;
|
|
443
477
|
async validateUser() {
|
|
444
478
|
try {
|
|
445
479
|
const { data: usr } = await axios.get("/users/me", {
|
|
@@ -487,7 +521,7 @@ class BagelAuth {
|
|
|
487
521
|
this.bagel.onError?.(err);
|
|
488
522
|
console.log(err);
|
|
489
523
|
}
|
|
490
|
-
this.user =
|
|
524
|
+
this.user = void 0;
|
|
491
525
|
}
|
|
492
526
|
async acceptInvite(token, user) {
|
|
493
527
|
await axios.post(`/auth/accept-invite/${token}`, user);
|
|
@@ -505,10 +539,12 @@ class BagelAuth {
|
|
|
505
539
|
}
|
|
506
540
|
}
|
|
507
541
|
class Bagel {
|
|
508
|
-
host;
|
|
509
|
-
fileBaseUrl;
|
|
510
|
-
onError;
|
|
511
542
|
constructor({ host, fileBaseUrl, onError }) {
|
|
543
|
+
__publicField(this, "host");
|
|
544
|
+
__publicField(this, "fileBaseUrl");
|
|
545
|
+
__publicField(this, "onError");
|
|
546
|
+
__publicField(this, "read_table");
|
|
547
|
+
__publicField(this, "auth", new BagelAuth(this));
|
|
512
548
|
this.host = host?.replace(/\/$/, "");
|
|
513
549
|
this.fileBaseUrl = fileBaseUrl?.replace(/\/$/, "");
|
|
514
550
|
if (!this.host) {
|
|
@@ -517,11 +553,9 @@ class Bagel {
|
|
|
517
553
|
axios.defaults.baseURL = this.host;
|
|
518
554
|
this.onError = onError;
|
|
519
555
|
}
|
|
520
|
-
read_table = undefined;
|
|
521
556
|
data(table) {
|
|
522
557
|
return new DataRequest(table, this);
|
|
523
558
|
}
|
|
524
|
-
auth = new BagelAuth(this);
|
|
525
559
|
_endpointCleaner(endpoint) {
|
|
526
560
|
const url = `${endpoint.replace(/^\//, "").replaceAll(/\/$/g, "")}`;
|
|
527
561
|
return url;
|
|
@@ -536,10 +570,12 @@ class Bagel {
|
|
|
536
570
|
async get(endpoint, query) {
|
|
537
571
|
this._setAuthorization();
|
|
538
572
|
endpoint = this._endpointCleaner(endpoint);
|
|
539
|
-
if (/undefined|null/.test(endpoint))
|
|
573
|
+
if (/undefined|null/.test(endpoint))
|
|
574
|
+
throw new Error(`Invalid endpoint: ${endpoint}`);
|
|
540
575
|
if (query) {
|
|
541
576
|
const queryParams = Object.entries(query).filter(([_, value]) => !!value).map(([key, value]) => `${key}=${value}`).join("&");
|
|
542
|
-
if (queryParams)
|
|
577
|
+
if (queryParams)
|
|
578
|
+
endpoint = `${endpoint}?${queryParams}`;
|
|
543
579
|
}
|
|
544
580
|
const url = `/${endpoint}`;
|
|
545
581
|
return axios.get(url).then(({ data }) => data).catch((err) => {
|
|
@@ -589,7 +625,8 @@ class Bagel {
|
|
|
589
625
|
const formData = new FormData();
|
|
590
626
|
formData.append("file", file);
|
|
591
627
|
let url = "/static_files/upload";
|
|
592
|
-
if (options?.topic)
|
|
628
|
+
if (options?.topic)
|
|
629
|
+
url = `/static_files/upload?topic=${options.topic}`;
|
|
593
630
|
const { data } = await axios.post(url, formData, {
|
|
594
631
|
headers: {
|
|
595
632
|
"Content-Type": "multipart/form-data"
|
package/package.json
CHANGED
|
@@ -33,7 +33,7 @@ const primitiveTypes = [
|
|
|
33
33
|
function collectTypeForImportStatement(typeName: string) {
|
|
34
34
|
typeName = typeName.trim().replace('[]', '')
|
|
35
35
|
if (typeName.includes('|')) {
|
|
36
|
-
typeName.split('|').forEach(singleType => {
|
|
36
|
+
typeName.split('|').forEach((singleType) => {
|
|
37
37
|
collectTypeForImportStatement(singleType)
|
|
38
38
|
})
|
|
39
39
|
return
|
|
@@ -153,10 +153,10 @@ function generateRequestBody(requestBody?: RequestBodyObject): {
|
|
|
153
153
|
const bodySchema = jsonContent.schema
|
|
154
154
|
const requestBodyType = schemaToType(bodySchema)
|
|
155
155
|
collectTypeForImportStatement(requestBodyType)
|
|
156
|
-
const requestBodyPayload
|
|
157
|
-
toCamelCase(bodySchema.title)
|
|
158
|
-
|
|
159
|
-
|
|
156
|
+
const requestBodyPayload
|
|
157
|
+
= toCamelCase(bodySchema.title)
|
|
158
|
+
|| toCamelCase(requestBodyType)
|
|
159
|
+
|| 'requestBody'
|
|
160
160
|
|
|
161
161
|
const requestBodyParam = formatVarType({
|
|
162
162
|
varName: requestBodyPayload,
|
|
@@ -246,8 +246,8 @@ function generateFunctionForOperation(
|
|
|
246
246
|
if (!operation) return ''
|
|
247
247
|
|
|
248
248
|
// Check if this is a file upload operation by looking at the schema reference
|
|
249
|
-
const isFileUpload
|
|
250
|
-
operation.requestBody?.content[
|
|
249
|
+
const isFileUpload
|
|
250
|
+
= operation.requestBody?.content[
|
|
251
251
|
'multipart/form-data'
|
|
252
252
|
]?.schema?.$ref?.includes('Body_upload_files')
|
|
253
253
|
const parameters = generateFunctionParameters(
|
|
@@ -369,9 +369,9 @@ export function generateFunctions(paths: PathsObject, baseUrl: string) {
|
|
|
369
369
|
if (!objFuncKey) return acc
|
|
370
370
|
const methods = Object.keys(operation)
|
|
371
371
|
if (
|
|
372
|
-
index === array.length - 1
|
|
373
|
-
methods.length === 1
|
|
374
|
-
allPathsClean.filter(p => p === cleanPath(path)).length === 1
|
|
372
|
+
index === array.length - 1
|
|
373
|
+
&& methods.length === 1
|
|
374
|
+
&& allPathsClean.filter(p => p === cleanPath(path)).length === 1
|
|
375
375
|
) {
|
|
376
376
|
const method: string = methods[0]
|
|
377
377
|
const opp: any = { ...operation }[method]
|
|
@@ -1,23 +1,24 @@
|
|
|
1
1
|
import type { SchemaObject } from './openApiTypes'
|
|
2
2
|
|
|
3
|
-
export
|
|
4
|
-
str
|
|
3
|
+
export function toCamelCase(str?: string) {
|
|
4
|
+
return str
|
|
5
5
|
?.replaceAll(/[-._\s]+(.)?/g, (_, c) => c?.toUpperCase() || '')
|
|
6
|
-
.replace(/^./, str => str.toLowerCase())
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
.replace(/^./, str => str.toLowerCase())
|
|
7
|
+
|| str
|
|
8
|
+
|| ''
|
|
9
|
+
}
|
|
10
|
+
export function toPascalCase(str?: string) {
|
|
11
|
+
return str
|
|
11
12
|
?.replaceAll(/[-_\s]+(.)?/g, (_, c) => c?.toUpperCase() || '')
|
|
12
|
-
.replace(/^./, str => str.toUpperCase())
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
.replace(/^./, str => str.toUpperCase())
|
|
14
|
+
|| str
|
|
15
|
+
|| ''
|
|
16
|
+
}
|
|
15
17
|
|
|
16
18
|
export function formatType(typeName: string): string {
|
|
17
|
-
// eslint-disable-next-line regexp/no-unused-capturing-group
|
|
18
19
|
typeName = typeName
|
|
19
20
|
.replaceAll('-', '')
|
|
20
|
-
.replaceAll(/
|
|
21
|
+
.replaceAll(/post|put$/gi, '')
|
|
21
22
|
.replaceAll(/^body_/gi, '')
|
|
22
23
|
return toPascalCase(typeName)!
|
|
23
24
|
}
|
|
@@ -38,11 +39,12 @@ export function schemaToType(schema?: SchemaObject): string {
|
|
|
38
39
|
if (_t === '' || _t === 'null') _t = 'any'
|
|
39
40
|
return _t
|
|
40
41
|
}
|
|
41
|
-
if (schema.allOf)
|
|
42
|
+
if (schema.allOf) {
|
|
42
43
|
return schema.allOf
|
|
43
44
|
.map(s => schemaToType(s))
|
|
44
45
|
.filter(p => p !== 'any')
|
|
45
46
|
.join(' & ')
|
|
47
|
+
}
|
|
46
48
|
if (schema.$ref) return resolveReference(schema.$ref)
|
|
47
49
|
switch (schema.type) {
|
|
48
50
|
case 'object':
|
|
@@ -79,11 +81,12 @@ export function isOptional(schema: SchemaObject) {
|
|
|
79
81
|
return includesNull || includesUndefined || schema.default !== undefined
|
|
80
82
|
}
|
|
81
83
|
|
|
82
|
-
export
|
|
83
|
-
str
|
|
84
|
+
export function cleanOptionals(str: string) {
|
|
85
|
+
return str
|
|
84
86
|
.split(' | ')
|
|
85
87
|
.filter(t => t !== 'null' && t !== 'undefined')
|
|
86
88
|
.join(' | ')
|
|
89
|
+
}
|
|
87
90
|
|
|
88
91
|
export function formatVarType({
|
|
89
92
|
varName,
|
|
@@ -96,8 +99,6 @@ export function formatVarType({
|
|
|
96
99
|
required?: boolean
|
|
97
100
|
defaultValue?: unknown
|
|
98
101
|
}) {
|
|
99
|
-
if (varName === 'personId') console.log({ varName, schema, required, defaultValue });
|
|
100
|
-
|
|
101
102
|
let type = schemaToType(schema)
|
|
102
103
|
type = cleanOptionals(type)
|
|
103
104
|
|