@bagelink/sdk 0.0.1121 → 0.0.1123

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 CHANGED
@@ -14,23 +14,19 @@ function formatType(typeName) {
14
14
  }
15
15
  function resolveReference(ref) {
16
16
  const t = ref.split("/").pop();
17
- if (!t)
18
- return "any";
17
+ if (!t) return "any";
19
18
  return formatType(t);
20
19
  }
21
20
  function schemaToType(schema) {
22
- if (!schema)
23
- return "any";
21
+ if (!schema) return "any";
24
22
  if (schema.anyOf) {
25
23
  let _t = schema.anyOf.map((s) => schemaToType(s)).filter((p) => p !== "any").join(" | ");
26
- if (_t === "" || _t === "null")
27
- _t = "any";
24
+ if (_t === "" || _t === "null") _t = "any";
28
25
  return _t;
29
26
  }
30
27
  if (schema.allOf)
31
28
  return schema.allOf.map((s) => schemaToType(s)).filter((p) => p !== "any").join(" & ");
32
- if (schema.$ref)
33
- return resolveReference(schema.$ref);
29
+ if (schema.$ref) return resolveReference(schema.$ref);
34
30
  switch (schema.type) {
35
31
  case "object":
36
32
  return "{ [key: string]: any }";
@@ -48,7 +44,7 @@ function schemaToType(schema) {
48
44
  return "undefined";
49
45
  case "null":
50
46
  return "null";
51
- case void 0:
47
+ case undefined:
52
48
  return "any";
53
49
  default:
54
50
  console.log("Unknown type", schema.type);
@@ -60,10 +56,16 @@ function isOptional(schema) {
60
56
  const splitType = type.split(/\s+\|\s+/);
61
57
  const includesNull = splitType.includes("null");
62
58
  const includesUndefined = splitType.includes("undefined");
63
- return includesNull || includesUndefined || schema.default !== void 0;
59
+ return includesNull || includesUndefined || schema.default !== undefined;
64
60
  }
65
61
  const cleanOptionals = (str) => str.split(" | ").filter((t) => t !== "null" && t !== "undefined").join(" | ");
66
- function formatVarType(varName, schema, required = false, defaultValue) {
62
+ function formatVarType({
63
+ varName,
64
+ schema,
65
+ required = false,
66
+ defaultValue
67
+ }) {
68
+ if (varName === "personId") console.log({ varName, schema, required, defaultValue });
67
69
  let type = schemaToType(schema);
68
70
  type = cleanOptionals(type);
69
71
  let defaultStr = "";
@@ -74,9 +76,8 @@ function formatVarType(varName, schema, required = false, defaultValue) {
74
76
  defaultStr = ` = ${defaultValue}`;
75
77
  }
76
78
  }
77
- let optionalStr = required || isOptional(schema) ? "?" : "";
78
- if (defaultStr)
79
- optionalStr = "";
79
+ let optionalStr = !required && isOptional(schema) ? "?" : "";
80
+ if (defaultStr) optionalStr = "";
80
81
  return `${varName}${optionalStr}: ${type}${defaultStr}`;
81
82
  }
82
83
  function cleanPath(path) {
@@ -84,35 +85,39 @@ function cleanPath(path) {
84
85
  }
85
86
 
86
87
  const allTypes = [];
87
- const primitiveTypes = ["string", "number", "boolean", "null", "void", "any", "Record<string, any>", "undefined", "{ [key: string]: any }"];
88
+ const primitiveTypes = [
89
+ "string",
90
+ "number",
91
+ "boolean",
92
+ "null",
93
+ "void",
94
+ "any",
95
+ "Record<string, any>",
96
+ "undefined",
97
+ "{ [key: string]: any }"
98
+ ];
88
99
  function collectTypeForImportStatement(typeName) {
89
100
  typeName = typeName.trim().replace("[]", "");
90
101
  if (typeName.includes("|")) {
91
- typeName.split("|").forEach(
92
- (singleType) => {
93
- collectTypeForImportStatement(singleType);
94
- }
95
- );
102
+ typeName.split("|").forEach((singleType) => {
103
+ collectTypeForImportStatement(singleType);
104
+ });
96
105
  return;
97
106
  }
98
107
  const isPrimitive = primitiveTypes.includes(typeName);
99
108
  typeName = formatType(typeName);
100
- if (!typeName || isPrimitive)
101
- return;
102
- if (!allTypes.includes(typeName))
103
- allTypes.push(typeName);
109
+ if (!typeName || isPrimitive) return;
110
+ if (!allTypes.includes(typeName)) allTypes.push(typeName);
104
111
  }
105
112
  function getResponseType(response) {
106
113
  const mediaTypeObject = response.content?.["application/json"];
107
- if (!mediaTypeObject || !mediaTypeObject.schema)
108
- return;
114
+ if (!mediaTypeObject || !mediaTypeObject.schema) return;
109
115
  const responseType = schemaToType(mediaTypeObject.schema);
110
116
  collectTypeForImportStatement(responseType);
111
117
  return responseType;
112
118
  }
113
119
  function generateResponseType(responses) {
114
- if (!responses)
115
- return "";
120
+ if (!responses) return "";
116
121
  const types = [];
117
122
  for (const [statusCode, response] of Object.entries(responses)) {
118
123
  if (statusCode.startsWith("2")) {
@@ -125,8 +130,7 @@ function generateResponseType(responses) {
125
130
  return types.join(" | ");
126
131
  }
127
132
  function generateAxiosFunction(method, formattedPath, allParams, responseTypeStr, parameters, requestBodyPayload) {
128
- if (allParams === "undefined")
129
- allParams = "";
133
+ if (allParams === "undefined") allParams = "";
130
134
  let axiosFunction = `async (${allParams})${responseTypeStr} => {`;
131
135
  if (requestBodyPayload === "formData") {
132
136
  const paramStr = parameters?.config?.params ? `params: {${parameters.config.params}}` : "";
@@ -175,21 +179,23 @@ function generateRequestBody(requestBody) {
175
179
  const requestBodyType = schemaToType(bodySchema);
176
180
  collectTypeForImportStatement(requestBodyType);
177
181
  const requestBodyPayload = toCamelCase(bodySchema.title) || toCamelCase(requestBodyType) || "requestBody";
178
- const requestBodyParam = formatVarType(requestBodyPayload, bodySchema, bodySchema.default);
182
+ const requestBodyParam = formatVarType({
183
+ varName: requestBodyPayload,
184
+ schema: bodySchema,
185
+ defaultValue: bodySchema.default
186
+ });
179
187
  return { requestBodyParam, requestBodyPayload };
180
188
  }
181
189
  function combineAllParams(parameters, requestBodyParam) {
182
190
  let allParamsArray = [];
183
191
  if (parameters && parameters.params)
184
192
  allParamsArray = parameters.params.split(",").map((p) => p.trim());
185
- if (requestBodyParam)
186
- allParamsArray.push(requestBodyParam.trim());
193
+ if (requestBodyParam) allParamsArray.push(requestBodyParam.trim());
187
194
  allParamsArray = allParamsArray.filter((p) => p).sort((a, b) => (a.includes("?") ? 1 : -1) - (b.includes("?") ? 1 : -1));
188
195
  return allParamsArray.join(", ");
189
196
  }
190
197
  function generateFunctionParameters(params, isFileUpload = false) {
191
- if (!params?.length)
192
- return {};
198
+ if (!params?.length) return {};
193
199
  if (isFileUpload) {
194
200
  return {
195
201
  config: {
@@ -207,10 +213,19 @@ function generateFunctionParameters(params, isFileUpload = false) {
207
213
  const paramName = param.name;
208
214
  const varName = toCamelCase(param.name);
209
215
  if (param.in === "path" || param.in === "query" || param.in === "header") {
210
- functionParams.push(formatVarType(varName, param.schema, param.required, param.schema.default));
216
+ functionParams.push(
217
+ formatVarType({
218
+ varName,
219
+ schema: param.schema,
220
+ required: param.required,
221
+ defaultValue: param.schema.default
222
+ })
223
+ );
211
224
  }
212
225
  if (param.in === "query" || param.in === "header") {
213
- paramList.push(paramName === varName ? paramName : `'${paramName}': ${varName}`);
226
+ paramList.push(
227
+ paramName === varName ? paramName : `'${paramName}': ${varName}`
228
+ );
214
229
  }
215
230
  }
216
231
  return {
@@ -219,11 +234,15 @@ function generateFunctionParameters(params, isFileUpload = false) {
219
234
  };
220
235
  }
221
236
  function generateFunctionForOperation(method, path, operation) {
222
- if (!operation)
223
- return "";
237
+ if (!operation) return "";
224
238
  const isFileUpload = operation.requestBody?.content["multipart/form-data"]?.schema?.$ref?.includes("Body_upload_files");
225
- const parameters = generateFunctionParameters(operation.parameters, isFileUpload);
226
- const { requestBodyParam, requestBodyPayload } = generateRequestBody(operation.requestBody);
239
+ const parameters = generateFunctionParameters(
240
+ operation.parameters,
241
+ isFileUpload
242
+ );
243
+ const { requestBodyParam, requestBodyPayload } = generateRequestBody(
244
+ operation.requestBody
245
+ );
227
246
  const allParams = isFileUpload ? "file: File, options?: UploadOptions & { dirPath?: string, tags?: string[] }" : combineAllParams(parameters, requestBodyParam);
228
247
  const responseType = generateResponseType(operation.responses);
229
248
  const responseTypeStr = responseType ? `: Promise<AxiosResponse<${responseType}>>` : "";
@@ -241,13 +260,13 @@ function fileTemplate(tsString, typeForImport, baseURL) {
241
260
  const templateCode = `import ax from 'axios';
242
261
  import type { AxiosResponse } from 'axios';
243
262
  import type {${typeForImport.join(", ")}} from './types.d';
244
-
263
+
245
264
  interface UploadOptions {
246
265
  onUploadProgress?: (progressEvent: any) => void
247
266
  dirPath?: string
248
267
  tags?: string[]
249
268
  }
250
-
269
+
251
270
  export const axios = ax.create({baseURL:${baseURL}});
252
271
  ${tsString}`;
253
272
  const doubleQuoteRegex = /"([^"]+)":/g;
@@ -257,13 +276,19 @@ const functionsInventory = {};
257
276
  const pathOperations = [];
258
277
  function hasConflict(path, method) {
259
278
  const cleanPathName = path.split("/").filter((p) => p && !/\{|\}/.test(p)).join("/");
260
- const matchingPaths = pathOperations.filter((p) => p.path === cleanPathName && p.method === method);
279
+ const matchingPaths = pathOperations.filter(
280
+ (p) => p.path === cleanPathName && p.method === method
281
+ );
261
282
  pathOperations.push({ path: cleanPathName, method });
262
283
  return matchingPaths.length > 0;
263
284
  }
264
285
  function createFunctionPlaceholder(path, method, operation) {
265
286
  const funcID = generateRandomString();
266
- functionsInventory[funcID] = generateFunctionForOperation(method, path, operation);
287
+ functionsInventory[funcID] = generateFunctionForOperation(
288
+ method,
289
+ path,
290
+ operation
291
+ );
267
292
  return funcID;
268
293
  }
269
294
  function handlePathSegment(path, operation, existingObj = {}) {
@@ -275,7 +300,11 @@ function handlePathSegment(path, operation, existingObj = {}) {
275
300
  const params = getParamsFromPath(path);
276
301
  functionName += params ? `By${toPascalCase(params.pop() || "")}` : "All";
277
302
  }
278
- obj[functionName] = createFunctionPlaceholder(path, method, operation[method]);
303
+ obj[functionName] = createFunctionPlaceholder(
304
+ path,
305
+ method,
306
+ operation[method]
307
+ );
279
308
  }
280
309
  return { ...obj, ...existingObj };
281
310
  }
@@ -287,8 +316,7 @@ function generateFunctions(paths, baseUrl) {
287
316
  const splitPath = path.split("/").filter((p) => p && !/\{|\}/.test(p));
288
317
  splitPath.reduce((acc, key, index, array) => {
289
318
  const objFuncKey = toCamelCase(key);
290
- if (!objFuncKey)
291
- return acc;
319
+ if (!objFuncKey) return acc;
292
320
  const methods = Object.keys(operation);
293
321
  if (index === array.length - 1 && methods.length === 1 && allPathsClean.filter((p) => p === cleanPath(path)).length === 1) {
294
322
  const method = methods[0];
@@ -303,7 +331,7 @@ function generateFunctions(paths, baseUrl) {
303
331
  }, body);
304
332
  }
305
333
  for (const [parent, object] of Object.entries(body)) {
306
- tsString += `export const ${parent} = ${JSON.stringify(object, void 0, 2)};
334
+ tsString += `export const ${parent} = ${JSON.stringify(object, undefined, 2)};
307
335
  `;
308
336
  }
309
337
  Object.entries(functionsInventory).forEach(([key, value]) => {
@@ -320,10 +348,9 @@ function generateTypes(schemas) {
320
348
  return `export type ${typeName} = ${schema.enum.map((item) => `'${item}'`).join(" | ")};
321
349
  `;
322
350
  }
323
- if (!schema.properties)
324
- return "";
351
+ if (!schema.properties) return "";
325
352
  const properties = Object.entries(schema.properties).map(([key, value]) => {
326
- const varType = formatVarType(key, value);
353
+ const varType = formatVarType({ varName: key, schema: value });
327
354
  return ` ${varType}`;
328
355
  }).join(";\n ");
329
356
  return `export type ${typeName} = {
@@ -338,12 +365,10 @@ const index = async (openApiUrl, baseUrl) => {
338
365
  try {
339
366
  const { data: openApi } = await axios__default.get(openApiUrl, { headers: basicAuthHeader });
340
367
  const schemas = openApi.components?.schemas;
341
- if (!schemas)
342
- throw new Error("No schemas found in OpenAPI document");
368
+ if (!schemas) throw new Error("No schemas found in OpenAPI document");
343
369
  const types = generateTypes(schemas);
344
370
  const { paths } = openApi;
345
- if (!paths)
346
- throw new Error("No paths found in OpenAPI document");
371
+ if (!paths) throw new Error("No paths found in OpenAPI document");
347
372
  const code = generateFunctions(paths, baseUrl);
348
373
  return { types, code };
349
374
  } catch (error) {
@@ -351,28 +376,21 @@ const index = async (openApiUrl, baseUrl) => {
351
376
  }
352
377
  };
353
378
 
354
- var __defProp = Object.defineProperty;
355
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
356
- var __publicField = (obj, key, value) => {
357
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
358
- return value;
359
- };
360
379
  const axios = axios__default.create({
361
380
  withCredentials: true
362
381
  });
363
382
  class DataRequest {
383
+ data_table;
384
+ bagel;
385
+ itemID;
386
+ _filter = {};
364
387
  constructor(table, bagel) {
365
- __publicField(this, "data_table");
366
- __publicField(this, "bagel");
367
- __publicField(this, "itemID");
368
- __publicField(this, "_filter", {});
369
388
  this.data_table = table;
370
389
  this.bagel = bagel;
371
390
  this.itemID = "";
372
391
  }
373
392
  async post(item) {
374
- if (!this.data_table)
375
- throw new Error("Data table not set");
393
+ if (!this.data_table) throw new Error("Data table not set");
376
394
  const { data } = await axios.post(`/data/${this.data_table}`, item);
377
395
  return data;
378
396
  }
@@ -381,8 +399,7 @@ class DataRequest {
381
399
  return this;
382
400
  }
383
401
  async get() {
384
- if (!this.data_table)
385
- throw new Error("Data table not set");
402
+ if (!this.data_table) throw new Error("Data table not set");
386
403
  const filterStr = Object.keys(this._filter).length > 0 ? `?filter={${Object.entries(this._filter).map(([k, v]) => `${k}:${v}`).join(",")}}` : "";
387
404
  const url = `/data/${this.data_table}${this.itemID ? `/${this.itemID}` : ""}${filterStr}`;
388
405
  try {
@@ -391,7 +408,7 @@ class DataRequest {
391
408
  } catch (err) {
392
409
  console.log(err);
393
410
  this.bagel.onError?.(err);
394
- return void 0;
411
+ return undefined;
395
412
  }
396
413
  }
397
414
  item(id) {
@@ -399,8 +416,7 @@ class DataRequest {
399
416
  return this;
400
417
  }
401
418
  async delete() {
402
- if (!this.data_table)
403
- throw new Error("Data table not set");
419
+ if (!this.data_table) throw new Error("Data table not set");
404
420
  const { data } = await axios.delete(
405
421
  `/data/${this.data_table}/${this.itemID}`
406
422
  );
@@ -408,10 +424,8 @@ class DataRequest {
408
424
  }
409
425
  async put(updatedItem) {
410
426
  const { data_table, itemID } = this;
411
- if (!data_table)
412
- throw new Error("Data table not set");
413
- if (!itemID)
414
- throw new Error("Item ID not set");
427
+ if (!data_table) throw new Error("Data table not set");
428
+ if (!itemID) throw new Error("Item ID not set");
415
429
  const { data } = await axios.put(
416
430
  `/data/${data_table}/${itemID}`,
417
431
  updatedItem
@@ -429,9 +443,9 @@ function responses(key) {
429
443
  class BagelAuth {
430
444
  constructor(bagel) {
431
445
  this.bagel = bagel;
432
- __publicField(this, "user");
433
446
  this.bagel = bagel;
434
447
  }
448
+ user = undefined;
435
449
  async validateUser() {
436
450
  try {
437
451
  const { data: usr } = await axios.get("/users/me", {
@@ -479,7 +493,7 @@ class BagelAuth {
479
493
  this.bagel.onError?.(err);
480
494
  console.log(err);
481
495
  }
482
- this.user = void 0;
496
+ this.user = undefined;
483
497
  }
484
498
  async acceptInvite(token, user) {
485
499
  await axios.post(`/auth/accept-invite/${token}`, user);
@@ -497,12 +511,10 @@ class BagelAuth {
497
511
  }
498
512
  }
499
513
  class Bagel {
514
+ host;
515
+ fileBaseUrl;
516
+ onError;
500
517
  constructor({ host, fileBaseUrl, onError }) {
501
- __publicField(this, "host");
502
- __publicField(this, "fileBaseUrl");
503
- __publicField(this, "onError");
504
- __publicField(this, "read_table");
505
- __publicField(this, "auth", new BagelAuth(this));
506
518
  this.host = host?.replace(/\/$/, "");
507
519
  this.fileBaseUrl = fileBaseUrl?.replace(/\/$/, "");
508
520
  if (!this.host) {
@@ -511,9 +523,11 @@ class Bagel {
511
523
  axios.defaults.baseURL = this.host;
512
524
  this.onError = onError;
513
525
  }
526
+ read_table = undefined;
514
527
  data(table) {
515
528
  return new DataRequest(table, this);
516
529
  }
530
+ auth = new BagelAuth(this);
517
531
  _endpointCleaner(endpoint) {
518
532
  const url = `${endpoint.replace(/^\//, "").replaceAll(/\/$/g, "")}`;
519
533
  return url;
@@ -528,12 +542,10 @@ class Bagel {
528
542
  async get(endpoint, query) {
529
543
  this._setAuthorization();
530
544
  endpoint = this._endpointCleaner(endpoint);
531
- if (/undefined|null/.test(endpoint))
532
- throw new Error(`Invalid endpoint: ${endpoint}`);
545
+ if (/undefined|null/.test(endpoint)) throw new Error(`Invalid endpoint: ${endpoint}`);
533
546
  if (query) {
534
547
  const queryParams = Object.entries(query).filter(([_, value]) => !!value).map(([key, value]) => `${key}=${value}`).join("&");
535
- if (queryParams)
536
- endpoint = `${endpoint}?${queryParams}`;
548
+ if (queryParams) endpoint = `${endpoint}?${queryParams}`;
537
549
  }
538
550
  const url = `/${endpoint}`;
539
551
  return axios.get(url).then(({ data }) => data).catch((err) => {
@@ -583,8 +595,7 @@ class Bagel {
583
595
  const formData = new FormData();
584
596
  formData.append("file", file);
585
597
  let url = "/static_files/upload";
586
- if (options?.topic)
587
- url = `/static_files/upload?topic=${options.topic}`;
598
+ if (options?.topic) url = `/static_files/upload?topic=${options.topic}`;
588
599
  const { data } = await axios.post(url, formData, {
589
600
  headers: {
590
601
  "Content-Type": "multipart/form-data"
package/dist/index.mjs CHANGED
@@ -8,23 +8,19 @@ function formatType(typeName) {
8
8
  }
9
9
  function resolveReference(ref) {
10
10
  const t = ref.split("/").pop();
11
- if (!t)
12
- return "any";
11
+ if (!t) return "any";
13
12
  return formatType(t);
14
13
  }
15
14
  function schemaToType(schema) {
16
- if (!schema)
17
- return "any";
15
+ if (!schema) return "any";
18
16
  if (schema.anyOf) {
19
17
  let _t = schema.anyOf.map((s) => schemaToType(s)).filter((p) => p !== "any").join(" | ");
20
- if (_t === "" || _t === "null")
21
- _t = "any";
18
+ if (_t === "" || _t === "null") _t = "any";
22
19
  return _t;
23
20
  }
24
21
  if (schema.allOf)
25
22
  return schema.allOf.map((s) => schemaToType(s)).filter((p) => p !== "any").join(" & ");
26
- if (schema.$ref)
27
- return resolveReference(schema.$ref);
23
+ if (schema.$ref) return resolveReference(schema.$ref);
28
24
  switch (schema.type) {
29
25
  case "object":
30
26
  return "{ [key: string]: any }";
@@ -42,7 +38,7 @@ function schemaToType(schema) {
42
38
  return "undefined";
43
39
  case "null":
44
40
  return "null";
45
- case void 0:
41
+ case undefined:
46
42
  return "any";
47
43
  default:
48
44
  console.log("Unknown type", schema.type);
@@ -54,10 +50,16 @@ function isOptional(schema) {
54
50
  const splitType = type.split(/\s+\|\s+/);
55
51
  const includesNull = splitType.includes("null");
56
52
  const includesUndefined = splitType.includes("undefined");
57
- return includesNull || includesUndefined || schema.default !== void 0;
53
+ return includesNull || includesUndefined || schema.default !== undefined;
58
54
  }
59
55
  const cleanOptionals = (str) => str.split(" | ").filter((t) => t !== "null" && t !== "undefined").join(" | ");
60
- function formatVarType(varName, schema, required = false, defaultValue) {
56
+ function formatVarType({
57
+ varName,
58
+ schema,
59
+ required = false,
60
+ defaultValue
61
+ }) {
62
+ if (varName === "personId") console.log({ varName, schema, required, defaultValue });
61
63
  let type = schemaToType(schema);
62
64
  type = cleanOptionals(type);
63
65
  let defaultStr = "";
@@ -68,9 +70,8 @@ function formatVarType(varName, schema, required = false, defaultValue) {
68
70
  defaultStr = ` = ${defaultValue}`;
69
71
  }
70
72
  }
71
- let optionalStr = required || isOptional(schema) ? "?" : "";
72
- if (defaultStr)
73
- optionalStr = "";
73
+ let optionalStr = !required && isOptional(schema) ? "?" : "";
74
+ if (defaultStr) optionalStr = "";
74
75
  return `${varName}${optionalStr}: ${type}${defaultStr}`;
75
76
  }
76
77
  function cleanPath(path) {
@@ -78,35 +79,39 @@ function cleanPath(path) {
78
79
  }
79
80
 
80
81
  const allTypes = [];
81
- const primitiveTypes = ["string", "number", "boolean", "null", "void", "any", "Record<string, any>", "undefined", "{ [key: string]: any }"];
82
+ const primitiveTypes = [
83
+ "string",
84
+ "number",
85
+ "boolean",
86
+ "null",
87
+ "void",
88
+ "any",
89
+ "Record<string, any>",
90
+ "undefined",
91
+ "{ [key: string]: any }"
92
+ ];
82
93
  function collectTypeForImportStatement(typeName) {
83
94
  typeName = typeName.trim().replace("[]", "");
84
95
  if (typeName.includes("|")) {
85
- typeName.split("|").forEach(
86
- (singleType) => {
87
- collectTypeForImportStatement(singleType);
88
- }
89
- );
96
+ typeName.split("|").forEach((singleType) => {
97
+ collectTypeForImportStatement(singleType);
98
+ });
90
99
  return;
91
100
  }
92
101
  const isPrimitive = primitiveTypes.includes(typeName);
93
102
  typeName = formatType(typeName);
94
- if (!typeName || isPrimitive)
95
- return;
96
- if (!allTypes.includes(typeName))
97
- allTypes.push(typeName);
103
+ if (!typeName || isPrimitive) return;
104
+ if (!allTypes.includes(typeName)) allTypes.push(typeName);
98
105
  }
99
106
  function getResponseType(response) {
100
107
  const mediaTypeObject = response.content?.["application/json"];
101
- if (!mediaTypeObject || !mediaTypeObject.schema)
102
- return;
108
+ if (!mediaTypeObject || !mediaTypeObject.schema) return;
103
109
  const responseType = schemaToType(mediaTypeObject.schema);
104
110
  collectTypeForImportStatement(responseType);
105
111
  return responseType;
106
112
  }
107
113
  function generateResponseType(responses) {
108
- if (!responses)
109
- return "";
114
+ if (!responses) return "";
110
115
  const types = [];
111
116
  for (const [statusCode, response] of Object.entries(responses)) {
112
117
  if (statusCode.startsWith("2")) {
@@ -119,8 +124,7 @@ function generateResponseType(responses) {
119
124
  return types.join(" | ");
120
125
  }
121
126
  function generateAxiosFunction(method, formattedPath, allParams, responseTypeStr, parameters, requestBodyPayload) {
122
- if (allParams === "undefined")
123
- allParams = "";
127
+ if (allParams === "undefined") allParams = "";
124
128
  let axiosFunction = `async (${allParams})${responseTypeStr} => {`;
125
129
  if (requestBodyPayload === "formData") {
126
130
  const paramStr = parameters?.config?.params ? `params: {${parameters.config.params}}` : "";
@@ -169,21 +173,23 @@ function generateRequestBody(requestBody) {
169
173
  const requestBodyType = schemaToType(bodySchema);
170
174
  collectTypeForImportStatement(requestBodyType);
171
175
  const requestBodyPayload = toCamelCase(bodySchema.title) || toCamelCase(requestBodyType) || "requestBody";
172
- const requestBodyParam = formatVarType(requestBodyPayload, bodySchema, bodySchema.default);
176
+ const requestBodyParam = formatVarType({
177
+ varName: requestBodyPayload,
178
+ schema: bodySchema,
179
+ defaultValue: bodySchema.default
180
+ });
173
181
  return { requestBodyParam, requestBodyPayload };
174
182
  }
175
183
  function combineAllParams(parameters, requestBodyParam) {
176
184
  let allParamsArray = [];
177
185
  if (parameters && parameters.params)
178
186
  allParamsArray = parameters.params.split(",").map((p) => p.trim());
179
- if (requestBodyParam)
180
- allParamsArray.push(requestBodyParam.trim());
187
+ if (requestBodyParam) allParamsArray.push(requestBodyParam.trim());
181
188
  allParamsArray = allParamsArray.filter((p) => p).sort((a, b) => (a.includes("?") ? 1 : -1) - (b.includes("?") ? 1 : -1));
182
189
  return allParamsArray.join(", ");
183
190
  }
184
191
  function generateFunctionParameters(params, isFileUpload = false) {
185
- if (!params?.length)
186
- return {};
192
+ if (!params?.length) return {};
187
193
  if (isFileUpload) {
188
194
  return {
189
195
  config: {
@@ -201,10 +207,19 @@ function generateFunctionParameters(params, isFileUpload = false) {
201
207
  const paramName = param.name;
202
208
  const varName = toCamelCase(param.name);
203
209
  if (param.in === "path" || param.in === "query" || param.in === "header") {
204
- functionParams.push(formatVarType(varName, param.schema, param.required, param.schema.default));
210
+ functionParams.push(
211
+ formatVarType({
212
+ varName,
213
+ schema: param.schema,
214
+ required: param.required,
215
+ defaultValue: param.schema.default
216
+ })
217
+ );
205
218
  }
206
219
  if (param.in === "query" || param.in === "header") {
207
- paramList.push(paramName === varName ? paramName : `'${paramName}': ${varName}`);
220
+ paramList.push(
221
+ paramName === varName ? paramName : `'${paramName}': ${varName}`
222
+ );
208
223
  }
209
224
  }
210
225
  return {
@@ -213,11 +228,15 @@ function generateFunctionParameters(params, isFileUpload = false) {
213
228
  };
214
229
  }
215
230
  function generateFunctionForOperation(method, path, operation) {
216
- if (!operation)
217
- return "";
231
+ if (!operation) return "";
218
232
  const isFileUpload = operation.requestBody?.content["multipart/form-data"]?.schema?.$ref?.includes("Body_upload_files");
219
- const parameters = generateFunctionParameters(operation.parameters, isFileUpload);
220
- const { requestBodyParam, requestBodyPayload } = generateRequestBody(operation.requestBody);
233
+ const parameters = generateFunctionParameters(
234
+ operation.parameters,
235
+ isFileUpload
236
+ );
237
+ const { requestBodyParam, requestBodyPayload } = generateRequestBody(
238
+ operation.requestBody
239
+ );
221
240
  const allParams = isFileUpload ? "file: File, options?: UploadOptions & { dirPath?: string, tags?: string[] }" : combineAllParams(parameters, requestBodyParam);
222
241
  const responseType = generateResponseType(operation.responses);
223
242
  const responseTypeStr = responseType ? `: Promise<AxiosResponse<${responseType}>>` : "";
@@ -235,13 +254,13 @@ function fileTemplate(tsString, typeForImport, baseURL) {
235
254
  const templateCode = `import ax from 'axios';
236
255
  import type { AxiosResponse } from 'axios';
237
256
  import type {${typeForImport.join(", ")}} from './types.d';
238
-
257
+
239
258
  interface UploadOptions {
240
259
  onUploadProgress?: (progressEvent: any) => void
241
260
  dirPath?: string
242
261
  tags?: string[]
243
262
  }
244
-
263
+
245
264
  export const axios = ax.create({baseURL:${baseURL}});
246
265
  ${tsString}`;
247
266
  const doubleQuoteRegex = /"([^"]+)":/g;
@@ -251,13 +270,19 @@ const functionsInventory = {};
251
270
  const pathOperations = [];
252
271
  function hasConflict(path, method) {
253
272
  const cleanPathName = path.split("/").filter((p) => p && !/\{|\}/.test(p)).join("/");
254
- const matchingPaths = pathOperations.filter((p) => p.path === cleanPathName && p.method === method);
273
+ const matchingPaths = pathOperations.filter(
274
+ (p) => p.path === cleanPathName && p.method === method
275
+ );
255
276
  pathOperations.push({ path: cleanPathName, method });
256
277
  return matchingPaths.length > 0;
257
278
  }
258
279
  function createFunctionPlaceholder(path, method, operation) {
259
280
  const funcID = generateRandomString();
260
- functionsInventory[funcID] = generateFunctionForOperation(method, path, operation);
281
+ functionsInventory[funcID] = generateFunctionForOperation(
282
+ method,
283
+ path,
284
+ operation
285
+ );
261
286
  return funcID;
262
287
  }
263
288
  function handlePathSegment(path, operation, existingObj = {}) {
@@ -269,7 +294,11 @@ function handlePathSegment(path, operation, existingObj = {}) {
269
294
  const params = getParamsFromPath(path);
270
295
  functionName += params ? `By${toPascalCase(params.pop() || "")}` : "All";
271
296
  }
272
- obj[functionName] = createFunctionPlaceholder(path, method, operation[method]);
297
+ obj[functionName] = createFunctionPlaceholder(
298
+ path,
299
+ method,
300
+ operation[method]
301
+ );
273
302
  }
274
303
  return { ...obj, ...existingObj };
275
304
  }
@@ -281,8 +310,7 @@ function generateFunctions(paths, baseUrl) {
281
310
  const splitPath = path.split("/").filter((p) => p && !/\{|\}/.test(p));
282
311
  splitPath.reduce((acc, key, index, array) => {
283
312
  const objFuncKey = toCamelCase(key);
284
- if (!objFuncKey)
285
- return acc;
313
+ if (!objFuncKey) return acc;
286
314
  const methods = Object.keys(operation);
287
315
  if (index === array.length - 1 && methods.length === 1 && allPathsClean.filter((p) => p === cleanPath(path)).length === 1) {
288
316
  const method = methods[0];
@@ -297,7 +325,7 @@ function generateFunctions(paths, baseUrl) {
297
325
  }, body);
298
326
  }
299
327
  for (const [parent, object] of Object.entries(body)) {
300
- tsString += `export const ${parent} = ${JSON.stringify(object, void 0, 2)};
328
+ tsString += `export const ${parent} = ${JSON.stringify(object, undefined, 2)};
301
329
  `;
302
330
  }
303
331
  Object.entries(functionsInventory).forEach(([key, value]) => {
@@ -314,10 +342,9 @@ function generateTypes(schemas) {
314
342
  return `export type ${typeName} = ${schema.enum.map((item) => `'${item}'`).join(" | ")};
315
343
  `;
316
344
  }
317
- if (!schema.properties)
318
- return "";
345
+ if (!schema.properties) return "";
319
346
  const properties = Object.entries(schema.properties).map(([key, value]) => {
320
- const varType = formatVarType(key, value);
347
+ const varType = formatVarType({ varName: key, schema: value });
321
348
  return ` ${varType}`;
322
349
  }).join(";\n ");
323
350
  return `export type ${typeName} = {
@@ -332,12 +359,10 @@ const index = async (openApiUrl, baseUrl) => {
332
359
  try {
333
360
  const { data: openApi } = await axios$1.get(openApiUrl, { headers: basicAuthHeader });
334
361
  const schemas = openApi.components?.schemas;
335
- if (!schemas)
336
- throw new Error("No schemas found in OpenAPI document");
362
+ if (!schemas) throw new Error("No schemas found in OpenAPI document");
337
363
  const types = generateTypes(schemas);
338
364
  const { paths } = openApi;
339
- if (!paths)
340
- throw new Error("No paths found in OpenAPI document");
365
+ if (!paths) throw new Error("No paths found in OpenAPI document");
341
366
  const code = generateFunctions(paths, baseUrl);
342
367
  return { types, code };
343
368
  } catch (error) {
@@ -345,28 +370,21 @@ const index = async (openApiUrl, baseUrl) => {
345
370
  }
346
371
  };
347
372
 
348
- var __defProp = Object.defineProperty;
349
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
350
- var __publicField = (obj, key, value) => {
351
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
352
- return value;
353
- };
354
373
  const axios = axios$1.create({
355
374
  withCredentials: true
356
375
  });
357
376
  class DataRequest {
377
+ data_table;
378
+ bagel;
379
+ itemID;
380
+ _filter = {};
358
381
  constructor(table, bagel) {
359
- __publicField(this, "data_table");
360
- __publicField(this, "bagel");
361
- __publicField(this, "itemID");
362
- __publicField(this, "_filter", {});
363
382
  this.data_table = table;
364
383
  this.bagel = bagel;
365
384
  this.itemID = "";
366
385
  }
367
386
  async post(item) {
368
- if (!this.data_table)
369
- throw new Error("Data table not set");
387
+ if (!this.data_table) throw new Error("Data table not set");
370
388
  const { data } = await axios.post(`/data/${this.data_table}`, item);
371
389
  return data;
372
390
  }
@@ -375,8 +393,7 @@ class DataRequest {
375
393
  return this;
376
394
  }
377
395
  async get() {
378
- if (!this.data_table)
379
- throw new Error("Data table not set");
396
+ if (!this.data_table) throw new Error("Data table not set");
380
397
  const filterStr = Object.keys(this._filter).length > 0 ? `?filter={${Object.entries(this._filter).map(([k, v]) => `${k}:${v}`).join(",")}}` : "";
381
398
  const url = `/data/${this.data_table}${this.itemID ? `/${this.itemID}` : ""}${filterStr}`;
382
399
  try {
@@ -385,7 +402,7 @@ class DataRequest {
385
402
  } catch (err) {
386
403
  console.log(err);
387
404
  this.bagel.onError?.(err);
388
- return void 0;
405
+ return undefined;
389
406
  }
390
407
  }
391
408
  item(id) {
@@ -393,8 +410,7 @@ class DataRequest {
393
410
  return this;
394
411
  }
395
412
  async delete() {
396
- if (!this.data_table)
397
- throw new Error("Data table not set");
413
+ if (!this.data_table) throw new Error("Data table not set");
398
414
  const { data } = await axios.delete(
399
415
  `/data/${this.data_table}/${this.itemID}`
400
416
  );
@@ -402,10 +418,8 @@ class DataRequest {
402
418
  }
403
419
  async put(updatedItem) {
404
420
  const { data_table, itemID } = this;
405
- if (!data_table)
406
- throw new Error("Data table not set");
407
- if (!itemID)
408
- throw new Error("Item ID not set");
421
+ if (!data_table) throw new Error("Data table not set");
422
+ if (!itemID) throw new Error("Item ID not set");
409
423
  const { data } = await axios.put(
410
424
  `/data/${data_table}/${itemID}`,
411
425
  updatedItem
@@ -423,9 +437,9 @@ function responses(key) {
423
437
  class BagelAuth {
424
438
  constructor(bagel) {
425
439
  this.bagel = bagel;
426
- __publicField(this, "user");
427
440
  this.bagel = bagel;
428
441
  }
442
+ user = undefined;
429
443
  async validateUser() {
430
444
  try {
431
445
  const { data: usr } = await axios.get("/users/me", {
@@ -473,7 +487,7 @@ class BagelAuth {
473
487
  this.bagel.onError?.(err);
474
488
  console.log(err);
475
489
  }
476
- this.user = void 0;
490
+ this.user = undefined;
477
491
  }
478
492
  async acceptInvite(token, user) {
479
493
  await axios.post(`/auth/accept-invite/${token}`, user);
@@ -491,12 +505,10 @@ class BagelAuth {
491
505
  }
492
506
  }
493
507
  class Bagel {
508
+ host;
509
+ fileBaseUrl;
510
+ onError;
494
511
  constructor({ host, fileBaseUrl, onError }) {
495
- __publicField(this, "host");
496
- __publicField(this, "fileBaseUrl");
497
- __publicField(this, "onError");
498
- __publicField(this, "read_table");
499
- __publicField(this, "auth", new BagelAuth(this));
500
512
  this.host = host?.replace(/\/$/, "");
501
513
  this.fileBaseUrl = fileBaseUrl?.replace(/\/$/, "");
502
514
  if (!this.host) {
@@ -505,9 +517,11 @@ class Bagel {
505
517
  axios.defaults.baseURL = this.host;
506
518
  this.onError = onError;
507
519
  }
520
+ read_table = undefined;
508
521
  data(table) {
509
522
  return new DataRequest(table, this);
510
523
  }
524
+ auth = new BagelAuth(this);
511
525
  _endpointCleaner(endpoint) {
512
526
  const url = `${endpoint.replace(/^\//, "").replaceAll(/\/$/g, "")}`;
513
527
  return url;
@@ -522,12 +536,10 @@ class Bagel {
522
536
  async get(endpoint, query) {
523
537
  this._setAuthorization();
524
538
  endpoint = this._endpointCleaner(endpoint);
525
- if (/undefined|null/.test(endpoint))
526
- throw new Error(`Invalid endpoint: ${endpoint}`);
539
+ if (/undefined|null/.test(endpoint)) throw new Error(`Invalid endpoint: ${endpoint}`);
527
540
  if (query) {
528
541
  const queryParams = Object.entries(query).filter(([_, value]) => !!value).map(([key, value]) => `${key}=${value}`).join("&");
529
- if (queryParams)
530
- endpoint = `${endpoint}?${queryParams}`;
542
+ if (queryParams) endpoint = `${endpoint}?${queryParams}`;
531
543
  }
532
544
  const url = `/${endpoint}`;
533
545
  return axios.get(url).then(({ data }) => data).catch((err) => {
@@ -577,8 +589,7 @@ class Bagel {
577
589
  const formData = new FormData();
578
590
  formData.append("file", file);
579
591
  let url = "/static_files/upload";
580
- if (options?.topic)
581
- url = `/static_files/upload?topic=${options.topic}`;
592
+ if (options?.topic) url = `/static_files/upload?topic=${options.topic}`;
582
593
  const { data } = await axios.post(url, formData, {
583
594
  headers: {
584
595
  "Content-Type": "multipart/form-data"
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@bagelink/sdk",
3
3
  "type": "module",
4
- "version": "0.0.1121",
4
+ "version": "0.0.1123",
5
5
  "description": "Bagel core sdk packages",
6
6
  "author": {
7
7
  "name": "Neveh Allon",
@@ -18,14 +18,24 @@ import {
18
18
 
19
19
  const allTypes: string[] = []
20
20
 
21
- const primitiveTypes = ['string', 'number', 'boolean', 'null', 'void', 'any', 'Record<string, any>', 'undefined', '{ [key: string]: any }']
21
+ const primitiveTypes = [
22
+ 'string',
23
+ 'number',
24
+ 'boolean',
25
+ 'null',
26
+ 'void',
27
+ 'any',
28
+ 'Record<string, any>',
29
+ 'undefined',
30
+ '{ [key: string]: any }',
31
+ ]
22
32
 
23
33
  function collectTypeForImportStatement(typeName: string) {
24
34
  typeName = typeName.trim().replace('[]', '')
25
35
  if (typeName.includes('|')) {
26
- typeName.split('|').forEach(
27
- (singleType) => { collectTypeForImportStatement(singleType) },
28
- )
36
+ typeName.split('|').forEach(singleType => {
37
+ collectTypeForImportStatement(singleType)
38
+ })
29
39
  return
30
40
  }
31
41
  const isPrimitive = primitiveTypes.includes(typeName)
@@ -73,7 +83,7 @@ function generateAxiosFunction(
73
83
  allParams: string,
74
84
  responseTypeStr: string,
75
85
  parameters: any,
76
- requestBodyPayload: string,
86
+ requestBodyPayload: string
77
87
  ): string {
78
88
  if (allParams === 'undefined') allParams = ''
79
89
 
@@ -92,7 +102,9 @@ function generateAxiosFunction(
92
102
  onUploadProgress: options?.onUploadProgress${paramStr ? `,\n ${paramStr}` : ''}
93
103
  })`
94
104
  } else {
95
- const paramStr = parameters?.config?.params ? `, { params: {${parameters.config.params}} }` : ''
105
+ const paramStr = parameters?.config?.params
106
+ ? `, { params: {${parameters.config.params}} }`
107
+ : ''
96
108
  const bodyVar = requestBodyPayload ? `${requestBodyPayload}` : '{}'
97
109
  axiosFunction += `return axios.${method}(${formattedPath}${['get', 'delete'].includes(method) ? paramStr : `, ${bodyVar}${paramStr}`})`
98
110
  }
@@ -110,19 +122,25 @@ function getParamsFromPath(path: string) {
110
122
 
111
123
  function formatPathWithParams(path: string) {
112
124
  const params = getParamsFromPath(path)
113
- const formattedPath = params ? `\`${path.replace(pathParamRegex, v => `$${toCamelCase(v)}`)}\`` : `'${path}'`
125
+ const formattedPath = params
126
+ ? `\`${path.replace(pathParamRegex, v => `$${toCamelCase(v)}`)}\``
127
+ : `'${path}'`
114
128
  return formattedPath
115
129
  }
116
130
 
117
- function generateRequestBody(requestBody?: RequestBodyObject): { [key: string]: string } {
118
- if (!requestBody?.content) return { requestBodyParam: '', requestBodyPayload: '' }
131
+ function generateRequestBody(requestBody?: RequestBodyObject): {
132
+ [key: string]: string
133
+ } {
134
+ if (!requestBody?.content)
135
+ return { requestBodyParam: '', requestBodyPayload: '' }
119
136
 
120
137
  const { content } = requestBody
121
138
  const multipartFormData = content['multipart/form-data'] || {}
122
139
  if (multipartFormData.schema?.$ref?.includes('Body_upload_files')) {
123
140
  return {
124
- requestBodyParam: 'file: File, options?: UploadOptions & { dirPath?: string, tags?: string[] }',
125
- requestBodyPayload: 'formData'
141
+ requestBodyParam:
142
+ 'file: File, options?: UploadOptions & { dirPath?: string, tags?: string[] }',
143
+ requestBodyPayload: 'formData',
126
144
  }
127
145
  }
128
146
 
@@ -135,8 +153,16 @@ function generateRequestBody(requestBody?: RequestBodyObject): { [key: string]:
135
153
  const bodySchema = jsonContent.schema
136
154
  const requestBodyType = schemaToType(bodySchema)
137
155
  collectTypeForImportStatement(requestBodyType)
138
- const requestBodyPayload = toCamelCase(bodySchema.title) || toCamelCase(requestBodyType) || 'requestBody'
139
- const requestBodyParam = formatVarType(requestBodyPayload, bodySchema, bodySchema.default)
156
+ const requestBodyPayload =
157
+ toCamelCase(bodySchema.title) ||
158
+ toCamelCase(requestBodyType) ||
159
+ 'requestBody'
160
+
161
+ const requestBodyParam = formatVarType({
162
+ varName: requestBodyPayload,
163
+ schema: bodySchema,
164
+ defaultValue: bodySchema.default,
165
+ })
140
166
  return { requestBodyParam, requestBodyPayload }
141
167
  }
142
168
 
@@ -146,9 +172,13 @@ function generateRequestBody(requestBody?: RequestBodyObject): { [key: string]:
146
172
  * @param requestBodyParam - The parameter representing the request body.
147
173
  * @returns A string representing all combined parameters.
148
174
  */
149
- function combineAllParams(parameters: { params?: string }, requestBodyParam: string): string {
175
+ function combineAllParams(
176
+ parameters: { params?: string },
177
+ requestBodyParam: string
178
+ ): string {
150
179
  let allParamsArray: string[] = []
151
- if (parameters && parameters.params) allParamsArray = parameters.params.split(',').map(p => p.trim())
180
+ if (parameters && parameters.params)
181
+ allParamsArray = parameters.params.split(',').map(p => p.trim())
152
182
  if (requestBodyParam) allParamsArray.push(requestBodyParam.trim())
153
183
 
154
184
  allParamsArray = allParamsArray
@@ -158,7 +188,10 @@ function combineAllParams(parameters: { params?: string }, requestBodyParam: str
158
188
  return allParamsArray.join(', ')
159
189
  }
160
190
 
161
- function generateFunctionParameters(params?: ParameterObject[], isFileUpload = false) {
191
+ function generateFunctionParameters(
192
+ params?: ParameterObject[],
193
+ isFileUpload = false
194
+ ) {
162
195
  if (!params?.length) return {}
163
196
 
164
197
  // For file uploads, we want to handle query parameters differently
@@ -166,9 +199,9 @@ function generateFunctionParameters(params?: ParameterObject[], isFileUpload = f
166
199
  // Don't include these as function parameters, they'll be part of options
167
200
  return {
168
201
  config: {
169
- params: 'dir_path: options?.dirPath, tags: options?.tags'
202
+ params: 'dir_path: options?.dirPath, tags: options?.tags',
170
203
  },
171
- params: '' // Empty string to ensure file is the first parameter
204
+ params: '', // Empty string to ensure file is the first parameter
172
205
  }
173
206
  }
174
207
 
@@ -182,27 +215,48 @@ function generateFunctionParameters(params?: ParameterObject[], isFileUpload = f
182
215
  const varName = toCamelCase(param.name)
183
216
 
184
217
  if (param.in === 'path' || param.in === 'query' || param.in === 'header') {
185
- functionParams.push(formatVarType(varName, param.schema, param.required, param.schema.default))
218
+ functionParams.push(
219
+ formatVarType({
220
+ varName,
221
+ schema: param.schema,
222
+ required: param.required,
223
+ defaultValue: param.schema.default,
224
+ })
225
+ )
186
226
  }
187
227
 
188
228
  if (param.in === 'query' || param.in === 'header') {
189
- paramList.push(paramName === varName ? paramName : `'${paramName}': ${varName}`)
229
+ paramList.push(
230
+ paramName === varName ? paramName : `'${paramName}': ${varName}`
231
+ )
190
232
  }
191
233
  }
192
234
 
193
235
  return {
194
236
  params: functionParams.join(', '),
195
- config: paramList.length ? { params: paramList.join(', ') } : {}
237
+ config: paramList.length ? { params: paramList.join(', ') } : {},
196
238
  }
197
239
  }
198
240
 
199
- function generateFunctionForOperation(method: string, path: string, operation: OperationObject): string {
241
+ function generateFunctionForOperation(
242
+ method: string,
243
+ path: string,
244
+ operation: OperationObject
245
+ ): string {
200
246
  if (!operation) return ''
201
247
 
202
248
  // Check if this is a file upload operation by looking at the schema reference
203
- const isFileUpload = operation.requestBody?.content['multipart/form-data']?.schema?.$ref?.includes('Body_upload_files')
204
- const parameters = generateFunctionParameters(operation.parameters, isFileUpload)
205
- const { requestBodyParam, requestBodyPayload } = generateRequestBody(operation.requestBody)
249
+ const isFileUpload =
250
+ operation.requestBody?.content[
251
+ 'multipart/form-data'
252
+ ]?.schema?.$ref?.includes('Body_upload_files')
253
+ const parameters = generateFunctionParameters(
254
+ operation.parameters,
255
+ isFileUpload
256
+ )
257
+ const { requestBodyParam, requestBodyPayload } = generateRequestBody(
258
+ operation.requestBody
259
+ )
206
260
 
207
261
  // For file uploads, ignore the regular parameter generation
208
262
  const allParams = isFileUpload
@@ -210,7 +264,9 @@ function generateFunctionForOperation(method: string, path: string, operation: O
210
264
  : combineAllParams(parameters, requestBodyParam)
211
265
 
212
266
  const responseType = generateResponseType(operation.responses)
213
- const responseTypeStr = responseType ? `: Promise<AxiosResponse<${responseType}>>` : ''
267
+ const responseTypeStr = responseType
268
+ ? `: Promise<AxiosResponse<${responseType}>>`
269
+ : ''
214
270
 
215
271
  return generateAxiosFunction(
216
272
  method,
@@ -224,21 +280,23 @@ function generateFunctionForOperation(method: string, path: string, operation: O
224
280
 
225
281
  const generateRandomString = () => Math.random().toString(36).slice(7)
226
282
 
227
- function fileTemplate(tsString: string, typeForImport: string[], baseURL: string) {
228
- const templateCode = (
229
- `import ax from 'axios';
283
+ function fileTemplate(
284
+ tsString: string,
285
+ typeForImport: string[],
286
+ baseURL: string
287
+ ) {
288
+ const templateCode = `import ax from 'axios';
230
289
  import type { AxiosResponse } from 'axios';
231
290
  import type {${typeForImport.join(', ')}} from './types.d';
232
-
291
+
233
292
  interface UploadOptions {
234
293
  onUploadProgress?: (progressEvent: any) => void
235
294
  dirPath?: string
236
295
  tags?: string[]
237
296
  }
238
-
297
+
239
298
  export const axios = ax.create({baseURL:${baseURL}});
240
299
  ${tsString}`
241
- )
242
300
  const doubleQuoteRegex = /"([^"]+)":/g
243
301
  return templateCode.replace(doubleQuoteRegex, '$1:')
244
302
  }
@@ -252,23 +310,36 @@ const functionsInventory: Record<string, string> = {}
252
310
  const pathOperations: PathOperation[] = []
253
311
 
254
312
  function hasConflict(path: string, method: string) {
255
- const cleanPathName = path.split('/').filter(p => p && !(/\{|\}/).test(p)).join('/')
256
- const matchingPaths = pathOperations.filter(p => p.path === cleanPathName && p.method === method)
313
+ const cleanPathName = path
314
+ .split('/')
315
+ .filter(p => p && !/\{|\}/.test(p))
316
+ .join('/')
317
+ const matchingPaths = pathOperations.filter(
318
+ p => p.path === cleanPathName && p.method === method
319
+ )
257
320
  pathOperations.push({ path: cleanPathName, method })
258
321
  return matchingPaths.length > 0
259
322
  }
260
323
 
261
324
  // Creates a placeholder for a function and stores its body in the inventory
262
- function createFunctionPlaceholder(path: string, method: string, operation: any) {
325
+ function createFunctionPlaceholder(
326
+ path: string,
327
+ method: string,
328
+ operation: any
329
+ ) {
263
330
  const funcID = generateRandomString()
264
- functionsInventory[funcID] = generateFunctionForOperation(method, path, operation)
331
+ functionsInventory[funcID] = generateFunctionForOperation(
332
+ method,
333
+ path,
334
+ operation
335
+ )
265
336
  return funcID
266
337
  }
267
338
 
268
339
  function handlePathSegment(
269
340
  path: string,
270
341
  operation: any,
271
- existingObj: { [key: string]: any } = {},
342
+ existingObj: { [key: string]: any } = {}
272
343
  ) {
273
344
  const methods = Object.keys(operation)
274
345
  const obj: { [key: string]: any } = {}
@@ -276,9 +347,13 @@ function handlePathSegment(
276
347
  let functionName = method.toLowerCase()
277
348
  if (hasConflict(path, method)) {
278
349
  const params: string[] | undefined = getParamsFromPath(path)
279
- functionName += (params ? `By${toPascalCase(params.pop() || '')}` : 'All')
350
+ functionName += params ? `By${toPascalCase(params.pop() || '')}` : 'All'
280
351
  }
281
- obj[functionName] = createFunctionPlaceholder(path, method, operation[method])
352
+ obj[functionName] = createFunctionPlaceholder(
353
+ path,
354
+ method,
355
+ operation[method]
356
+ )
282
357
  }
283
358
  return { ...obj, ...existingObj }
284
359
  }
@@ -288,24 +363,23 @@ export function generateFunctions(paths: PathsObject, baseUrl: string) {
288
363
  const body: { [key: string]: any } = {}
289
364
  const allPathsClean = Object.keys(paths).map(cleanPath)
290
365
  for (const [path, operation] of Object.entries(paths)) {
291
- const splitPath = path.split('/').filter(p => p && !(/\{|\}/).test(p))
366
+ const splitPath = path.split('/').filter(p => p && !/\{|\}/.test(p))
292
367
  splitPath.reduce((acc, key: string, index: number, array: string[]) => {
293
368
  const objFuncKey = toCamelCase(key)
294
369
  if (!objFuncKey) return acc
295
370
  const methods = Object.keys(operation)
296
371
  if (
297
- index === array.length - 1
298
- && methods.length === 1
299
- && 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
300
375
  ) {
301
376
  const method: string = methods[0]
302
377
  const opp: any = { ...operation }[method]
303
378
  acc[objFuncKey] = createFunctionPlaceholder(path, methods[0], opp)
304
- } else if (
305
- index === array.length - 1
306
- ) { acc[objFuncKey] = handlePathSegment(path, operation, acc[objFuncKey])
307
- }
308
- else if (!acc[objFuncKey] || typeof acc[objFuncKey] !== 'object') { acc[objFuncKey] = {}
379
+ } else if (index === array.length - 1) {
380
+ acc[objFuncKey] = handlePathSegment(path, operation, acc[objFuncKey])
381
+ } else if (!acc[objFuncKey] || typeof acc[objFuncKey] !== 'object') {
382
+ acc[objFuncKey] = {}
309
383
  }
310
384
  return acc[objFuncKey]
311
385
  }, body)
@@ -11,7 +11,7 @@ export function generateTypes(schemas: SchemasObject): string {
11
11
  if (!schema.properties) return ''
12
12
 
13
13
  const properties = Object.entries(schema.properties).map(([key, value]) => {
14
- const varType = formatVarType(key, value)
14
+ const varType = formatVarType({ varName: key, schema: value })
15
15
 
16
16
  return `\t\t${varType}`
17
17
  }).join(';\n ')
@@ -1,11 +1,24 @@
1
1
  import type { SchemaObject } from './openApiTypes'
2
2
 
3
- export const toCamelCase = (str?: string) => str?.replaceAll(/[-._\s]+(.)?/g, (_, c) => c?.toUpperCase() || '').replace(/^./, str => str.toLowerCase()) || str || ''
4
- export const toPascalCase = (str?: string) => str?.replaceAll(/[-_\s]+(.)?/g, (_, c) => c?.toUpperCase() || '').replace(/^./, str => str.toUpperCase()) || str || ''
3
+ export const toCamelCase = (str?: string) =>
4
+ str
5
+ ?.replaceAll(/[-._\s]+(.)?/g, (_, c) => c?.toUpperCase() || '')
6
+ .replace(/^./, str => str.toLowerCase()) ||
7
+ str ||
8
+ ''
9
+ export const toPascalCase = (str?: string) =>
10
+ str
11
+ ?.replaceAll(/[-_\s]+(.)?/g, (_, c) => c?.toUpperCase() || '')
12
+ .replace(/^./, str => str.toUpperCase()) ||
13
+ str ||
14
+ ''
5
15
 
6
16
  export function formatType(typeName: string): string {
7
17
  // eslint-disable-next-line regexp/no-unused-capturing-group
8
- typeName = typeName.replaceAll('-', '').replaceAll(/(post|put)$/gi, '').replaceAll(/^body_/gi, '')
18
+ typeName = typeName
19
+ .replaceAll('-', '')
20
+ .replaceAll(/(post|put)$/gi, '')
21
+ .replaceAll(/^body_/gi, '')
9
22
  return toPascalCase(typeName)!
10
23
  }
11
24
 
@@ -18,11 +31,18 @@ function resolveReference(ref: string): string {
18
31
  export function schemaToType(schema?: SchemaObject): string {
19
32
  if (!schema) return 'any'
20
33
  if (schema.anyOf) {
21
- let _t = schema.anyOf.map(s => schemaToType(s)).filter(p => p !== 'any').join(' | ')
34
+ let _t = schema.anyOf
35
+ .map(s => schemaToType(s))
36
+ .filter(p => p !== 'any')
37
+ .join(' | ')
22
38
  if (_t === '' || _t === 'null') _t = 'any'
23
39
  return _t
24
40
  }
25
- if (schema.allOf) return schema.allOf.map(s => schemaToType(s)).filter(p => p !== 'any').join(' & ')
41
+ if (schema.allOf)
42
+ return schema.allOf
43
+ .map(s => schemaToType(s))
44
+ .filter(p => p !== 'any')
45
+ .join(' & ')
26
46
  if (schema.$ref) return resolveReference(schema.$ref)
27
47
  switch (schema.type) {
28
48
  case 'object':
@@ -59,9 +79,25 @@ export function isOptional(schema: SchemaObject) {
59
79
  return includesNull || includesUndefined || schema.default !== undefined
60
80
  }
61
81
 
62
- export const cleanOptionals = (str: string) => str.split(' | ').filter(t => t !== 'null' && t !== 'undefined').join(' | ')
82
+ export const cleanOptionals = (str: string) =>
83
+ str
84
+ .split(' | ')
85
+ .filter(t => t !== 'null' && t !== 'undefined')
86
+ .join(' | ')
87
+
88
+ export function formatVarType({
89
+ varName,
90
+ schema,
91
+ required = false,
92
+ defaultValue,
93
+ }: {
94
+ varName: string
95
+ schema: SchemaObject
96
+ required?: boolean
97
+ defaultValue?: unknown
98
+ }) {
99
+ if (varName === 'personId') console.log({ varName, schema, required, defaultValue });
63
100
 
64
- export function formatVarType(varName: string, schema: any, required = false, defaultValue?: unknown) {
65
101
  let type = schemaToType(schema)
66
102
  type = cleanOptionals(type)
67
103
 
@@ -74,12 +110,16 @@ export function formatVarType(varName: string, schema: any, required = false, de
74
110
  }
75
111
  }
76
112
 
77
- let optionalStr = required || isOptional(schema) ? '?' : ''
113
+ let optionalStr = (!required && isOptional(schema)) ? '?' : ''
114
+
78
115
  if (defaultStr) optionalStr = ''
79
116
 
80
117
  return `${varName}${optionalStr}: ${type}${defaultStr}`
81
118
  }
82
119
 
83
120
  export function cleanPath(path: string) {
84
- return path.split('/').filter(p => p && !(/\{|\}/).test(p)).join('/')
121
+ return path
122
+ .split('/')
123
+ .filter(p => p && !/\{|\}/.test(p))
124
+ .join('/')
85
125
  }