@bagelink/sdk 1.5.15 → 1.5.20
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/bin/index.ts +1 -1
- package/bin/splitClientGen.ts +40 -40
- package/dist/index.cjs +110 -52
- package/dist/index.mjs +110 -52
- package/package.json +1 -1
- package/src/index.ts +9 -9
- package/src/openAPITools/functionGenerator.ts +21 -21
- package/src/openAPITools/index.ts +2 -2
- package/src/openAPITools/typeGenerator.ts +6 -6
- package/src/openAPITools/types/utils.ts +3 -3
- package/src/openAPITools/utils.ts +11 -11
- package/src/utils.ts +1 -1
package/dist/index.mjs
CHANGED
|
@@ -4,11 +4,13 @@ function getPath(pathsObject, path) {
|
|
|
4
4
|
return pathsObject ? pathsObject[path] : void 0;
|
|
5
5
|
}
|
|
6
6
|
function isReferenceObject(obj) {
|
|
7
|
-
if (!obj)
|
|
8
|
-
|
|
7
|
+
if (!obj) {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
return Object.hasOwn(obj, "$ref");
|
|
9
11
|
}
|
|
10
12
|
function isSchemaObject(schema) {
|
|
11
|
-
return !Object.
|
|
13
|
+
return !Object.hasOwn(schema, "$ref");
|
|
12
14
|
}
|
|
13
15
|
function dereference(property) {
|
|
14
16
|
return property;
|
|
@@ -26,7 +28,9 @@ function formatType(typeName) {
|
|
|
26
28
|
}
|
|
27
29
|
function resolveReference(ref) {
|
|
28
30
|
const t = ref.split("/").pop();
|
|
29
|
-
if (!t)
|
|
31
|
+
if (!t) {
|
|
32
|
+
return "any";
|
|
33
|
+
}
|
|
30
34
|
return formatType(t);
|
|
31
35
|
}
|
|
32
36
|
function handleArrayItems(schema) {
|
|
@@ -45,21 +49,27 @@ function handleArrayItems(schema) {
|
|
|
45
49
|
return res;
|
|
46
50
|
}
|
|
47
51
|
function schemaToType(schema) {
|
|
48
|
-
if (!schema)
|
|
52
|
+
if (!schema) {
|
|
53
|
+
return "any";
|
|
54
|
+
}
|
|
49
55
|
if (isReferenceObject(schema)) {
|
|
50
|
-
if (schema.$ref)
|
|
56
|
+
if (schema.$ref) {
|
|
57
|
+
return resolveReference(schema.$ref);
|
|
58
|
+
}
|
|
51
59
|
}
|
|
52
60
|
if (!isSchemaObject(schema)) {
|
|
53
61
|
console.warn("Schema is not a SchemaObject:", schema);
|
|
54
62
|
return "any";
|
|
55
63
|
}
|
|
56
64
|
if (schema.anyOf) {
|
|
57
|
-
let _t = schema.anyOf.map((s) => schemaToType(s)).filter((p) =>
|
|
58
|
-
if (
|
|
65
|
+
let _t = schema.anyOf.map((s) => schemaToType(s)).filter((p) => "any" !== p).join(" | ");
|
|
66
|
+
if ("" === _t || "null" === _t) {
|
|
67
|
+
_t = "any";
|
|
68
|
+
}
|
|
59
69
|
return _t;
|
|
60
70
|
}
|
|
61
71
|
if (schema.allOf) {
|
|
62
|
-
return schema.allOf.map((s) => schemaToType(s)).filter((p) =>
|
|
72
|
+
return schema.allOf.map((s) => schemaToType(s)).filter((p) => "any" !== p).join(" & ");
|
|
63
73
|
}
|
|
64
74
|
switch (schema.type) {
|
|
65
75
|
case "object":
|
|
@@ -96,7 +106,7 @@ function isOptional(schema) {
|
|
|
96
106
|
return includesNull || includesUndefined || schema?.default !== void 0;
|
|
97
107
|
}
|
|
98
108
|
function cleanOptionals(str) {
|
|
99
|
-
return str.split(" | ").filter((t) =>
|
|
109
|
+
return str.split(" | ").filter((t) => "null" !== t && "undefined" !== t).join(" | ");
|
|
100
110
|
}
|
|
101
111
|
function formatVarType({
|
|
102
112
|
varName,
|
|
@@ -108,16 +118,18 @@ function formatVarType({
|
|
|
108
118
|
type = cleanOptionals(type);
|
|
109
119
|
let defaultStr = "";
|
|
110
120
|
if (defaultValue) {
|
|
111
|
-
if (typeof defaultValue
|
|
121
|
+
if ("string" === typeof defaultValue) {
|
|
112
122
|
defaultStr = ` = '${defaultValue}'`;
|
|
113
|
-
} else if (typeof defaultValue
|
|
123
|
+
} else if ("object" === typeof defaultValue) {
|
|
114
124
|
defaultStr = ` = ${JSON.stringify(defaultValue)}`;
|
|
115
125
|
} else {
|
|
116
126
|
defaultStr = ` = ${defaultValue}`;
|
|
117
127
|
}
|
|
118
128
|
}
|
|
119
129
|
let optionalStr = !required && isOptional(schema) ? "?" : "";
|
|
120
|
-
if (defaultStr)
|
|
130
|
+
if (defaultStr) {
|
|
131
|
+
optionalStr = "";
|
|
132
|
+
}
|
|
121
133
|
return `${varName}${optionalStr}: ${type}${defaultStr}`;
|
|
122
134
|
}
|
|
123
135
|
const RESERVED_KEYWORDS = /* @__PURE__ */ new Set([
|
|
@@ -230,7 +242,9 @@ const RESERVED_KEYWORDS = /* @__PURE__ */ new Set([
|
|
|
230
242
|
"Reflect"
|
|
231
243
|
]);
|
|
232
244
|
function sanitizeVarName(varName) {
|
|
233
|
-
if (!varName)
|
|
245
|
+
if (!varName) {
|
|
246
|
+
return varName;
|
|
247
|
+
}
|
|
234
248
|
if (RESERVED_KEYWORDS.has(varName.toLowerCase())) {
|
|
235
249
|
return `${varName}_`;
|
|
236
250
|
}
|
|
@@ -267,8 +281,12 @@ function collectTypeForImportStatement(typeName) {
|
|
|
267
281
|
}
|
|
268
282
|
const isPrimitive = primitiveTypes.includes(typeName);
|
|
269
283
|
typeName = formatType(typeName);
|
|
270
|
-
if (!typeName || isPrimitive)
|
|
271
|
-
|
|
284
|
+
if (!typeName || isPrimitive) {
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
if (!allTypes.includes(typeName)) {
|
|
288
|
+
allTypes.push(typeName);
|
|
289
|
+
}
|
|
272
290
|
}
|
|
273
291
|
function schemaToTypeWithCollection(schema) {
|
|
274
292
|
const type = schemaToType(schema);
|
|
@@ -280,16 +298,20 @@ function getResponseType(response) {
|
|
|
280
298
|
return void 0;
|
|
281
299
|
}
|
|
282
300
|
const mediaTypeObject = response.content?.["application/json"];
|
|
283
|
-
if (!mediaTypeObject?.schema)
|
|
301
|
+
if (!mediaTypeObject?.schema) {
|
|
302
|
+
return void 0;
|
|
303
|
+
}
|
|
284
304
|
return schemaToTypeWithCollection(mediaTypeObject.schema);
|
|
285
305
|
}
|
|
286
306
|
function generateResponseType(responses) {
|
|
287
|
-
if (!responses)
|
|
307
|
+
if (!responses) {
|
|
308
|
+
return "";
|
|
309
|
+
}
|
|
288
310
|
const types = [];
|
|
289
311
|
for (const [statusCode, response] of Object.entries(responses)) {
|
|
290
312
|
if (statusCode.startsWith("2")) {
|
|
291
313
|
const responseType = getResponseType(response);
|
|
292
|
-
if (responseType &&
|
|
314
|
+
if (responseType && "any" !== responseType) {
|
|
293
315
|
types.push(responseType);
|
|
294
316
|
}
|
|
295
317
|
}
|
|
@@ -302,12 +324,14 @@ function getParamsFromPath(path) {
|
|
|
302
324
|
}
|
|
303
325
|
function formatPathWithParams(path) {
|
|
304
326
|
const params = getParamsFromPath(path);
|
|
305
|
-
if (!params)
|
|
327
|
+
if (!params) {
|
|
328
|
+
return `'${path}'`;
|
|
329
|
+
}
|
|
306
330
|
return `\`${path.replace(/\{([^}]+)\}/g, (_, paramName) => `\${${toCamelCase(paramName)}}`)}\``;
|
|
307
331
|
}
|
|
308
332
|
function generateRequestBody(requestBody) {
|
|
309
333
|
const content = dereference(requestBody)?.content;
|
|
310
|
-
if (!content || Object.keys(content).length
|
|
334
|
+
if (!content || 0 === Object.keys(content).length) {
|
|
311
335
|
return { requestBodyParam: "", requestBodyPayload: "" };
|
|
312
336
|
}
|
|
313
337
|
if (content["multipart/form-data"]) {
|
|
@@ -339,7 +363,9 @@ function generateRequestBody(requestBody) {
|
|
|
339
363
|
return { requestBodyParam, requestBodyPayload };
|
|
340
364
|
}
|
|
341
365
|
function generateFunctionParameters(params, isFileUpload = false) {
|
|
342
|
-
if (!params?.length)
|
|
366
|
+
if (!params?.length) {
|
|
367
|
+
return {};
|
|
368
|
+
}
|
|
343
369
|
if (isFileUpload) {
|
|
344
370
|
return {
|
|
345
371
|
config: {
|
|
@@ -358,7 +384,7 @@ function generateFunctionParameters(params, isFileUpload = false) {
|
|
|
358
384
|
collectTypeForImportStatement(paramType);
|
|
359
385
|
const paramName = param.name;
|
|
360
386
|
const varName = toCamelCaseSafe(param.name);
|
|
361
|
-
if (
|
|
387
|
+
if ("path" === param.in || "query" === param.in || "header" === param.in) {
|
|
362
388
|
functionParams.push(
|
|
363
389
|
formatVarType({
|
|
364
390
|
varName,
|
|
@@ -368,7 +394,7 @@ function generateFunctionParameters(params, isFileUpload = false) {
|
|
|
368
394
|
})
|
|
369
395
|
);
|
|
370
396
|
}
|
|
371
|
-
if (
|
|
397
|
+
if ("query" === param.in || "header" === param.in) {
|
|
372
398
|
queryParams.push(
|
|
373
399
|
paramName === varName ? paramName : `'${paramName}': ${varName}`
|
|
374
400
|
);
|
|
@@ -386,7 +412,7 @@ function parseParameter(paramStr) {
|
|
|
386
412
|
const name = nameMatch ? nameMatch[1] : "";
|
|
387
413
|
const typeMatch = trimmed.match(/:\s*([^=]+)/);
|
|
388
414
|
const type = typeMatch ? typeMatch[1].trim() : "any";
|
|
389
|
-
const defaultMatch = trimmed.match(
|
|
415
|
+
const defaultMatch = trimmed.match(/[=](.+)$/);
|
|
390
416
|
const defaultValue = defaultMatch ? defaultMatch[1].trim() : void 0;
|
|
391
417
|
return { name, type, defaultValue, isOptional };
|
|
392
418
|
}
|
|
@@ -398,7 +424,7 @@ function combineAllParams(parameters, requestBodyParam) {
|
|
|
398
424
|
if (requestBodyParam) {
|
|
399
425
|
allParamsArray.push(requestBodyParam.trim());
|
|
400
426
|
}
|
|
401
|
-
if (allParamsArray.length
|
|
427
|
+
if (0 === allParamsArray.length) {
|
|
402
428
|
return "";
|
|
403
429
|
}
|
|
404
430
|
const parsedParams = allParamsArray.filter(Boolean).map(parseParameter);
|
|
@@ -409,10 +435,12 @@ function combineAllParams(parameters, requestBodyParam) {
|
|
|
409
435
|
return `{ ${destructuredNames} }: { ${typeDefinition} } = {}`;
|
|
410
436
|
}
|
|
411
437
|
function generateAxiosFunction(method, formattedPath, allParams, responseTypeStr, parameters, requestBodyPayload) {
|
|
412
|
-
if (
|
|
438
|
+
if ("undefined" === allParams) {
|
|
439
|
+
allParams = "";
|
|
440
|
+
}
|
|
413
441
|
let axiosFunction = `async (${allParams})${responseTypeStr} => {`;
|
|
414
442
|
const paramStr = parameters.config?.params ? `params: {${parameters.config.params}}` : "";
|
|
415
|
-
if (
|
|
443
|
+
if ("formData" === requestBodyPayload) {
|
|
416
444
|
if (allParams.includes("file: File")) {
|
|
417
445
|
axiosFunction += `
|
|
418
446
|
const formData = new FormData()
|
|
@@ -442,8 +470,10 @@ function buildJSDocComment(operation, method, path) {
|
|
|
442
470
|
`;
|
|
443
471
|
}
|
|
444
472
|
if (operation.description) {
|
|
445
|
-
if (operation.summary)
|
|
473
|
+
if (operation.summary) {
|
|
474
|
+
functionComment += ` *
|
|
446
475
|
`;
|
|
476
|
+
}
|
|
447
477
|
const descriptionLines = operation.description.split("\n");
|
|
448
478
|
descriptionLines.forEach((line) => {
|
|
449
479
|
functionComment += ` * ${line}
|
|
@@ -457,7 +487,9 @@ function buildJSDocComment(operation, method, path) {
|
|
|
457
487
|
return functionComment;
|
|
458
488
|
}
|
|
459
489
|
function generateFunctionForOperation(method, path, operation) {
|
|
460
|
-
if (!operation)
|
|
490
|
+
if (!operation) {
|
|
491
|
+
return "";
|
|
492
|
+
}
|
|
461
493
|
const multiPartSchema = dereference(operation.requestBody)?.content?.["multipart/form-data"]?.schema;
|
|
462
494
|
const isFileUpload = isReferenceObject(multiPartSchema) && multiPartSchema?.$ref?.includes("Body_upload_files");
|
|
463
495
|
const parameters = generateFunctionParameters(
|
|
@@ -486,7 +518,7 @@ function hasConflict(path, method) {
|
|
|
486
518
|
(p) => p.path === cleanPathName && p.method === method
|
|
487
519
|
);
|
|
488
520
|
pathOperations.push({ path: cleanPathName, method });
|
|
489
|
-
return matchingPaths.length
|
|
521
|
+
return 0 < matchingPaths.length;
|
|
490
522
|
}
|
|
491
523
|
function generateRandomString() {
|
|
492
524
|
return Math.random().toString(36).slice(7);
|
|
@@ -528,15 +560,17 @@ function generateFunctions(paths, baseUrl) {
|
|
|
528
560
|
const splitPath = path.split("/").filter((p) => p && !/\{|\}/.test(p));
|
|
529
561
|
splitPath.reduce((acc, key, index, array) => {
|
|
530
562
|
const objFuncKey = toCamelCaseSafe(key);
|
|
531
|
-
if (!objFuncKey)
|
|
563
|
+
if (!objFuncKey) {
|
|
564
|
+
return acc;
|
|
565
|
+
}
|
|
532
566
|
const methods = Object.keys(operation);
|
|
533
|
-
if (index === array.length - 1 && methods.length
|
|
567
|
+
if (index === array.length - 1 && 1 === methods.length && 1 === allPathsClean.filter((p) => p === cleanPath(path)).length) {
|
|
534
568
|
const method = methods[0];
|
|
535
569
|
const opp = operation[method];
|
|
536
570
|
acc[objFuncKey] = createFunctionPlaceholder(path, method, opp);
|
|
537
571
|
} else if (index === array.length - 1) {
|
|
538
572
|
acc[objFuncKey] = handlePathSegment(path, operation, acc[objFuncKey]);
|
|
539
|
-
} else if (!acc[objFuncKey] || typeof acc[objFuncKey]
|
|
573
|
+
} else if (!acc[objFuncKey] || "object" !== typeof acc[objFuncKey]) {
|
|
540
574
|
acc[objFuncKey] = {};
|
|
541
575
|
}
|
|
542
576
|
return acc[objFuncKey];
|
|
@@ -585,27 +619,31 @@ ${tsString}`;
|
|
|
585
619
|
}
|
|
586
620
|
|
|
587
621
|
function generateTypes(schemas) {
|
|
588
|
-
if (!schemas)
|
|
622
|
+
if (!schemas) {
|
|
623
|
+
return "";
|
|
624
|
+
}
|
|
589
625
|
const schemaEntries = Object.entries(schemas);
|
|
590
626
|
return schemaEntries.map(([_typeName, schema]) => {
|
|
591
627
|
const typeName = formatType(_typeName);
|
|
592
|
-
if (!isSchemaObject(schema))
|
|
628
|
+
if (!isSchemaObject(schema)) {
|
|
629
|
+
return "";
|
|
630
|
+
}
|
|
593
631
|
if (schema?.enum) {
|
|
594
632
|
return `export type ${typeName} = ${schema.enum.map((item) => `'${item}'`).join(" | ")};
|
|
595
633
|
`;
|
|
596
634
|
}
|
|
597
|
-
if (schema?.type
|
|
635
|
+
if ("array" === schema?.type && schema.items) {
|
|
598
636
|
return `export type ${typeName} = (${schemaToType(schema.items)})[];
|
|
599
637
|
`;
|
|
600
638
|
}
|
|
601
639
|
if (!schema.properties) {
|
|
602
|
-
if (schema.additionalProperties
|
|
640
|
+
if (true === schema.additionalProperties) {
|
|
603
641
|
return `export type ${typeName} = { [key: string]: any };
|
|
604
642
|
`;
|
|
605
643
|
}
|
|
606
644
|
return "";
|
|
607
645
|
}
|
|
608
|
-
if (Object.keys(schema.properties).length
|
|
646
|
+
if (0 === Object.keys(schema.properties).length && true === schema.additionalProperties) {
|
|
609
647
|
return `export type ${typeName} = { [key: string]: any };
|
|
610
648
|
`;
|
|
611
649
|
}
|
|
@@ -613,7 +651,7 @@ function generateTypes(schemas) {
|
|
|
613
651
|
const varType = formatVarType({ varName: key, schema: value });
|
|
614
652
|
return ` ${varType}`;
|
|
615
653
|
}).join(";\n ");
|
|
616
|
-
const indexSignature = schema.additionalProperties
|
|
654
|
+
const indexSignature = true === schema.additionalProperties ? "\n [key: string]: any;" : "";
|
|
617
655
|
return `export type ${typeName} = {
|
|
618
656
|
${properties};${indexSignature}
|
|
619
657
|
};
|
|
@@ -626,10 +664,14 @@ const index = async (openApiUrl, baseUrl) => {
|
|
|
626
664
|
try {
|
|
627
665
|
const { data: openApi } = await axios$1.get(openApiUrl, { headers: basicAuthHeader });
|
|
628
666
|
const schemas = openApi.components?.schemas;
|
|
629
|
-
if (!schemas)
|
|
667
|
+
if (!schemas) {
|
|
668
|
+
throw new Error("No schemas found in OpenAPI document");
|
|
669
|
+
}
|
|
630
670
|
const types = generateTypes(schemas);
|
|
631
671
|
const { paths } = openApi;
|
|
632
|
-
if (!paths)
|
|
672
|
+
if (!paths) {
|
|
673
|
+
throw new Error("No paths found in OpenAPI document");
|
|
674
|
+
}
|
|
633
675
|
const code = generateFunctions(paths, baseUrl);
|
|
634
676
|
return { types, code };
|
|
635
677
|
} catch (error) {
|
|
@@ -663,7 +705,7 @@ function formatAPIErrorMessage(err) {
|
|
|
663
705
|
case 500:
|
|
664
706
|
return "An internal server error occurred. Please try again later.";
|
|
665
707
|
}
|
|
666
|
-
if (data.detail && typeof data.detail
|
|
708
|
+
if (data.detail && "string" === typeof data.detail) {
|
|
667
709
|
return data.detail;
|
|
668
710
|
}
|
|
669
711
|
if (data.message) {
|
|
@@ -686,7 +728,9 @@ class DataRequest {
|
|
|
686
728
|
this.itemID = "";
|
|
687
729
|
}
|
|
688
730
|
async post(item) {
|
|
689
|
-
if (!this.data_table)
|
|
731
|
+
if (!this.data_table) {
|
|
732
|
+
throw new Error("Data table not set");
|
|
733
|
+
}
|
|
690
734
|
const { data } = await axios.post(`/data/${this.data_table}`, item);
|
|
691
735
|
return data;
|
|
692
736
|
}
|
|
@@ -695,8 +739,10 @@ class DataRequest {
|
|
|
695
739
|
return this;
|
|
696
740
|
}
|
|
697
741
|
async get() {
|
|
698
|
-
if (!this.data_table)
|
|
699
|
-
|
|
742
|
+
if (!this.data_table) {
|
|
743
|
+
throw new Error("Data table not set");
|
|
744
|
+
}
|
|
745
|
+
const filterStr = 0 < Object.keys(this._filter).length ? `?filter={${Object.entries(this._filter).map(([k, v]) => `${k}:${v}`).join(",")}}` : "";
|
|
700
746
|
const url = `/data/${this.data_table}${this.itemID ? `/${this.itemID}` : ""}${filterStr}`;
|
|
701
747
|
try {
|
|
702
748
|
const { data } = await axios.get(url);
|
|
@@ -712,7 +758,9 @@ class DataRequest {
|
|
|
712
758
|
return this;
|
|
713
759
|
}
|
|
714
760
|
async delete() {
|
|
715
|
-
if (!this.data_table)
|
|
761
|
+
if (!this.data_table) {
|
|
762
|
+
throw new Error("Data table not set");
|
|
763
|
+
}
|
|
716
764
|
const { data } = await axios.delete(
|
|
717
765
|
`/data/${this.data_table}/${this.itemID}`
|
|
718
766
|
);
|
|
@@ -720,8 +768,12 @@ class DataRequest {
|
|
|
720
768
|
}
|
|
721
769
|
async put(updatedItem) {
|
|
722
770
|
const { data_table, itemID } = this;
|
|
723
|
-
if (!data_table)
|
|
724
|
-
|
|
771
|
+
if (!data_table) {
|
|
772
|
+
throw new Error("Data table not set");
|
|
773
|
+
}
|
|
774
|
+
if (!itemID) {
|
|
775
|
+
throw new Error("Item ID not set");
|
|
776
|
+
}
|
|
725
777
|
const { data } = await axios.put(
|
|
726
778
|
`/data/${data_table}/${itemID}`,
|
|
727
779
|
updatedItem
|
|
@@ -839,10 +891,14 @@ class Bagel {
|
|
|
839
891
|
async get(endpoint, query) {
|
|
840
892
|
this._setAuthorization();
|
|
841
893
|
endpoint = this._endpointCleaner(endpoint);
|
|
842
|
-
if (/undefined|null/.test(endpoint))
|
|
894
|
+
if (/undefined|null/.test(endpoint)) {
|
|
895
|
+
throw new Error(`Invalid endpoint: ${endpoint}`);
|
|
896
|
+
}
|
|
843
897
|
if (query) {
|
|
844
898
|
const queryParams = Object.entries(query).filter(([_, value]) => !!value).map(([key, value]) => `${key}=${value}`).join("&");
|
|
845
|
-
if (queryParams)
|
|
899
|
+
if (queryParams) {
|
|
900
|
+
endpoint = `${endpoint}?${queryParams}`;
|
|
901
|
+
}
|
|
846
902
|
}
|
|
847
903
|
const url = `/${endpoint}`;
|
|
848
904
|
return axios.get(url).then(({ data }) => data).catch((err) => {
|
|
@@ -892,7 +948,9 @@ class Bagel {
|
|
|
892
948
|
const formData = new FormData();
|
|
893
949
|
formData.append("file", file);
|
|
894
950
|
let url = "/static_files/upload";
|
|
895
|
-
if (options?.topic)
|
|
951
|
+
if (options?.topic) {
|
|
952
|
+
url = `/static_files/upload?topic=${options.topic}`;
|
|
953
|
+
}
|
|
896
954
|
const { data } = await axios.post(url, formData, {
|
|
897
955
|
headers: {
|
|
898
956
|
"Content-Type": "multipart/form-data"
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -42,7 +42,7 @@ class DataRequest<T extends Tables = Tables> {
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
async post(item: { [key: string]: any }): Promise<{ [key: string]: any }> {
|
|
45
|
-
if (!this.data_table) throw new Error('Data table not set')
|
|
45
|
+
if (!this.data_table) {throw new Error('Data table not set')}
|
|
46
46
|
const { data } = await axios.post(`/data/${this.data_table}`, item)
|
|
47
47
|
return data
|
|
48
48
|
}
|
|
@@ -55,8 +55,8 @@ class DataRequest<T extends Tables = Tables> {
|
|
|
55
55
|
async get(): Promise<
|
|
56
56
|
TableToTypeMapping[T] | TableToTypeMapping[T][] | undefined
|
|
57
57
|
> {
|
|
58
|
-
if (!this.data_table) throw new Error('Data table not set')
|
|
59
|
-
const filterStr = Object.keys(this._filter).length
|
|
58
|
+
if (!this.data_table) {throw new Error('Data table not set')}
|
|
59
|
+
const filterStr = 0 < Object.keys(this._filter).length
|
|
60
60
|
? `?filter={${Object.entries(this._filter)
|
|
61
61
|
.map(([k, v]) => `${k}:${v}`)
|
|
62
62
|
.join(',')}}`
|
|
@@ -80,7 +80,7 @@ class DataRequest<T extends Tables = Tables> {
|
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
async delete(): Promise<TableToTypeMapping[T][]> {
|
|
83
|
-
if (!this.data_table) throw new Error('Data table not set')
|
|
83
|
+
if (!this.data_table) {throw new Error('Data table not set')}
|
|
84
84
|
const { data } = await axios.delete(
|
|
85
85
|
`/data/${this.data_table}/${this.itemID}`,
|
|
86
86
|
)
|
|
@@ -89,8 +89,8 @@ class DataRequest<T extends Tables = Tables> {
|
|
|
89
89
|
|
|
90
90
|
async put(updatedItem: { [key: string]: any }): Promise<{ [key: string]: any }> {
|
|
91
91
|
const { data_table, itemID } = this
|
|
92
|
-
if (!data_table) throw new Error('Data table not set')
|
|
93
|
-
if (!itemID) throw new Error('Item ID not set')
|
|
92
|
+
if (!data_table) {throw new Error('Data table not set')}
|
|
93
|
+
if (!itemID) {throw new Error('Item ID not set')}
|
|
94
94
|
const { data } = await axios.put(
|
|
95
95
|
`/data/${data_table}/${itemID}`,
|
|
96
96
|
updatedItem,
|
|
@@ -237,14 +237,14 @@ export class Bagel {
|
|
|
237
237
|
): Promise<T> {
|
|
238
238
|
this._setAuthorization()
|
|
239
239
|
endpoint = this._endpointCleaner(endpoint)
|
|
240
|
-
if ((/undefined|null/).test(endpoint)) throw new Error(`Invalid endpoint: ${endpoint}`)
|
|
240
|
+
if ((/undefined|null/).test(endpoint)) {throw new Error(`Invalid endpoint: ${endpoint}`)}
|
|
241
241
|
|
|
242
242
|
if (query) {
|
|
243
243
|
const queryParams = Object.entries(query)
|
|
244
244
|
.filter(([_, value]) => !!value)
|
|
245
245
|
.map(([key, value]) => `${key}=${value}`)
|
|
246
246
|
.join('&')
|
|
247
|
-
if (queryParams) endpoint = `${endpoint}?${queryParams}`
|
|
247
|
+
if (queryParams) {endpoint = `${endpoint}?${queryParams}`}
|
|
248
248
|
}
|
|
249
249
|
const url = `/${endpoint}`
|
|
250
250
|
return axios
|
|
@@ -321,7 +321,7 @@ export class Bagel {
|
|
|
321
321
|
const formData = new FormData()
|
|
322
322
|
formData.append('file', file)
|
|
323
323
|
let url = '/static_files/upload'
|
|
324
|
-
if (options?.topic) url = `/static_files/upload?topic=${options.topic}`
|
|
324
|
+
if (options?.topic) {url = `/static_files/upload?topic=${options.topic}`}
|
|
325
325
|
// get an indication of the progress
|
|
326
326
|
const { data } = await axios.post<T>(url, formData, {
|
|
327
327
|
headers: {
|
|
@@ -75,8 +75,8 @@ function collectTypeForImportStatement(typeName: string): void {
|
|
|
75
75
|
const isPrimitive = primitiveTypes.includes(typeName)
|
|
76
76
|
typeName = formatType(typeName)
|
|
77
77
|
|
|
78
|
-
if (!typeName || isPrimitive) return
|
|
79
|
-
if (!allTypes.includes(typeName)) allTypes.push(typeName)
|
|
78
|
+
if (!typeName || isPrimitive) {return}
|
|
79
|
+
if (!allTypes.includes(typeName)) {allTypes.push(typeName)}
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
/**
|
|
@@ -100,7 +100,7 @@ function getResponseType(response: OpenAPIResponse | ReferenceObject): string |
|
|
|
100
100
|
return undefined // TODO: handle references properly
|
|
101
101
|
}
|
|
102
102
|
const mediaTypeObject = response.content?.['application/json']
|
|
103
|
-
if (!mediaTypeObject?.schema) return undefined
|
|
103
|
+
if (!mediaTypeObject?.schema) {return undefined}
|
|
104
104
|
return schemaToTypeWithCollection(mediaTypeObject.schema)
|
|
105
105
|
}
|
|
106
106
|
|
|
@@ -110,13 +110,13 @@ function getResponseType(response: OpenAPIResponse | ReferenceObject): string |
|
|
|
110
110
|
* @returns The TypeScript response type string
|
|
111
111
|
*/
|
|
112
112
|
function generateResponseType(responses?: OpenAPIResponses): string {
|
|
113
|
-
if (!responses) return ''
|
|
113
|
+
if (!responses) {return ''}
|
|
114
114
|
|
|
115
115
|
const types: string[] = []
|
|
116
116
|
for (const [statusCode, response] of Object.entries(responses)) {
|
|
117
117
|
if (statusCode.startsWith('2')) {
|
|
118
118
|
const responseType = getResponseType(response)
|
|
119
|
-
if (responseType &&
|
|
119
|
+
if (responseType && 'any' !== responseType) {
|
|
120
120
|
types.push(responseType)
|
|
121
121
|
}
|
|
122
122
|
}
|
|
@@ -142,7 +142,7 @@ function getParamsFromPath(path: string): string[] | undefined {
|
|
|
142
142
|
*/
|
|
143
143
|
function formatPathWithParams(path: string): string {
|
|
144
144
|
const params = getParamsFromPath(path)
|
|
145
|
-
if (!params) return `'${path}'`
|
|
145
|
+
if (!params) {return `'${path}'`}
|
|
146
146
|
|
|
147
147
|
return `\`${path.replace(/\{([^}]+)\}/g, (_, paramName) => `\${${toCamelCase(paramName)}}`)}\``
|
|
148
148
|
}
|
|
@@ -160,7 +160,7 @@ function generateRequestBody(requestBody?: OpenAPIOperation['requestBody']): {
|
|
|
160
160
|
// return { requestBodyParam: '', requestBodyPayload: '' }
|
|
161
161
|
|
|
162
162
|
const content = dereference(requestBody)?.content
|
|
163
|
-
if (!content || Object.keys(content).length
|
|
163
|
+
if (!content || 0 === Object.keys(content).length) {
|
|
164
164
|
return { requestBodyParam: '', requestBodyPayload: '' }
|
|
165
165
|
}
|
|
166
166
|
|
|
@@ -217,7 +217,7 @@ function generateFunctionParameters(
|
|
|
217
217
|
params?: OpenAPIOperation['parameters'],
|
|
218
218
|
isFileUpload = false
|
|
219
219
|
): { params?: string, config?: { params?: string } } {
|
|
220
|
-
if (!params?.length) return {}
|
|
220
|
+
if (!params?.length) {return {}}
|
|
221
221
|
|
|
222
222
|
// Special handling for file uploads
|
|
223
223
|
if (isFileUpload) {
|
|
@@ -241,7 +241,7 @@ function generateFunctionParameters(
|
|
|
241
241
|
const paramName = param.name
|
|
242
242
|
const varName = toCamelCaseSafe(param.name)
|
|
243
243
|
|
|
244
|
-
if (
|
|
244
|
+
if ('path' === param.in || 'query' === param.in || 'header' === param.in) {
|
|
245
245
|
functionParams.push(
|
|
246
246
|
formatVarType({
|
|
247
247
|
varName,
|
|
@@ -252,7 +252,7 @@ function generateFunctionParameters(
|
|
|
252
252
|
)
|
|
253
253
|
}
|
|
254
254
|
|
|
255
|
-
if (
|
|
255
|
+
if ('query' === param.in || 'header' === param.in) {
|
|
256
256
|
queryParams.push(
|
|
257
257
|
paramName === varName ? paramName : `'${paramName}': ${varName}`
|
|
258
258
|
)
|
|
@@ -290,7 +290,7 @@ function parseParameter(paramStr: string): {
|
|
|
290
290
|
const type = typeMatch ? typeMatch[1].trim() : 'any'
|
|
291
291
|
|
|
292
292
|
// Extract default value if exists
|
|
293
|
-
const defaultMatch = trimmed.match(
|
|
293
|
+
const defaultMatch = trimmed.match(/[=](.+)$/)
|
|
294
294
|
const defaultValue = defaultMatch ? defaultMatch[1].trim() : undefined
|
|
295
295
|
|
|
296
296
|
return { name, type, defaultValue, isOptional }
|
|
@@ -316,7 +316,7 @@ function combineAllParams(
|
|
|
316
316
|
allParamsArray.push(requestBodyParam.trim())
|
|
317
317
|
}
|
|
318
318
|
|
|
319
|
-
if (allParamsArray.length
|
|
319
|
+
if (0 === allParamsArray.length) {
|
|
320
320
|
return ''
|
|
321
321
|
}
|
|
322
322
|
|
|
@@ -357,14 +357,14 @@ function generateAxiosFunction(
|
|
|
357
357
|
parameters: { config?: { params?: string } },
|
|
358
358
|
requestBodyPayload: string
|
|
359
359
|
): string {
|
|
360
|
-
if (
|
|
360
|
+
if ('undefined' === allParams) {allParams = ''}
|
|
361
361
|
|
|
362
362
|
let axiosFunction = `async (${allParams})${responseTypeStr} => {`
|
|
363
363
|
const paramStr = parameters.config?.params
|
|
364
364
|
? `params: {${parameters.config.params}}`
|
|
365
365
|
: ''
|
|
366
366
|
|
|
367
|
-
if (
|
|
367
|
+
if ('formData' === requestBodyPayload) {
|
|
368
368
|
// Check if this is a file upload with specific file parameter
|
|
369
369
|
if (allParams.includes('file: File')) {
|
|
370
370
|
axiosFunction += `
|
|
@@ -415,7 +415,7 @@ function buildJSDocComment(operation: OpenAPIOperation, method: string, path: st
|
|
|
415
415
|
// Add description if available
|
|
416
416
|
if (operation.description) {
|
|
417
417
|
// If there's already a summary, add a line break
|
|
418
|
-
if (operation.summary) functionComment += ` *\n`
|
|
418
|
+
if (operation.summary) {functionComment += ` *\n`}
|
|
419
419
|
|
|
420
420
|
// Split description into lines and add each line with proper JSDoc formatting
|
|
421
421
|
const descriptionLines = operation.description.split('\n')
|
|
@@ -443,7 +443,7 @@ function generateFunctionForOperation(
|
|
|
443
443
|
path: string,
|
|
444
444
|
operation: OpenAPIOperation
|
|
445
445
|
): string {
|
|
446
|
-
if (!operation) return ''
|
|
446
|
+
if (!operation) {return ''}
|
|
447
447
|
|
|
448
448
|
// Check if this is a file upload
|
|
449
449
|
const multiPartSchema = dereference(operation.requestBody)?.content?.[
|
|
@@ -500,7 +500,7 @@ function hasConflict(path: string, method: string): boolean {
|
|
|
500
500
|
)
|
|
501
501
|
|
|
502
502
|
pathOperations.push({ path: cleanPathName, method })
|
|
503
|
-
return matchingPaths.length
|
|
503
|
+
return 0 < matchingPaths.length
|
|
504
504
|
}
|
|
505
505
|
|
|
506
506
|
/**
|
|
@@ -585,14 +585,14 @@ export function generateFunctions(paths: OpenAPIPaths, baseUrl: string): string
|
|
|
585
585
|
|
|
586
586
|
splitPath.reduce((acc, key: string, index: number, array: string[]) => {
|
|
587
587
|
const objFuncKey = toCamelCaseSafe(key)
|
|
588
|
-
if (!objFuncKey) return acc
|
|
588
|
+
if (!objFuncKey) {return acc}
|
|
589
589
|
|
|
590
590
|
const methods = Object.keys(operation) as Array<keyof OpenAPIPath>
|
|
591
591
|
|
|
592
592
|
if (
|
|
593
593
|
index === array.length - 1
|
|
594
|
-
&& methods.length
|
|
595
|
-
&& allPathsClean.filter(p => p === cleanPath(path)).length
|
|
594
|
+
&& 1 === methods.length
|
|
595
|
+
&& 1 === allPathsClean.filter(p => p === cleanPath(path)).length
|
|
596
596
|
) {
|
|
597
597
|
// Single method endpoint with unique path
|
|
598
598
|
const method = methods[0]
|
|
@@ -601,7 +601,7 @@ export function generateFunctions(paths: OpenAPIPaths, baseUrl: string): string
|
|
|
601
601
|
} else if (index === array.length - 1) {
|
|
602
602
|
// Multiple methods endpoint or path with conflicts
|
|
603
603
|
acc[objFuncKey] = handlePathSegment(path, operation, acc[objFuncKey])
|
|
604
|
-
} else if (!acc[objFuncKey] || typeof acc[objFuncKey]
|
|
604
|
+
} else if (!acc[objFuncKey] || 'object' !== typeof acc[objFuncKey]) {
|
|
605
605
|
// Intermediate path segment
|
|
606
606
|
acc[objFuncKey] = {}
|
|
607
607
|
}
|
|
@@ -13,11 +13,11 @@ export default async (openApiUrl: string, baseUrl: string): Promise<OpenAPIRespo
|
|
|
13
13
|
try {
|
|
14
14
|
const { data: openApi } = await axios.get<OpenAPIObject>(openApiUrl, { headers: basicAuthHeader })
|
|
15
15
|
const schemas = openApi.components?.schemas
|
|
16
|
-
if (!schemas) throw new Error('No schemas found in OpenAPI document')
|
|
16
|
+
if (!schemas) {throw new Error('No schemas found in OpenAPI document')}
|
|
17
17
|
const types = generateTypes(schemas)
|
|
18
18
|
// Generate Functions
|
|
19
19
|
const { paths } = openApi
|
|
20
|
-
if (!paths) throw new Error('No paths found in OpenAPI document')
|
|
20
|
+
if (!paths) {throw new Error('No paths found in OpenAPI document')}
|
|
21
21
|
const code = generateFunctions(paths, baseUrl) // TODO baseURL should not be set here, but should be instatiated in runtime somehow
|
|
22
22
|
return { types, code }
|
|
23
23
|
} catch (error: any) {
|