openapi-sync 2.0.0 → 2.0.2

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.
@@ -23,7 +23,8 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.JSONStringify = exports.getEndpointDetails = exports.capitalize = exports.yamlStringToJson = exports.isYamlString = exports.isJson = void 0;
26
+ exports.renderTypeRefMD = exports.JSONStringify = exports.getEndpointDetails = exports.capitalize = exports.yamlStringToJson = exports.isYamlString = exports.isJson = void 0;
27
+ exports.getNestedValue = getNestedValue;
27
28
  const regex_1 = require("./regex");
28
29
  const yaml = __importStar(require("js-yaml"));
29
30
  const isJson = (value) => {
@@ -99,24 +100,46 @@ const getEndpointDetails = (path, method) => {
99
100
  return { name, variables, pathParts };
100
101
  };
101
102
  exports.getEndpointDetails = getEndpointDetails;
102
- const JSONStringify = (obj) => {
103
+ const JSONStringify = (obj, indent = 1) => {
103
104
  let result = "{";
104
105
  const keys = Object.keys(obj);
105
106
  for (let i = 0; i < keys.length; i++) {
106
107
  const key = keys[i];
107
108
  const value = obj[key];
108
- result += key + ": ";
109
+ result += "\n" + " ".repeat(indent) + key + ": ";
109
110
  if (typeof value === "object" && value !== null) {
110
- result += (0, exports.JSONStringify)(value);
111
+ result += "" + (0, exports.JSONStringify)(value, indent + 1);
111
112
  }
112
113
  else {
113
- result += value;
114
+ result += value
115
+ .split("\n")
116
+ .filter((line) => line.trim() !== "")
117
+ .join(`\n${" ".repeat(indent)}`);
114
118
  }
115
119
  if (i < keys.length - 1) {
116
120
  result += ", ";
117
121
  }
118
122
  }
119
- result += "}";
123
+ result += `\n${" ".repeat(indent - 1)}}`;
120
124
  return result;
121
125
  };
122
126
  exports.JSONStringify = JSONStringify;
127
+ const renderTypeRefMD = (typeRef, indent = 1) => {
128
+ return `\n\`\`\`typescript\n${" ".repeat(indent)} ${typeRef
129
+ .split("\n")
130
+ .filter((line) => line.trim() !== "")
131
+ .join(`\n${" ".repeat(indent)} `)}\n\`\`\``;
132
+ };
133
+ exports.renderTypeRefMD = renderTypeRefMD;
134
+ function getNestedValue(obj, path) {
135
+ // Split the path string into an array of keys
136
+ const keys = path.split(".");
137
+ // Use the reduce method to navigate the object
138
+ return keys.reduce((currentObj, key) => {
139
+ // If the current object is not null or undefined,
140
+ // return the value of the next key. Otherwise, return undefined.
141
+ return currentObj && currentObj[key] !== undefined
142
+ ? currentObj[key]
143
+ : undefined;
144
+ }, obj);
145
+ }
@@ -21,6 +21,7 @@ const axios_1 = __importDefault(require("axios"));
21
21
  const axios_retry_1 = __importDefault(require("axios-retry"));
22
22
  const openapi_core_1 = require("@redocly/openapi-core");
23
23
  const state_1 = require("./state");
24
+ const curl_generator_1 = require("curl-generator");
24
25
  const rootUsingCwd = process.cwd();
25
26
  let fetchTimeout = {};
26
27
  // Create an Axios instance
@@ -39,7 +40,7 @@ const apiClient = axios_1.default.create({
39
40
  },
40
41
  });
41
42
  const OpenapiSync = (apiUrl, apiName, config, refetchInterval) => __awaiter(void 0, void 0, void 0, function* () {
42
- var _a, _b, _c, _d;
43
+ var _a, _b, _c, _d, _e, _f;
43
44
  const specResponse = yield apiClient.get(apiUrl);
44
45
  const redoclyConfig = yield (0, openapi_core_1.createConfig)({
45
46
  extends: ["minimal"],
@@ -51,18 +52,19 @@ const OpenapiSync = (apiUrl, apiName, config, refetchInterval) => __awaiter(void
51
52
  source,
52
53
  config: redoclyConfig,
53
54
  });
54
- const folderPath = path_1.default.join(config.folder || "", apiName);
55
+ const folderPath = path_1.default.join((config === null || config === void 0 ? void 0 : config.folder) || "", apiName);
55
56
  const spec = lintResults.bundle.parsed;
56
- const typePrefix = typeof ((_b = (_a = config === null || config === void 0 ? void 0 : config.types) === null || _a === void 0 ? void 0 : _a.name) === null || _b === void 0 ? void 0 : _b.prefix) === "string"
57
- ? config.types.name.prefix
57
+ const serverUrl = ((_b = (_a = spec === null || spec === void 0 ? void 0 : spec.servers) === null || _a === void 0 ? void 0 : _a[(config === null || config === void 0 ? void 0 : config.server) || 0]) === null || _b === void 0 ? void 0 : _b.url) || "";
58
+ const typePrefix = typeof ((_d = (_c = config === null || config === void 0 ? void 0 : config.types) === null || _c === void 0 ? void 0 : _c.name) === null || _d === void 0 ? void 0 : _d.prefix) === "string"
59
+ ? config === null || config === void 0 ? void 0 : config.types.name.prefix
58
60
  : "I";
59
- const endpointPrefix = typeof ((_d = (_c = config === null || config === void 0 ? void 0 : config.endpoints) === null || _c === void 0 ? void 0 : _c.name) === null || _d === void 0 ? void 0 : _d.prefix) === "string"
60
- ? config.endpoints.name.prefix
61
+ const endpointPrefix = typeof ((_f = (_e = config === null || config === void 0 ? void 0 : config.endpoints) === null || _e === void 0 ? void 0 : _e.name) === null || _f === void 0 ? void 0 : _f.prefix) === "string"
62
+ ? config === null || config === void 0 ? void 0 : config.endpoints.name.prefix
61
63
  : "";
62
64
  const getSharedComponentName = (componentName, componentType) => {
63
65
  var _a, _b;
64
66
  if ((_b = (_a = config === null || config === void 0 ? void 0 : config.types) === null || _a === void 0 ? void 0 : _a.name) === null || _b === void 0 ? void 0 : _b.format) {
65
- const formattedName = config.types.name.format("shared", {
67
+ const formattedName = config === null || config === void 0 ? void 0 : config.types.name.format("shared", {
66
68
  name: componentName,
67
69
  });
68
70
  if (formattedName)
@@ -70,7 +72,7 @@ const OpenapiSync = (apiUrl, apiName, config, refetchInterval) => __awaiter(void
70
72
  }
71
73
  return `${typePrefix}${(0, helpers_1.capitalize)(componentName)}`;
72
74
  };
73
- const parseSchemaToType = (apiDoc, schema, name, isRequired, options) => {
75
+ const parseSchemaToType = (apiDoc, schema, name, isRequired, options, indentLevel = 0) => {
74
76
  let overrideName = "";
75
77
  let componentName = "";
76
78
  let type = "";
@@ -135,11 +137,20 @@ const OpenapiSync = (apiUrl, apiName, config, refetchInterval) => __awaiter(void
135
137
  const requiredKeys = schema.required || [];
136
138
  let typeCnt = "";
137
139
  objKeys.forEach((key) => {
138
- var _a;
139
- typeCnt += `${parseSchemaToType(apiDoc, (_a = schema.properties) === null || _a === void 0 ? void 0 : _a[key], key, requiredKeys.includes(key), options)}`;
140
+ var _a, _b, _c, _d, _e, _f;
141
+ let doc = "";
142
+ if (!((_b = (_a = config === null || config === void 0 ? void 0 : config.types) === null || _a === void 0 ? void 0 : _a.doc) === null || _b === void 0 ? void 0 : _b.disable) &&
143
+ ((_d = (_c = schema.properties) === null || _c === void 0 ? void 0 : _c[key]) === null || _d === void 0 ? void 0 : _d.description)) {
144
+ doc =
145
+ " * " +
146
+ ((_e = schema.properties) === null || _e === void 0 ? void 0 : _e[key].description.split("\n").filter((line) => line.trim() !== "").join(` \n *${" ".repeat(1)}`));
147
+ }
148
+ typeCnt +=
149
+ (doc ? `/**\n${doc}\n */\n` : "") +
150
+ `${parseSchemaToType(apiDoc, (_f = schema.properties) === null || _f === void 0 ? void 0 : _f[key], key, requiredKeys.includes(key), options, indentLevel + 1)}`;
140
151
  });
141
152
  if (typeCnt.length > 0) {
142
- type += `{\n${typeCnt}}`;
153
+ type += `{\n${" ".repeat(indentLevel)}${typeCnt}${" ".repeat(indentLevel)}}`;
143
154
  }
144
155
  else {
145
156
  type += "{[k: string]: any}";
@@ -205,6 +216,97 @@ const OpenapiSync = (apiUrl, apiName, config, refetchInterval) => __awaiter(void
205
216
  ? `${typeName}${type}${nullable}${_name ? ";\n" : ""}`
206
217
  : "";
207
218
  };
219
+ const getSchemaExamples = (apiDoc, schema) => {
220
+ let overrideName = "";
221
+ let componentName = "";
222
+ let type = "";
223
+ if (schema) {
224
+ if (schema.$ref) {
225
+ if (schema.$ref[0] === "#") {
226
+ let pathToComponentParts = (schema.$ref || "").split("/");
227
+ pathToComponentParts.shift();
228
+ const pathToComponent = pathToComponentParts;
229
+ const component = lodash_1.default.get(apiDoc, pathToComponent, null);
230
+ if (component) {
231
+ if (component === null || component === void 0 ? void 0 : component.name) {
232
+ overrideName = component.name;
233
+ }
234
+ componentName =
235
+ pathToComponentParts[pathToComponentParts.length - 1];
236
+ type += getSchemaExamples(apiDoc, component);
237
+ }
238
+ }
239
+ else {
240
+ type += "";
241
+ //TODO $ref is a uri - use axios to fetch doc
242
+ }
243
+ }
244
+ else if (schema.anyOf) {
245
+ type += getSchemaExamples(apiDoc, schema.anyOf[0]);
246
+ }
247
+ else if (schema.oneOf) {
248
+ type += getSchemaExamples(apiDoc, schema.oneOf[0]);
249
+ }
250
+ else if (schema.allOf) {
251
+ type += `{${schema.allOf
252
+ .map((v) => `...(${getSchemaExamples(apiDoc, v)})`)
253
+ .join(",")}}`;
254
+ }
255
+ else if (schema.items) {
256
+ type += `[${getSchemaExamples(apiDoc, schema.items)}]`;
257
+ }
258
+ else if (schema.properties) {
259
+ //parse object key one at a time
260
+ const objKeys = Object.keys(schema.properties);
261
+ const arr = objKeys.map((key) => {
262
+ var _a;
263
+ return ` "${key}": ${getSchemaExamples(apiDoc, (_a = schema.properties) === null || _a === void 0 ? void 0 : _a[key])}`;
264
+ });
265
+ let typeCnt = arr.join(",\n");
266
+ if (typeCnt.length > 0) {
267
+ type += `{\n${typeCnt}\n }`;
268
+ }
269
+ else {
270
+ type += "{}";
271
+ }
272
+ }
273
+ else if (schema.enum && schema.enum.length > 0) {
274
+ if (schema.enum.length > 1)
275
+ type += schema.enum[0];
276
+ }
277
+ else if (schema.type) {
278
+ if (schema.example) {
279
+ type += JSON.stringify(schema.example);
280
+ }
281
+ else {
282
+ if (["string", "integer", "number", "array", "boolean"].includes(schema.type)) {
283
+ if (["integer", "number"].includes(schema.type)) {
284
+ type += `123`;
285
+ }
286
+ else if (schema.type === "array") {
287
+ //Since we would have already parsed the arrays keys above "schema.items" if it exists
288
+ type += "[]";
289
+ }
290
+ else if (schema.type === "boolean") {
291
+ type += `true`;
292
+ }
293
+ else {
294
+ type += `"${schema.type}"`;
295
+ }
296
+ }
297
+ else if (schema.type === "object") {
298
+ //Since we would have already parsed the object keys above "schema.properties" if it exists
299
+ type += "{}";
300
+ }
301
+ }
302
+ }
303
+ }
304
+ else {
305
+ //Default type to string if no schema provided
306
+ type = "string";
307
+ }
308
+ return type;
309
+ };
208
310
  // auto update only on dev
209
311
  if (refetchInterval && !isNaN(refetchInterval) && refetchInterval > 0) {
210
312
  if (!(process.env.NODE_ENV &&
@@ -239,6 +341,7 @@ const OpenapiSync = (apiUrl, apiName, config, refetchInterval) => __awaiter(void
239
341
  // Create components (shared) types
240
342
  const components = spec.components[key];
241
343
  const componentInterfaces = {};
344
+ const componentSchema = {};
242
345
  const contentKeys = Object.keys(components);
243
346
  // only need 1 schema so will us the first schema provided
244
347
  contentKeys.forEach((contentKey) => {
@@ -261,6 +364,7 @@ const OpenapiSync = (apiUrl, apiName, config, refetchInterval) => __awaiter(void
261
364
  if (typeCnt) {
262
365
  const parts = contentKey.split(".");
263
366
  let currentLevel = componentInterfaces;
367
+ let currentSchemaLevel = componentSchema;
264
368
  // Navigate or create the nested structure
265
369
  for (let i = 0; i < parts.length; i++) {
266
370
  const part = parts[i];
@@ -268,23 +372,41 @@ const OpenapiSync = (apiUrl, apiName, config, refetchInterval) => __awaiter(void
268
372
  // If it's not the last part, create a nested object if it doesn't exist
269
373
  if (!(part in currentLevel)) {
270
374
  currentLevel[part] = {}; //<== This rely on js ability to assign value to origianl object by reference, so this assignment will be reflected in componentInterfaces
375
+ currentSchemaLevel[part] = {}; //<== This rely on js ability to assign value to origianl object by reference, so this assignment will be reflected in componentSchema
271
376
  }
272
377
  currentLevel = currentLevel[part]; //<== This rely on js ability to assign value to origianl object by reference, so this assignment will be reflected in componentInterfaces
378
+ currentSchemaLevel = currentSchemaLevel[part]; //<== This rely on js ability to assign value to origianl object by reference, so this assignment will be reflected in componentSchema
273
379
  }
274
380
  else {
275
381
  // This is the last part, assign the original schema value
276
382
  currentLevel[part] = typeCnt; //<== This rely on js ability to assign value to origianl object by reference, so this assignment will be reflected in componentInterfaces
383
+ currentSchemaLevel[part] = schema; //<== This rely on js ability to assign value to origianl object by reference, so this assignment will be reflected in componentSchema
277
384
  }
278
385
  }
279
386
  }
280
387
  });
281
388
  // Generate TypeScript interfaces for each component
282
389
  Object.keys(componentInterfaces).forEach((key) => {
283
- var _a;
390
+ var _a, _b, _c, _d;
284
391
  const name = getSharedComponentName(key);
285
392
  const cnt = componentInterfaces[key];
393
+ let doc = "";
394
+ if (!((_b = (_a = config === null || config === void 0 ? void 0 : config.types) === null || _a === void 0 ? void 0 : _a.doc) === null || _b === void 0 ? void 0 : _b.disable) &&
395
+ key in components &&
396
+ (
397
+ //@ts-expect-error
398
+ (_c = components[key]) === null || _c === void 0 ? void 0 : _c.description)) {
399
+ doc =
400
+ " * " +
401
+ //@ts-expect-error
402
+ components[key].description
403
+ .split("\n")
404
+ .filter((line) => line.trim() !== "")
405
+ .join(` \n *${" ".repeat(1)}`);
406
+ }
286
407
  sharedTypesFileContent[key] =
287
- ((_a = sharedTypesFileContent[key]) !== null && _a !== void 0 ? _a : "") +
408
+ ((_d = sharedTypesFileContent[key]) !== null && _d !== void 0 ? _d : "") +
409
+ (doc ? `/**\n${doc}\n */\n` : "") +
288
410
  "export type " +
289
411
  name +
290
412
  " = " +
@@ -308,7 +430,7 @@ const OpenapiSync = (apiUrl, apiName, config, refetchInterval) => __awaiter(void
308
430
  const treatEndpointUrl = (endpointUrl) => {
309
431
  var _a, _b, _c, _d, _e;
310
432
  if (((_b = (_a = config === null || config === void 0 ? void 0 : config.endpoints) === null || _a === void 0 ? void 0 : _a.value) === null || _b === void 0 ? void 0 : _b.replaceWords) &&
311
- Array.isArray(config.endpoints.value.replaceWords)) {
433
+ Array.isArray(config === null || config === void 0 ? void 0 : config.endpoints.value.replaceWords)) {
312
434
  let newEndpointUrl = endpointUrl;
313
435
  (_e = (_d = (_c = config === null || config === void 0 ? void 0 : config.endpoints) === null || _c === void 0 ? void 0 : _c.value) === null || _d === void 0 ? void 0 : _d.replaceWords) === null || _e === void 0 ? void 0 : _e.forEach((replaceWord, indx) => {
314
436
  const regexp = new RegExp(replaceWord.replace, "g");
@@ -322,32 +444,32 @@ const OpenapiSync = (apiUrl, apiName, config, refetchInterval) => __awaiter(void
322
444
  };
323
445
  Object.keys(spec.paths || {}).forEach((endpointPath) => {
324
446
  const endpointSpec = spec.paths[endpointPath];
325
- // console.log("Endpoint Path:", { endpointPath, endpointSpec });
326
447
  const endpointMethods = Object.keys(endpointSpec);
327
448
  endpointMethods.forEach((_method) => {
328
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
449
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
329
450
  const method = _method;
330
451
  const endpoint = (0, helpers_1.getEndpointDetails)(endpointPath, method);
331
- const endpointUrlTxt = endpoint.pathParts
332
- .map((part) => {
333
- // check if part is a variable
334
- if (part[0] === "{" && part[part.length - 1] === "}") {
335
- const s = part.replace(/{/, "").replace(/}/, "");
336
- part = `\${${s}}`;
337
- }
338
- //api/<userId>
339
- else if (part[0] === "<" && part[part.length - 1] === ">") {
340
- const s = part.replace(/</, "").replace(/>/, "");
341
- part = `\${${s}}`;
342
- }
343
- //api/:userId
344
- else if (part[0] === ":") {
345
- const s = part.replace(/:/, "");
346
- part = `\${${s}}`;
347
- }
348
- return part;
349
- })
350
- .join("/");
452
+ const endpointUrlTxt = (((_b = (_a = config === null || config === void 0 ? void 0 : config.endpoints) === null || _a === void 0 ? void 0 : _a.value) === null || _b === void 0 ? void 0 : _b.includeServer) ? serverUrl : "") +
453
+ endpoint.pathParts
454
+ .map((part) => {
455
+ // check if part is a variable
456
+ if (part[0] === "{" && part[part.length - 1] === "}") {
457
+ const s = part.replace(/{/, "").replace(/}/, "");
458
+ part = `\${${s}}`;
459
+ }
460
+ //api/<userId>
461
+ else if (part[0] === "<" && part[part.length - 1] === ">") {
462
+ const s = part.replace(/</, "").replace(/>/, "");
463
+ part = `\${${s}}`;
464
+ }
465
+ //api/:userId
466
+ else if (part[0] === ":") {
467
+ const s = part.replace(/:/, "");
468
+ part = `\${${s}}`;
469
+ }
470
+ return part;
471
+ })
472
+ .join("/");
351
473
  let endpointUrl = `"${endpointUrlTxt}"`;
352
474
  if (endpoint.variables.length > 0) {
353
475
  const params = endpoint.variables.map((v) => `${v}:string`).join(",");
@@ -355,88 +477,213 @@ const OpenapiSync = (apiUrl, apiName, config, refetchInterval) => __awaiter(void
355
477
  }
356
478
  //treat endpoint url
357
479
  endpointUrl = treatEndpointUrl(endpointUrl);
358
- let name = `${endpoint.name}`;
359
- if ((_b = (_a = config === null || config === void 0 ? void 0 : config.endpoints) === null || _a === void 0 ? void 0 : _a.name) === null || _b === void 0 ? void 0 : _b.format) {
360
- const formattedName = config.endpoints.name.format({
361
- method,
362
- path: endpointPath,
363
- summary: (_c = endpointSpec[method]) === null || _c === void 0 ? void 0 : _c.summary,
364
- });
365
- if (formattedName)
366
- name = formattedName;
367
- }
368
- // Add the endpoint url
369
- endpointsFileContent += `export const ${endpointPrefix}${name} = ${endpointUrl};
370
- `;
371
- if ((_d = endpointSpec[method]) === null || _d === void 0 ? void 0 : _d.parameters) {
480
+ const eSpec = endpointSpec[method];
481
+ let queryTypeCnt = "";
482
+ if (eSpec === null || eSpec === void 0 ? void 0 : eSpec.parameters) {
372
483
  // create query parameters types
373
- const parameters = (_e = endpointSpec[method]) === null || _e === void 0 ? void 0 : _e.parameters;
374
- let typeCnt = "";
484
+ const parameters = eSpec === null || eSpec === void 0 ? void 0 : eSpec.parameters;
375
485
  parameters.forEach((param, i) => {
376
486
  if (param.$ref || (param.in === "query" && param.name)) {
377
- typeCnt += `${parseSchemaToType(spec, param.$ref ? param : param.schema, param.name || "", param.required)}`;
487
+ queryTypeCnt += `${parseSchemaToType(spec, param.$ref ? param : param.schema, param.name || "", param.required)}`;
378
488
  }
379
489
  });
380
- if (typeCnt) {
490
+ if (queryTypeCnt) {
491
+ queryTypeCnt = `{\n${queryTypeCnt}}`;
381
492
  let name = `${endpoint.name}Query`;
382
- if ((_g = (_f = config === null || config === void 0 ? void 0 : config.types) === null || _f === void 0 ? void 0 : _f.name) === null || _g === void 0 ? void 0 : _g.format) {
383
- const formattedName = config.types.name.format("endpoint", {
493
+ if ((_d = (_c = config === null || config === void 0 ? void 0 : config.types) === null || _c === void 0 ? void 0 : _c.name) === null || _d === void 0 ? void 0 : _d.format) {
494
+ const formattedName = config === null || config === void 0 ? void 0 : config.types.name.format("endpoint", {
384
495
  code: "",
385
496
  type: "query",
386
497
  method,
387
498
  path: endpointPath,
388
- summary: (_h = endpointSpec[method]) === null || _h === void 0 ? void 0 : _h.summary,
499
+ summary: eSpec === null || eSpec === void 0 ? void 0 : eSpec.summary,
389
500
  });
390
501
  if (formattedName)
391
502
  name = formattedName;
392
503
  }
393
- typesFileContent += `export type ${typePrefix}${name} = {\n${typeCnt}};\n`;
504
+ typesFileContent += `export type ${typePrefix}${name} = ${queryTypeCnt};\n`;
394
505
  }
395
506
  }
396
- if ((_j = endpointSpec[method]) === null || _j === void 0 ? void 0 : _j.requestBody) {
507
+ const requestBody = eSpec === null || eSpec === void 0 ? void 0 : eSpec.requestBody;
508
+ let dtoTypeCnt = "";
509
+ if (requestBody) {
397
510
  //create requestBody types
398
- const requestBody = (_k = endpointSpec[method]) === null || _k === void 0 ? void 0 : _k.requestBody;
399
- let typeCnt = getBodySchemaType(requestBody);
400
- if (typeCnt) {
511
+ dtoTypeCnt = getBodySchemaType(requestBody);
512
+ if (dtoTypeCnt) {
401
513
  let name = `${endpoint.name}DTO`;
402
- if ((_m = (_l = config === null || config === void 0 ? void 0 : config.types) === null || _l === void 0 ? void 0 : _l.name) === null || _m === void 0 ? void 0 : _m.format) {
403
- const formattedName = config.types.name.format("endpoint", {
514
+ if ((_f = (_e = config === null || config === void 0 ? void 0 : config.types) === null || _e === void 0 ? void 0 : _e.name) === null || _f === void 0 ? void 0 : _f.format) {
515
+ const formattedName = config === null || config === void 0 ? void 0 : config.types.name.format("endpoint", {
404
516
  code: "",
405
517
  type: "dto",
406
518
  method,
407
519
  path: endpointPath,
408
- summary: (_o = endpointSpec[method]) === null || _o === void 0 ? void 0 : _o.summary,
520
+ summary: eSpec === null || eSpec === void 0 ? void 0 : eSpec.summary,
409
521
  });
410
522
  if (formattedName)
411
523
  name = formattedName;
412
524
  }
413
- typesFileContent += `export type ${typePrefix}${name} = ${typeCnt};\n`;
525
+ typesFileContent += `export type ${typePrefix}${name} = ${dtoTypeCnt};\n`;
414
526
  }
415
527
  }
416
- if ((_p = endpointSpec[method]) === null || _p === void 0 ? void 0 : _p.responses) {
528
+ const responseTypeObject = {};
529
+ let responseTypeCnt = "";
530
+ if (eSpec === null || eSpec === void 0 ? void 0 : eSpec.responses) {
417
531
  // create request response types
418
- const responses = (_q = endpointSpec[method]) === null || _q === void 0 ? void 0 : _q.responses;
532
+ const responses = eSpec === null || eSpec === void 0 ? void 0 : eSpec.responses;
419
533
  const resCodes = Object.keys(responses);
420
534
  resCodes.forEach((code) => {
421
- var _a, _b, _c;
422
- let typeCnt = getBodySchemaType(responses[code]);
423
- if (typeCnt) {
535
+ var _a, _b;
536
+ responseTypeCnt = getBodySchemaType(responses[code]);
537
+ responseTypeObject[code] = responseTypeCnt;
538
+ if (responseTypeCnt) {
424
539
  let name = `${endpoint.name}${code}Response`;
425
540
  if ((_b = (_a = config === null || config === void 0 ? void 0 : config.types) === null || _a === void 0 ? void 0 : _a.name) === null || _b === void 0 ? void 0 : _b.format) {
426
- const formattedName = config.types.name.format("endpoint", {
541
+ const formattedName = config === null || config === void 0 ? void 0 : config.types.name.format("endpoint", {
427
542
  code,
428
543
  type: "response",
429
544
  method,
430
545
  path: endpointPath,
431
- summary: (_c = endpointSpec[method]) === null || _c === void 0 ? void 0 : _c.summary,
546
+ summary: eSpec === null || eSpec === void 0 ? void 0 : eSpec.summary,
432
547
  });
433
548
  if (formattedName)
434
549
  name = formattedName;
435
550
  }
436
- typesFileContent += `export type ${typePrefix}${name} = ${typeCnt};\n`;
551
+ typesFileContent += `export type ${typePrefix}${name} = ${responseTypeCnt};\n`;
437
552
  }
438
553
  });
439
554
  }
555
+ // Function to format security requirements
556
+ const formatSecuritySpec = (security) => {
557
+ if (!security || !security.length)
558
+ return "";
559
+ return security
560
+ .map((securityRequirement) => {
561
+ const requirements = Object.entries(securityRequirement)
562
+ .map(([scheme, scopes]) => {
563
+ let sch = scheme;
564
+ let scopeText = "";
565
+ if (Array.isArray(scopes) && scopes.length) {
566
+ scopeText = `\n - Scopes: [\`${scopes.join("`, `")}\`]`;
567
+ sch = `**${sch}**`;
568
+ }
569
+ return `\n - ${sch}${scopeText}`;
570
+ })
571
+ .join("");
572
+ return requirements;
573
+ })
574
+ .join("\n");
575
+ };
576
+ // Get formatted security specification
577
+ const securitySpec = (eSpec === null || eSpec === void 0 ? void 0 : eSpec.security)
578
+ ? formatSecuritySpec(eSpec.security)
579
+ : "";
580
+ let doc = "";
581
+ if (!((_h = (_g = config === null || config === void 0 ? void 0 : config.endpoints) === null || _g === void 0 ? void 0 : _g.doc) === null || _h === void 0 ? void 0 : _h.disable)) {
582
+ let curl = "";
583
+ if ((_k = (_j = config === null || config === void 0 ? void 0 : config.endpoints) === null || _j === void 0 ? void 0 : _j.doc) === null || _k === void 0 ? void 0 : _k.showCurl) {
584
+ // console.log("cirl data", {
585
+ // body: eSpec?.requestBody,
586
+ // bodyContent:
587
+ // eSpec?.requestBody?.content["application/json"]?.schema
588
+ // ?.properties,
589
+ // security: eSpec?.security,
590
+ // });
591
+ const headers = {};
592
+ let body = "";
593
+ let extras = "";
594
+ if ((_l = eSpec.requestBody) === null || _l === void 0 ? void 0 : _l.content) {
595
+ const contentTypes = Object.keys(eSpec.requestBody.content);
596
+ contentTypes.forEach((contentType) => {
597
+ // console.log("requestBody content", {
598
+ // contentType,
599
+ // schema: eSpec.requestBody.content[contentType].schema,
600
+ // });
601
+ const schema = eSpec.requestBody.content[contentType].schema;
602
+ if (schema) {
603
+ if (Array.isArray(headers["Content-type"])) {
604
+ headers["Content-type"].push(contentType);
605
+ }
606
+ else {
607
+ headers["Content-type"] = [contentType];
608
+ }
609
+ const schemaType = getSchemaExamples(spec, schema);
610
+ if (schemaType)
611
+ body = schemaType;
612
+ }
613
+ });
614
+ }
615
+ if (eSpec === null || eSpec === void 0 ? void 0 : eSpec.security) {
616
+ eSpec.security.forEach((securityItem) => {
617
+ Object.keys(securityItem).forEach((security) => {
618
+ var _a, _b;
619
+ const securitySchema = (_b = (_a = spec.components) === null || _a === void 0 ? void 0 : _a.securitySchemes) === null || _b === void 0 ? void 0 : _b[security];
620
+ if (securitySchema) {
621
+ // headers["Authorization"] = securitySchema;
622
+ if (securitySchema.type === "mutualTLS") {
623
+ extras += `\n--cert client-certificate.crt \
624
+ --key client-private-key.key \
625
+ --cacert ca-certificate.crt`;
626
+ }
627
+ else if (securitySchema.type === "apiKey") {
628
+ headers[(securitySchema === null || securitySchema === void 0 ? void 0 : securitySchema.name) || "X-API-KEY"] = `{API_KEY_VALUE}`;
629
+ }
630
+ else {
631
+ headers["Authorization"] = `${(securitySchema === null || securitySchema === void 0 ? void 0 : securitySchema.scheme) === "basic" ? "Basic" : "Bearer"} {${(securitySchema === null || securitySchema === void 0 ? void 0 : securitySchema.scheme) === "basic" ? "VALUE" : "TOKEN"}}`;
632
+ }
633
+ }
634
+ });
635
+ });
636
+ }
637
+ const curlHeaders = {};
638
+ Object.keys(headers).forEach((header) => {
639
+ if (Array.isArray(headers[header])) {
640
+ curlHeaders[header] = headers[header].join("; ");
641
+ }
642
+ else {
643
+ curlHeaders[header] = headers[header];
644
+ }
645
+ });
646
+ // console.log("curlHeaders", { headers, curlHeaders, body });
647
+ curl = `\n\`\`\`bash
648
+ ${(0, curl_generator_1.CurlGenerator)({
649
+ url: serverUrl + endpointPath,
650
+ method: method.toUpperCase(),
651
+ headers: curlHeaders,
652
+ body,
653
+ })}${extras}
654
+ \`\`\``;
655
+ }
656
+ doc = `/**${(eSpec === null || eSpec === void 0 ? void 0 : eSpec.description) ? `\n* ${eSpec === null || eSpec === void 0 ? void 0 : eSpec.description} ` : ""}
657
+ * **Method**: \`${method.toUpperCase()}\`
658
+ * **Summary**: ${(eSpec === null || eSpec === void 0 ? void 0 : eSpec.summary) || ""}
659
+ * **Tags**: [${((_m = eSpec === null || eSpec === void 0 ? void 0 : eSpec.tags) === null || _m === void 0 ? void 0 : _m.join(", ")) || ""}]
660
+ * **OperationId**: ${(eSpec === null || eSpec === void 0 ? void 0 : eSpec.operationId) || ""} ${queryTypeCnt
661
+ ? `\n * **Query**: ${(0, helpers_1.renderTypeRefMD)(queryTypeCnt)} `
662
+ : ""}${dtoTypeCnt ? `\n * **DTO**: ${(0, helpers_1.renderTypeRefMD)(dtoTypeCnt)} ` : ""}${responseTypeCnt
663
+ ? `\n * **Response**: ${Object.entries(responseTypeObject)
664
+ .map(([code, type]) => `\n - **${code}**: ${(0, helpers_1.renderTypeRefMD)(type, 2)} `)
665
+ .join("")}`
666
+ : ""}${securitySpec ? `\n * **Security**: ${securitySpec}\n` : ""}${curl}
667
+ */\n`;
668
+ }
669
+ let name = ((_p = (_o = config === null || config === void 0 ? void 0 : config.endpoints) === null || _o === void 0 ? void 0 : _o.name) === null || _p === void 0 ? void 0 : _p.useOperationId) &&
670
+ ((_q = eSpec === null || eSpec === void 0 ? void 0 : eSpec.operationId) === null || _q === void 0 ? void 0 : _q.length) > 0
671
+ ? eSpec.operationId
672
+ : `${endpoint.name}`;
673
+ console.log("endpoint.name", eSpec);
674
+ if ((_s = (_r = config === null || config === void 0 ? void 0 : config.endpoints) === null || _r === void 0 ? void 0 : _r.name) === null || _s === void 0 ? void 0 : _s.format) {
675
+ const formattedName = config === null || config === void 0 ? void 0 : config.endpoints.name.format({
676
+ method,
677
+ path: endpointPath,
678
+ summary: eSpec === null || eSpec === void 0 ? void 0 : eSpec.summary,
679
+ operationId: eSpec === null || eSpec === void 0 ? void 0 : eSpec.operationId,
680
+ });
681
+ if (formattedName)
682
+ name = formattedName;
683
+ }
684
+ // Add the endpoint url
685
+ endpointsFileContent += `${doc}export const ${endpointPrefix}${name} = ${endpointUrl};
686
+ `;
440
687
  });
441
688
  });
442
689
  // Create the necessary directories
@@ -7,6 +7,9 @@ exports.resetState = exports.getState = exports.setState = void 0;
7
7
  const path_1 = __importDefault(require("path"));
8
8
  const fs_1 = __importDefault(require("fs"));
9
9
  const dbPath = path_1.default.join(__dirname, "../", "../db.json");
10
+ if (!fs_1.default.existsSync(dbPath)) {
11
+ fs_1.default.writeFileSync(dbPath, "{}");
12
+ }
10
13
  let db = {};
11
14
  try {
12
15
  db = require(dbPath);