openapi-sync 2.0.0 → 2.0.1

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.
@@ -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;
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 = (_a = spec.servers[(config === null || config === void 0 ? void 0 : config.server) || 0]) === null || _a === void 0 ? void 0 : _a.url;
58
+ const typePrefix = typeof ((_c = (_b = config === null || config === void 0 ? void 0 : config.types) === null || _b === void 0 ? void 0 : _b.name) === null || _c === void 0 ? void 0 : _c.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 ((_e = (_d = config === null || config === void 0 ? void 0 : config.endpoints) === null || _d === void 0 ? void 0 : _d.name) === null || _e === void 0 ? void 0 : _e.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;
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,208 @@ const OpenapiSync = (apiUrl, apiName, config, refetchInterval) => __awaiter(void
355
477
  }
356
478
  //treat endpoint url
357
479
  endpointUrl = treatEndpointUrl(endpointUrl);
480
+ const eSpec = endpointSpec[method];
358
481
  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({
482
+ if ((_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.format) {
483
+ const formattedName = config === null || config === void 0 ? void 0 : config.endpoints.name.format({
361
484
  method,
362
485
  path: endpointPath,
363
- summary: (_c = endpointSpec[method]) === null || _c === void 0 ? void 0 : _c.summary,
486
+ summary: eSpec === null || eSpec === void 0 ? void 0 : eSpec.summary,
364
487
  });
365
488
  if (formattedName)
366
489
  name = formattedName;
367
490
  }
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) {
491
+ let queryTypeCnt = "";
492
+ if (eSpec === null || eSpec === void 0 ? void 0 : eSpec.parameters) {
372
493
  // create query parameters types
373
- const parameters = (_e = endpointSpec[method]) === null || _e === void 0 ? void 0 : _e.parameters;
374
- let typeCnt = "";
494
+ const parameters = eSpec === null || eSpec === void 0 ? void 0 : eSpec.parameters;
375
495
  parameters.forEach((param, i) => {
376
496
  if (param.$ref || (param.in === "query" && param.name)) {
377
- typeCnt += `${parseSchemaToType(spec, param.$ref ? param : param.schema, param.name || "", param.required)}`;
497
+ queryTypeCnt += `${parseSchemaToType(spec, param.$ref ? param : param.schema, param.name || "", param.required)}`;
378
498
  }
379
499
  });
380
- if (typeCnt) {
500
+ if (queryTypeCnt) {
501
+ queryTypeCnt = `{\n${queryTypeCnt}}`;
381
502
  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", {
503
+ 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) {
504
+ const formattedName = config === null || config === void 0 ? void 0 : config.types.name.format("endpoint", {
384
505
  code: "",
385
506
  type: "query",
386
507
  method,
387
508
  path: endpointPath,
388
- summary: (_h = endpointSpec[method]) === null || _h === void 0 ? void 0 : _h.summary,
509
+ summary: eSpec === null || eSpec === void 0 ? void 0 : eSpec.summary,
389
510
  });
390
511
  if (formattedName)
391
512
  name = formattedName;
392
513
  }
393
- typesFileContent += `export type ${typePrefix}${name} = {\n${typeCnt}};\n`;
514
+ typesFileContent += `export type ${typePrefix}${name} = ${queryTypeCnt};\n`;
394
515
  }
395
516
  }
396
- if ((_j = endpointSpec[method]) === null || _j === void 0 ? void 0 : _j.requestBody) {
517
+ const requestBody = eSpec === null || eSpec === void 0 ? void 0 : eSpec.requestBody;
518
+ let dtoTypeCnt = "";
519
+ if (requestBody) {
397
520
  //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) {
521
+ dtoTypeCnt = getBodySchemaType(requestBody);
522
+ if (dtoTypeCnt) {
401
523
  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", {
524
+ if ((_h = (_g = config === null || config === void 0 ? void 0 : config.types) === null || _g === void 0 ? void 0 : _g.name) === null || _h === void 0 ? void 0 : _h.format) {
525
+ const formattedName = config === null || config === void 0 ? void 0 : config.types.name.format("endpoint", {
404
526
  code: "",
405
527
  type: "dto",
406
528
  method,
407
529
  path: endpointPath,
408
- summary: (_o = endpointSpec[method]) === null || _o === void 0 ? void 0 : _o.summary,
530
+ summary: eSpec === null || eSpec === void 0 ? void 0 : eSpec.summary,
409
531
  });
410
532
  if (formattedName)
411
533
  name = formattedName;
412
534
  }
413
- typesFileContent += `export type ${typePrefix}${name} = ${typeCnt};\n`;
535
+ typesFileContent += `export type ${typePrefix}${name} = ${dtoTypeCnt};\n`;
414
536
  }
415
537
  }
416
- if ((_p = endpointSpec[method]) === null || _p === void 0 ? void 0 : _p.responses) {
538
+ const responseTypeObject = {};
539
+ let responseTypeCnt = "";
540
+ if (eSpec === null || eSpec === void 0 ? void 0 : eSpec.responses) {
417
541
  // create request response types
418
- const responses = (_q = endpointSpec[method]) === null || _q === void 0 ? void 0 : _q.responses;
542
+ const responses = eSpec === null || eSpec === void 0 ? void 0 : eSpec.responses;
419
543
  const resCodes = Object.keys(responses);
420
544
  resCodes.forEach((code) => {
421
- var _a, _b, _c;
422
- let typeCnt = getBodySchemaType(responses[code]);
423
- if (typeCnt) {
545
+ var _a, _b;
546
+ responseTypeCnt = getBodySchemaType(responses[code]);
547
+ responseTypeObject[code] = responseTypeCnt;
548
+ if (responseTypeCnt) {
424
549
  let name = `${endpoint.name}${code}Response`;
425
550
  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", {
551
+ const formattedName = config === null || config === void 0 ? void 0 : config.types.name.format("endpoint", {
427
552
  code,
428
553
  type: "response",
429
554
  method,
430
555
  path: endpointPath,
431
- summary: (_c = endpointSpec[method]) === null || _c === void 0 ? void 0 : _c.summary,
556
+ summary: eSpec === null || eSpec === void 0 ? void 0 : eSpec.summary,
432
557
  });
433
558
  if (formattedName)
434
559
  name = formattedName;
435
560
  }
436
- typesFileContent += `export type ${typePrefix}${name} = ${typeCnt};\n`;
561
+ typesFileContent += `export type ${typePrefix}${name} = ${responseTypeCnt};\n`;
437
562
  }
438
563
  });
439
564
  }
565
+ // Function to format security requirements
566
+ const formatSecuritySpec = (security) => {
567
+ if (!security || !security.length)
568
+ return "";
569
+ return security
570
+ .map((securityRequirement) => {
571
+ const requirements = Object.entries(securityRequirement)
572
+ .map(([scheme, scopes]) => {
573
+ let sch = scheme;
574
+ let scopeText = "";
575
+ if (Array.isArray(scopes) && scopes.length) {
576
+ scopeText = `\n - Scopes: [\`${scopes.join("`, `")}\`]`;
577
+ sch = `**${sch}**`;
578
+ }
579
+ return `\n - ${sch}${scopeText}`;
580
+ })
581
+ .join("");
582
+ return requirements;
583
+ })
584
+ .join("\n");
585
+ };
586
+ // Get formatted security specification
587
+ const securitySpec = (eSpec === null || eSpec === void 0 ? void 0 : eSpec.security)
588
+ ? formatSecuritySpec(eSpec.security)
589
+ : "";
590
+ let doc = "";
591
+ 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.disable)) {
592
+ let curl = "";
593
+ if ((_m = (_l = config === null || config === void 0 ? void 0 : config.endpoints) === null || _l === void 0 ? void 0 : _l.doc) === null || _m === void 0 ? void 0 : _m.showCurl) {
594
+ // console.log("cirl data", {
595
+ // body: eSpec?.requestBody,
596
+ // bodyContent:
597
+ // eSpec?.requestBody?.content["application/json"]?.schema
598
+ // ?.properties,
599
+ // security: eSpec?.security,
600
+ // });
601
+ const headers = {};
602
+ let body = "";
603
+ let extras = "";
604
+ if ((_o = eSpec.requestBody) === null || _o === void 0 ? void 0 : _o.content) {
605
+ const contentTypes = Object.keys(eSpec.requestBody.content);
606
+ contentTypes.forEach((contentType) => {
607
+ // console.log("requestBody content", {
608
+ // contentType,
609
+ // schema: eSpec.requestBody.content[contentType].schema,
610
+ // });
611
+ const schema = eSpec.requestBody.content[contentType].schema;
612
+ if (schema) {
613
+ if (Array.isArray(headers["Content-type"])) {
614
+ headers["Content-type"].push(contentType);
615
+ }
616
+ else {
617
+ headers["Content-type"] = [contentType];
618
+ }
619
+ const schemaType = getSchemaExamples(spec, schema);
620
+ if (schemaType)
621
+ body = schemaType;
622
+ }
623
+ });
624
+ }
625
+ if (eSpec === null || eSpec === void 0 ? void 0 : eSpec.security) {
626
+ eSpec.security.forEach((securityItem) => {
627
+ Object.keys(securityItem).forEach((security) => {
628
+ var _a, _b;
629
+ const securitySchema = (_b = (_a = spec.components) === null || _a === void 0 ? void 0 : _a.securitySchemes) === null || _b === void 0 ? void 0 : _b[security];
630
+ if (securitySchema) {
631
+ // headers["Authorization"] = securitySchema;
632
+ if (securitySchema.type === "mutualTLS") {
633
+ extras += `\n--cert client-certificate.crt \
634
+ --key client-private-key.key \
635
+ --cacert ca-certificate.crt`;
636
+ }
637
+ else if (securitySchema.type === "apiKey") {
638
+ headers[(securitySchema === null || securitySchema === void 0 ? void 0 : securitySchema.name) || "X-API-KEY"] = `{API_KEY_VALUE}`;
639
+ }
640
+ else {
641
+ 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"}}`;
642
+ }
643
+ }
644
+ });
645
+ });
646
+ }
647
+ const curlHeaders = {};
648
+ Object.keys(headers).forEach((header) => {
649
+ if (Array.isArray(headers[header])) {
650
+ curlHeaders[header] = headers[header].join("; ");
651
+ }
652
+ else {
653
+ curlHeaders[header] = headers[header];
654
+ }
655
+ });
656
+ // console.log("curlHeaders", { headers, curlHeaders, body });
657
+ curl = `\n\`\`\`bash
658
+ ${(0, curl_generator_1.CurlGenerator)({
659
+ url: serverUrl + endpointPath,
660
+ method: method.toUpperCase(),
661
+ headers: curlHeaders,
662
+ body,
663
+ })}${extras}
664
+ \`\`\``;
665
+ }
666
+ doc = `/**${(eSpec === null || eSpec === void 0 ? void 0 : eSpec.description) ? `\n* ${eSpec === null || eSpec === void 0 ? void 0 : eSpec.description} ` : ""}
667
+ * **Method**: \`${method.toUpperCase()}\`
668
+ * **Summary**: ${(eSpec === null || eSpec === void 0 ? void 0 : eSpec.summary) || ""}
669
+ * **Tags**: [${((_p = eSpec === null || eSpec === void 0 ? void 0 : eSpec.tags) === null || _p === void 0 ? void 0 : _p.join(", ")) || ""}]
670
+ * **OperationId**: ${(eSpec === null || eSpec === void 0 ? void 0 : eSpec.operationId) || ""} ${queryTypeCnt
671
+ ? `\n * **Query**: ${(0, helpers_1.renderTypeRefMD)(queryTypeCnt)} `
672
+ : ""}${dtoTypeCnt ? `\n * **DTO**: ${(0, helpers_1.renderTypeRefMD)(dtoTypeCnt)} ` : ""}${responseTypeCnt
673
+ ? `\n * **Response**: ${Object.entries(responseTypeObject)
674
+ .map(([code, type]) => `\n - **${code}**: ${(0, helpers_1.renderTypeRefMD)(type, 2)} `)
675
+ .join("")}`
676
+ : ""}${securitySpec ? `\n * **Security**: ${securitySpec}\n` : ""}${curl}
677
+ */\n`;
678
+ }
679
+ // Add the endpoint url
680
+ endpointsFileContent += `${doc}export const ${endpointPrefix}${name} = ${endpointUrl};
681
+ `;
440
682
  });
441
683
  });
442
684
  // 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);