openapi-sync 1.0.25 → 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.
@@ -14,12 +14,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  const fs_1 = __importDefault(require("fs"));
16
16
  const path_1 = __importDefault(require("path"));
17
+ const lodash_1 = __importDefault(require("lodash"));
17
18
  const helpers_1 = require("./components/helpers");
18
- const lodash_1 = require("lodash");
19
+ const lodash_2 = require("lodash");
19
20
  const axios_1 = __importDefault(require("axios"));
20
21
  const axios_retry_1 = __importDefault(require("axios-retry"));
21
22
  const openapi_core_1 = require("@redocly/openapi-core");
22
23
  const state_1 = require("./state");
24
+ const curl_generator_1 = require("curl-generator");
23
25
  const rootUsingCwd = process.cwd();
24
26
  let fetchTimeout = {};
25
27
  // Create an Axios instance
@@ -37,7 +39,8 @@ const apiClient = axios_1.default.create({
37
39
  return retryCount * 1000; // Exponential back-off: 1s, 2s, 3s, etc.
38
40
  },
39
41
  });
40
- const OpenapiSync = (apiUrl, apiName, refetchInterval) => __awaiter(void 0, void 0, void 0, function* () {
42
+ const OpenapiSync = (apiUrl, apiName, config, refetchInterval) => __awaiter(void 0, void 0, void 0, function* () {
43
+ var _a, _b, _c, _d, _e;
41
44
  const specResponse = yield apiClient.get(apiUrl);
42
45
  const redoclyConfig = yield (0, openapi_core_1.createConfig)({
43
46
  extends: ["minimal"],
@@ -49,10 +52,261 @@ const OpenapiSync = (apiUrl, apiName, refetchInterval) => __awaiter(void 0, void
49
52
  source,
50
53
  config: redoclyConfig,
51
54
  });
52
- // Load config file
53
- const config = require(path_1.default.join(rootUsingCwd, "openapi.sync.json"));
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;
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
60
+ : "I";
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
63
+ : "";
64
+ const getSharedComponentName = (componentName, componentType) => {
65
+ var _a, _b;
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) {
67
+ const formattedName = config === null || config === void 0 ? void 0 : config.types.name.format("shared", {
68
+ name: componentName,
69
+ });
70
+ if (formattedName)
71
+ return `${typePrefix}${formattedName}`;
72
+ }
73
+ return `${typePrefix}${(0, helpers_1.capitalize)(componentName)}`;
74
+ };
75
+ const parseSchemaToType = (apiDoc, schema, name, isRequired, options, indentLevel = 0) => {
76
+ let overrideName = "";
77
+ let componentName = "";
78
+ let type = "";
79
+ if (schema) {
80
+ if (schema.$ref) {
81
+ if (schema.$ref[0] === "#") {
82
+ let pathToComponentParts = (schema.$ref || "").split("/");
83
+ pathToComponentParts.shift();
84
+ const partsClone = [...pathToComponentParts];
85
+ partsClone.pop();
86
+ const pathToComponent = pathToComponentParts;
87
+ const component = lodash_1.default.get(apiDoc, pathToComponent, null);
88
+ if (component) {
89
+ if (component === null || component === void 0 ? void 0 : component.name) {
90
+ overrideName = component.name;
91
+ }
92
+ componentName =
93
+ pathToComponentParts[pathToComponentParts.length - 1];
94
+ let name = getSharedComponentName(componentName);
95
+ if (name.includes(".")) {
96
+ const nameParts = name.split(".");
97
+ name = nameParts
98
+ .map((part, i) => {
99
+ if (i === 0) {
100
+ return part;
101
+ }
102
+ return `["${part}"]`;
103
+ })
104
+ .join("");
105
+ }
106
+ // Reference component via import instead of parsing
107
+ type += `${(options === null || options === void 0 ? void 0 : options.noSharedImport) ? "" : "Shared."}${name}`;
108
+ // type += `${parseSchemaToType(apiDoc, component, "", isRequired)}`;
109
+ }
110
+ }
111
+ else {
112
+ type += "";
113
+ //TODO $ref is a uri - use axios to fetch doc
114
+ }
115
+ }
116
+ else if (schema.anyOf) {
117
+ type += `(${schema.anyOf
118
+ .map((v) => parseSchemaToType(apiDoc, v, "", isRequired, options))
119
+ .join("|")})`;
120
+ }
121
+ else if (schema.oneOf) {
122
+ type += `(${schema.oneOf
123
+ .map((v) => parseSchemaToType(apiDoc, v, "", isRequired, options))
124
+ .join("|")})`;
125
+ }
126
+ else if (schema.allOf) {
127
+ type += `(${schema.allOf
128
+ .map((v) => parseSchemaToType(apiDoc, v, "", isRequired, options))
129
+ .join("&")})`;
130
+ }
131
+ else if (schema.items) {
132
+ type += `${parseSchemaToType(apiDoc, schema.items, "", false, options)}[]`;
133
+ }
134
+ else if (schema.properties) {
135
+ //parse object key one at a time
136
+ const objKeys = Object.keys(schema.properties);
137
+ const requiredKeys = schema.required || [];
138
+ let typeCnt = "";
139
+ objKeys.forEach((key) => {
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)}`;
151
+ });
152
+ if (typeCnt.length > 0) {
153
+ type += `{\n${" ".repeat(indentLevel)}${typeCnt}${" ".repeat(indentLevel)}}`;
154
+ }
155
+ else {
156
+ type += "{[k: string]: any}";
157
+ }
158
+ }
159
+ else if (schema.enum && schema.enum.length > 0) {
160
+ if (schema.enum.length > 1)
161
+ type += "(";
162
+ schema.enum.forEach((v) => {
163
+ let val = JSON.stringify(v);
164
+ if (val)
165
+ type += `|${val}`;
166
+ });
167
+ if (schema.enum.length > 1)
168
+ type += ")";
169
+ }
170
+ else if (schema.type) {
171
+ if (["string", "integer", "number", "array", "boolean"].includes(schema.type)) {
172
+ if (["integer", "number"].includes(schema.type)) {
173
+ type += `number`;
174
+ }
175
+ else if (schema.type === "array") {
176
+ //Since we would have already parsed the arrays keys above "schema.items" if it exists
177
+ type += "any[]";
178
+ /* if (schema.items) {
179
+ type += `${parseSchemaToType(
180
+ apiDoc,
181
+ schema.items,
182
+ "",
183
+ false,
184
+ options
185
+ )}[]`;
186
+ } else {
187
+ type += "any[]";
188
+ } */
189
+ }
190
+ else {
191
+ type += schema.type;
192
+ }
193
+ }
194
+ else if (schema.type === "object") {
195
+ //Since we would have already parsed the object keys above "schema.properties" if it exists
196
+ if (schema.additionalProperties) {
197
+ type += `{[k: string]: ${parseSchemaToType(apiDoc, schema.additionalProperties, "", true, options) || "any"}}`;
198
+ }
199
+ else {
200
+ type += "{[k: string]: any}";
201
+ }
202
+ }
203
+ }
204
+ }
205
+ else {
206
+ //Default type to string if no schema provided
207
+ type = "string";
208
+ }
209
+ let _name = overrideName || name;
210
+ if ((options === null || options === void 0 ? void 0 : options.useComponentName) && !_name) {
211
+ _name = componentName;
212
+ }
213
+ let typeName = _name ? `\t"${_name}"${isRequired ? "" : "?"}: ` : "";
214
+ const nullable = (schema === null || schema === void 0 ? void 0 : schema.nullable) ? " | null" : "";
215
+ return type.length > 0
216
+ ? `${typeName}${type}${nullable}${_name ? ";\n" : ""}`
217
+ : "";
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
+ };
56
310
  // auto update only on dev
57
311
  if (refetchInterval && !isNaN(refetchInterval) && refetchInterval > 0) {
58
312
  if (!(process.env.NODE_ENV &&
@@ -61,12 +315,12 @@ const OpenapiSync = (apiUrl, apiName, refetchInterval) => __awaiter(void 0, void
61
315
  if (fetchTimeout[apiName])
62
316
  clearTimeout(fetchTimeout[apiName]);
63
317
  // set next request timeout
64
- fetchTimeout[apiName] = setTimeout(() => OpenapiSync(apiUrl, apiName, refetchInterval), refetchInterval);
318
+ fetchTimeout[apiName] = setTimeout(() => OpenapiSync(apiUrl, apiName, config, refetchInterval), refetchInterval);
65
319
  }
66
320
  }
67
321
  // compare new spec with old spec, continuing only if spec it different
68
322
  const prevSpec = (0, state_1.getState)(apiName);
69
- if ((0, lodash_1.isEqual)(prevSpec, spec))
323
+ if ((0, lodash_2.isEqual)(prevSpec, spec))
70
324
  return;
71
325
  (0, state_1.setState)(apiName, spec);
72
326
  let endpointsFileContent = "";
@@ -86,10 +340,12 @@ const OpenapiSync = (apiUrl, apiName, refetchInterval) => __awaiter(void 0, void
86
340
  ].includes(key)) {
87
341
  // Create components (shared) types
88
342
  const components = spec.components[key];
343
+ const componentInterfaces = {};
344
+ const componentSchema = {};
89
345
  const contentKeys = Object.keys(components);
90
346
  // only need 1 schema so will us the first schema provided
91
347
  contentKeys.forEach((contentKey) => {
92
- var _a, _b;
348
+ var _a;
93
349
  /* const schema = (() => {
94
350
  switch (key) {
95
351
  case "parameters":
@@ -101,15 +357,61 @@ const OpenapiSync = (apiUrl, apiName, refetchInterval) => __awaiter(void 0, void
101
357
  const schema = (((_a = components[contentKey]) === null || _a === void 0 ? void 0 : _a.schema)
102
358
  ? components[contentKey].schema
103
359
  : components[contentKey]);
104
- const typeCnt = `${(0, helpers_1.parseSchemaToType)(spec, schema, "", true, {
360
+ const typeCnt = `${parseSchemaToType(spec, schema, "", true, {
105
361
  noSharedImport: true,
106
362
  useComponentName: ["parameters"].includes(key),
107
363
  })}`;
108
364
  if (typeCnt) {
109
- sharedTypesFileContent[key] =
110
- ((_b = sharedTypesFileContent[key]) !== null && _b !== void 0 ? _b : "") +
111
- `export type ${(0, helpers_1.getSharedComponentName)(contentKey)} = ${typeCnt};\n`;
365
+ const parts = contentKey.split(".");
366
+ let currentLevel = componentInterfaces;
367
+ let currentSchemaLevel = componentSchema;
368
+ // Navigate or create the nested structure
369
+ for (let i = 0; i < parts.length; i++) {
370
+ const part = parts[i];
371
+ if (i < parts.length - 1) {
372
+ // If it's not the last part, create a nested object if it doesn't exist
373
+ if (!(part in currentLevel)) {
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
376
+ }
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
379
+ }
380
+ else {
381
+ // This is the last part, assign the original schema value
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
384
+ }
385
+ }
386
+ }
387
+ });
388
+ // Generate TypeScript interfaces for each component
389
+ Object.keys(componentInterfaces).forEach((key) => {
390
+ var _a, _b, _c, _d;
391
+ const name = getSharedComponentName(key);
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)}`);
112
406
  }
407
+ sharedTypesFileContent[key] =
408
+ ((_d = sharedTypesFileContent[key]) !== null && _d !== void 0 ? _d : "") +
409
+ (doc ? `/**\n${doc}\n */\n` : "") +
410
+ "export type " +
411
+ name +
412
+ " = " +
413
+ (typeof cnt === "string" ? cnt : (0, helpers_1.JSONStringify)(cnt)) +
414
+ ";\n";
113
415
  });
114
416
  }
115
417
  });
@@ -120,17 +422,17 @@ const OpenapiSync = (apiUrl, apiName, refetchInterval) => __awaiter(void 0, void
120
422
  const contentKeys = Object.keys(requestBody.content);
121
423
  // only need 1 schema so will us the first schema provided
122
424
  if (contentKeys[0] && requestBody.content[contentKeys[0]].schema) {
123
- typeCnt += `${(0, helpers_1.parseSchemaToType)(spec, requestBody.content[contentKeys[0]].schema, "")}`;
425
+ typeCnt += `${parseSchemaToType(spec, requestBody.content[contentKeys[0]].schema, "")}`;
124
426
  }
125
427
  }
126
428
  return typeCnt;
127
429
  };
128
430
  const treatEndpointUrl = (endpointUrl) => {
129
- var _a, _b;
431
+ var _a, _b, _c, _d, _e;
130
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) &&
131
- Array.isArray(config.endpoints.value.replaceWords)) {
433
+ Array.isArray(config === null || config === void 0 ? void 0 : config.endpoints.value.replaceWords)) {
132
434
  let newEndpointUrl = endpointUrl;
133
- config.endpoints.value.replaceWords.forEach((replaceWord, indx) => {
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) => {
134
436
  const regexp = new RegExp(replaceWord.replace, "g");
135
437
  newEndpointUrl = newEndpointUrl.replace(regexp, replaceWord.with || "");
136
438
  });
@@ -143,29 +445,31 @@ const OpenapiSync = (apiUrl, apiName, refetchInterval) => __awaiter(void 0, void
143
445
  Object.keys(spec.paths || {}).forEach((endpointPath) => {
144
446
  const endpointSpec = spec.paths[endpointPath];
145
447
  const endpointMethods = Object.keys(endpointSpec);
146
- endpointMethods.forEach((method) => {
147
- var _a, _b, _c, _d, _e, _f;
448
+ endpointMethods.forEach((_method) => {
449
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
450
+ const method = _method;
148
451
  const endpoint = (0, helpers_1.getEndpointDetails)(endpointPath, method);
149
- const endpointUrlTxt = endpoint.pathParts
150
- .map((part) => {
151
- // check if part is a variable
152
- if (part[0] === "{" && part[part.length - 1] === "}") {
153
- const s = part.replace(/{/, "").replace(/}/, "");
154
- part = `\${${s}}`;
155
- }
156
- //api/<userId>
157
- else if (part[0] === "<" && part[part.length - 1] === ">") {
158
- const s = part.replace(/</, "").replace(/>/, "");
159
- part = `\${${s}}`;
160
- }
161
- //api/:userId
162
- else if (part[0] === ":") {
163
- const s = part.replace(/:/, "");
164
- part = `\${${s}}`;
165
- }
166
- return part;
167
- })
168
- .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("/");
169
473
  let endpointUrl = `"${endpointUrlTxt}"`;
170
474
  if (endpoint.variables.length > 0) {
171
475
  const params = endpoint.variables.map((v) => `${v}:string`).join(",");
@@ -173,41 +477,208 @@ const OpenapiSync = (apiUrl, apiName, refetchInterval) => __awaiter(void 0, void
173
477
  }
174
478
  //treat endpoint url
175
479
  endpointUrl = treatEndpointUrl(endpointUrl);
176
- // Add the endpoint url
177
- endpointsFileContent += `export const ${endpoint.name} = ${endpointUrl};
178
- `;
179
- if ((_a = endpointSpec[method]) === null || _a === void 0 ? void 0 : _a.parameters) {
480
+ const eSpec = endpointSpec[method];
481
+ let name = `${endpoint.name}`;
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({
484
+ method,
485
+ path: endpointPath,
486
+ summary: eSpec === null || eSpec === void 0 ? void 0 : eSpec.summary,
487
+ });
488
+ if (formattedName)
489
+ name = formattedName;
490
+ }
491
+ let queryTypeCnt = "";
492
+ if (eSpec === null || eSpec === void 0 ? void 0 : eSpec.parameters) {
180
493
  // create query parameters types
181
- const parameters = (_b = endpointSpec[method]) === null || _b === void 0 ? void 0 : _b.parameters;
182
- let typeCnt = "";
494
+ const parameters = eSpec === null || eSpec === void 0 ? void 0 : eSpec.parameters;
183
495
  parameters.forEach((param, i) => {
184
496
  if (param.$ref || (param.in === "query" && param.name)) {
185
- typeCnt += `${(0, helpers_1.parseSchemaToType)(spec, param.$ref ? param : param.schema, param.name || "", param.required)}`;
497
+ queryTypeCnt += `${parseSchemaToType(spec, param.$ref ? param : param.schema, param.name || "", param.required)}`;
186
498
  }
187
499
  });
188
- if (typeCnt) {
189
- typesFileContent += `export type I${endpoint.name}Query = {\n${typeCnt}};\n`;
500
+ if (queryTypeCnt) {
501
+ queryTypeCnt = `{\n${queryTypeCnt}}`;
502
+ let name = `${endpoint.name}Query`;
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", {
505
+ code: "",
506
+ type: "query",
507
+ method,
508
+ path: endpointPath,
509
+ summary: eSpec === null || eSpec === void 0 ? void 0 : eSpec.summary,
510
+ });
511
+ if (formattedName)
512
+ name = formattedName;
513
+ }
514
+ typesFileContent += `export type ${typePrefix}${name} = ${queryTypeCnt};\n`;
190
515
  }
191
516
  }
192
- if ((_c = endpointSpec[method]) === null || _c === void 0 ? void 0 : _c.requestBody) {
517
+ const requestBody = eSpec === null || eSpec === void 0 ? void 0 : eSpec.requestBody;
518
+ let dtoTypeCnt = "";
519
+ if (requestBody) {
193
520
  //create requestBody types
194
- const requestBody = (_d = endpointSpec[method]) === null || _d === void 0 ? void 0 : _d.requestBody;
195
- let typeCnt = getBodySchemaType(requestBody);
196
- if (typeCnt) {
197
- typesFileContent += `export type I${endpoint.name}DTO = ${typeCnt};\n`;
521
+ dtoTypeCnt = getBodySchemaType(requestBody);
522
+ if (dtoTypeCnt) {
523
+ let name = `${endpoint.name}DTO`;
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", {
526
+ code: "",
527
+ type: "dto",
528
+ method,
529
+ path: endpointPath,
530
+ summary: eSpec === null || eSpec === void 0 ? void 0 : eSpec.summary,
531
+ });
532
+ if (formattedName)
533
+ name = formattedName;
534
+ }
535
+ typesFileContent += `export type ${typePrefix}${name} = ${dtoTypeCnt};\n`;
198
536
  }
199
537
  }
200
- if ((_e = endpointSpec[method]) === null || _e === void 0 ? void 0 : _e.responses) {
538
+ const responseTypeObject = {};
539
+ let responseTypeCnt = "";
540
+ if (eSpec === null || eSpec === void 0 ? void 0 : eSpec.responses) {
201
541
  // create request response types
202
- const responses = (_f = endpointSpec[method]) === null || _f === void 0 ? void 0 : _f.responses;
542
+ const responses = eSpec === null || eSpec === void 0 ? void 0 : eSpec.responses;
203
543
  const resCodes = Object.keys(responses);
204
544
  resCodes.forEach((code) => {
205
- let typeCnt = getBodySchemaType(responses[code]);
206
- if (typeCnt) {
207
- typesFileContent += `export type I${endpoint.name}${code}Response = ${typeCnt};\n`;
545
+ var _a, _b;
546
+ responseTypeCnt = getBodySchemaType(responses[code]);
547
+ responseTypeObject[code] = responseTypeCnt;
548
+ if (responseTypeCnt) {
549
+ let name = `${endpoint.name}${code}Response`;
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) {
551
+ const formattedName = config === null || config === void 0 ? void 0 : config.types.name.format("endpoint", {
552
+ code,
553
+ type: "response",
554
+ method,
555
+ path: endpointPath,
556
+ summary: eSpec === null || eSpec === void 0 ? void 0 : eSpec.summary,
557
+ });
558
+ if (formattedName)
559
+ name = formattedName;
560
+ }
561
+ typesFileContent += `export type ${typePrefix}${name} = ${responseTypeCnt};\n`;
208
562
  }
209
563
  });
210
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
+ `;
211
682
  });
212
683
  });
213
684
  // Create the necessary directories