openapi-sync 2.1.10 → 2.1.12

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.
@@ -1,862 +0,0 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- var __importDefault = (this && this.__importDefault) || function (mod) {
12
- return (mod && mod.__esModule) ? mod : { "default": mod };
13
- };
14
- Object.defineProperty(exports, "__esModule", { value: true });
15
- const fs_1 = __importDefault(require("fs"));
16
- const path_1 = __importDefault(require("path"));
17
- const lodash_1 = __importDefault(require("lodash"));
18
- const helpers_1 = require("../helpers");
19
- const lodash_2 = require("lodash");
20
- const axios_1 = __importDefault(require("axios"));
21
- const axios_retry_1 = __importDefault(require("axios-retry"));
22
- const openapi_core_1 = require("@redocly/openapi-core");
23
- const state_1 = require("./state");
24
- const curl_generator_1 = require("curl-generator");
25
- const rootUsingCwd = process.cwd();
26
- let fetchTimeout = {};
27
- // Create an Axios instance
28
- const apiClient = axios_1.default.create({
29
- timeout: 60000, // Timeout after 1min
30
- });
31
- // Configure axios-retry
32
- (0, axios_retry_1.default)(apiClient, {
33
- retries: 20, // Number of retry attempts
34
- retryCondition: (error) => {
35
- // Retry on network error
36
- return (error.code === "ECONNABORTED" || error.message.includes("Network Error"));
37
- },
38
- retryDelay: (retryCount) => {
39
- return retryCount * 1000; // Exponential back-off: 1s, 2s, 3s, etc.
40
- },
41
- });
42
- const OpenapiSync = (apiUrl, apiName, config, refetchInterval) => __awaiter(void 0, void 0, void 0, function* () {
43
- var _a, _b, _c, _d, _e, _f;
44
- const specResponse = yield apiClient.get(apiUrl);
45
- const redoclyConfig = yield (0, openapi_core_1.createConfig)({
46
- extends: ["minimal"],
47
- });
48
- const source = JSON.stringify((0, helpers_1.isJson)(specResponse.data)
49
- ? specResponse.data
50
- : (0, helpers_1.yamlStringToJson)(specResponse.data));
51
- const lintResults = yield (0, openapi_core_1.bundleFromString)({
52
- source,
53
- config: redoclyConfig,
54
- });
55
- const folderPath = path_1.default.join((config === null || config === void 0 ? void 0 : config.folder) || "", apiName);
56
- const spec = lintResults.bundle.parsed;
57
- const serverUrl = typeof (config === null || config === void 0 ? void 0 : config.server) === "string"
58
- ? config === null || config === void 0 ? void 0 : config.server
59
- : ((_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) || "";
60
- 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"
61
- ? config === null || config === void 0 ? void 0 : config.types.name.prefix
62
- : "I";
63
- 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"
64
- ? config === null || config === void 0 ? void 0 : config.endpoints.name.prefix
65
- : "";
66
- const getSharedComponentName = (componentName, componentType) => {
67
- var _a, _b;
68
- const defaultName = (0, helpers_1.capitalize)(componentName);
69
- 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) {
70
- const formattedName = config === null || config === void 0 ? void 0 : config.types.name.format("shared", {
71
- name: componentName,
72
- }, defaultName);
73
- if (formattedName)
74
- return `${typePrefix}${formattedName}`;
75
- }
76
- return `${typePrefix}${defaultName}`;
77
- };
78
- const parseSchemaToType = (apiDoc, schema, name, isRequired, options, indentLevel = 0) => {
79
- let overrideName = "";
80
- let componentName = "";
81
- let type = "";
82
- if (schema) {
83
- if (schema.$ref) {
84
- if (schema.$ref[0] === "#") {
85
- let pathToComponentParts = (schema.$ref || "").split("/");
86
- pathToComponentParts.shift();
87
- const partsClone = [...pathToComponentParts];
88
- partsClone.pop();
89
- const pathToComponent = pathToComponentParts;
90
- const component = lodash_1.default.get(apiDoc, pathToComponent, null);
91
- if (component) {
92
- if (component === null || component === void 0 ? void 0 : component.name) {
93
- overrideName = component.name;
94
- }
95
- componentName =
96
- pathToComponentParts[pathToComponentParts.length - 1];
97
- let name = getSharedComponentName(componentName);
98
- if (name.includes(".")) {
99
- const nameParts = name.split(".");
100
- name = nameParts
101
- .map((part, i) => {
102
- if (i === 0) {
103
- return part;
104
- }
105
- return `["${part}"]`;
106
- })
107
- .join("");
108
- }
109
- // Reference component via import instead of parsing
110
- type += `${(options === null || options === void 0 ? void 0 : options.noSharedImport) ? "" : "Shared."}${name}`;
111
- // type += `${parseSchemaToType(apiDoc, component, "", isRequired)}`;
112
- }
113
- }
114
- else {
115
- type += "";
116
- //TODO $ref is a uri - use axios to fetch doc
117
- }
118
- }
119
- else if (schema.anyOf) {
120
- type += `(${schema.anyOf
121
- .map((v) => parseSchemaToType(apiDoc, v, "", isRequired, options))
122
- .filter((v) => !!v)
123
- .join("|")})`;
124
- }
125
- else if (schema.oneOf) {
126
- type += `(${schema.oneOf
127
- .map((v) => parseSchemaToType(apiDoc, v, "", isRequired, options))
128
- .filter((v) => !!v)
129
- .join("|")})`;
130
- }
131
- else if (schema.allOf) {
132
- type += `(${schema.allOf
133
- .map((v) => parseSchemaToType(apiDoc, v, "", isRequired, options))
134
- .filter((v) => !!v)
135
- .join("&")})`;
136
- }
137
- else if (schema.items) {
138
- type += `${parseSchemaToType(apiDoc, schema.items, "", false, options)}[]`;
139
- }
140
- else if (schema.properties) {
141
- //parse object key one at a time
142
- const objKeys = Object.keys(schema.properties);
143
- const requiredKeys = schema.required || [];
144
- let typeCnt = "";
145
- objKeys.forEach((key) => {
146
- var _a, _b, _c, _d, _e, _f;
147
- let doc = "";
148
- 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) &&
149
- ((_d = (_c = schema.properties) === null || _c === void 0 ? void 0 : _c[key]) === null || _d === void 0 ? void 0 : _d.description)) {
150
- doc =
151
- " * " +
152
- ((_e = schema.properties) === null || _e === void 0 ? void 0 : _e[key].description.split("\n").filter((line) => line.trim() !== "").join(` \n *${" ".repeat(1)}`));
153
- }
154
- typeCnt +=
155
- (doc ? `/**\n${doc}\n */\n` : "") +
156
- `${parseSchemaToType(apiDoc, (_f = schema.properties) === null || _f === void 0 ? void 0 : _f[key], key, requiredKeys.includes(key), options, indentLevel + 1)}`;
157
- });
158
- if (typeCnt.length > 0) {
159
- type += `{\n${" ".repeat(indentLevel)}${typeCnt}${" ".repeat(indentLevel)}}`;
160
- }
161
- else {
162
- type += "{[k: string]: any}";
163
- }
164
- }
165
- else if (schema.enum && schema.enum.length > 0) {
166
- if (schema.enum.length > 1)
167
- type += "(";
168
- schema.enum
169
- .map((v) => JSON.stringify(v))
170
- .filter((v) => !!v)
171
- .forEach((v, i) => {
172
- type += `${i === 0 ? "" : "|"}${v}`;
173
- });
174
- if (schema.enum.length > 1)
175
- type += ")";
176
- }
177
- else if (schema.type) {
178
- const handleType = (_type) => {
179
- let typeCnt = "";
180
- if (typeof _type === "string") {
181
- if ([
182
- "string",
183
- "integer",
184
- "number",
185
- "array",
186
- "boolean",
187
- "null",
188
- ].includes(_type)) {
189
- if (["integer", "number"].includes(_type)) {
190
- typeCnt += `number`;
191
- }
192
- else if (_type === "array") {
193
- //Since we would have already parsed the arrays keys above "schema.items" if it exists
194
- typeCnt += "any[]";
195
- /* if (schema.items) {
196
- typeCnt += `${parseSchemaToType(
197
- apiDoc,
198
- schema.items,
199
- "",
200
- false,
201
- options
202
- )}[]`;
203
- } else {
204
- typeCnt += "any[]";
205
- } */
206
- }
207
- else {
208
- typeCnt += _type;
209
- }
210
- }
211
- else if (_type === "object") {
212
- //Since we would have already parsed the object keys above "schema.properties" if it exists
213
- if (schema.additionalProperties) {
214
- typeCnt += `{[k: string]: ${parseSchemaToType(apiDoc, schema.additionalProperties, "", true, options) || "any"}}`;
215
- }
216
- else {
217
- typeCnt += "{[k: string]: any}";
218
- }
219
- }
220
- }
221
- else if (Array.isArray(_type)) {
222
- const arrType = _type.map((v) => handleType(v));
223
- arrType.filter((v) => v !== "");
224
- if (arrType.length > 1)
225
- typeCnt += "(" + arrType.join("|") + ")";
226
- }
227
- else {
228
- typeCnt += "any";
229
- }
230
- return typeCnt;
231
- };
232
- type = handleType(schema.type);
233
- }
234
- }
235
- else {
236
- //Default type to string if no schema provided
237
- type = "string";
238
- }
239
- let _name = overrideName || name;
240
- if ((options === null || options === void 0 ? void 0 : options.useComponentName) && !_name) {
241
- _name = componentName;
242
- }
243
- let typeName = _name ? `\t"${_name}"${isRequired ? "" : "?"}: ` : "";
244
- const nullable = (schema === null || schema === void 0 ? void 0 : schema.nullable) ? " | null" : "";
245
- return type.length > 0
246
- ? `${typeName}${type}${nullable}${_name ? ";\n" : ""}`
247
- : "";
248
- };
249
- const getSchemaExamples = (apiDoc, schema) => {
250
- let overrideName = "";
251
- let componentName = "";
252
- let type = "";
253
- if (schema) {
254
- if (schema.$ref) {
255
- if (schema.$ref[0] === "#") {
256
- let pathToComponentParts = (schema.$ref || "").split("/");
257
- pathToComponentParts.shift();
258
- const pathToComponent = pathToComponentParts;
259
- const component = lodash_1.default.get(apiDoc, pathToComponent, null);
260
- if (component) {
261
- if (component === null || component === void 0 ? void 0 : component.name) {
262
- overrideName = component.name;
263
- }
264
- componentName =
265
- pathToComponentParts[pathToComponentParts.length - 1];
266
- type += getSchemaExamples(apiDoc, component);
267
- }
268
- }
269
- else {
270
- type += "";
271
- //TODO $ref is a uri - use axios to fetch doc
272
- }
273
- }
274
- else if (schema.anyOf) {
275
- type += getSchemaExamples(apiDoc, schema.anyOf[0]);
276
- }
277
- else if (schema.oneOf) {
278
- type += getSchemaExamples(apiDoc, schema.oneOf[0]);
279
- }
280
- else if (schema.allOf) {
281
- type += `{${schema.allOf
282
- .map((v) => `...(${getSchemaExamples(apiDoc, v)})`)
283
- .join(",")}}`;
284
- }
285
- else if (schema.items) {
286
- type += `[${getSchemaExamples(apiDoc, schema.items)}]`;
287
- }
288
- else if (schema.properties) {
289
- //parse object key one at a time
290
- const objKeys = Object.keys(schema.properties);
291
- const arr = objKeys.map((key) => {
292
- var _a;
293
- return ` "${key}": ${getSchemaExamples(apiDoc, (_a = schema.properties) === null || _a === void 0 ? void 0 : _a[key])}`;
294
- });
295
- let typeCnt = arr.join(",\n");
296
- if (typeCnt.length > 0) {
297
- type += `{\n${typeCnt}\n }`;
298
- }
299
- else {
300
- type += "{}";
301
- }
302
- }
303
- else if (schema.enum && schema.enum.length > 0) {
304
- if (schema.enum.length > 1)
305
- type += schema.enum[0];
306
- }
307
- else if (schema.type) {
308
- if (schema.example) {
309
- type += JSON.stringify(schema.example);
310
- }
311
- else {
312
- const handleType = (_type) => {
313
- let typeCnt = "";
314
- if (typeof _type === "string") {
315
- if ([
316
- "string",
317
- "integer",
318
- "number",
319
- "array",
320
- "boolean",
321
- "null",
322
- ].includes(_type)) {
323
- if (["integer", "number"].includes(_type)) {
324
- typeCnt += `123`;
325
- }
326
- else if (_type === "array") {
327
- //Since we would have already parsed the arrays keys above "schema.items" if it exists
328
- typeCnt += "[]";
329
- }
330
- else if (_type === "boolean") {
331
- typeCnt += `true`;
332
- }
333
- else if (_type === "null") {
334
- typeCnt += `null`;
335
- }
336
- else {
337
- typeCnt += `"${_type}"`;
338
- }
339
- }
340
- else if (_type === "object") {
341
- //Since we would have already parsed the object keys above "schema.properties" if it exists
342
- typeCnt += "{}";
343
- }
344
- }
345
- else if (Array.isArray(_type)) {
346
- const arrType = _type.map((v) => handleType(v));
347
- arrType.filter((v) => v !== "");
348
- if (arrType.length > 1)
349
- typeCnt += arrType.join("|");
350
- }
351
- else {
352
- typeCnt += "any";
353
- }
354
- return typeCnt;
355
- };
356
- type = handleType(schema.type);
357
- }
358
- }
359
- }
360
- else {
361
- //Default type to string if no schema provided
362
- type = "string";
363
- }
364
- return type;
365
- };
366
- // auto update only on dev
367
- if (refetchInterval && !isNaN(refetchInterval) && refetchInterval > 0) {
368
- if (!(process.env.NODE_ENV &&
369
- ["production", "prod", "test", "staging"].includes(process.env.NODE_ENV))) {
370
- // auto sync at interval
371
- if (fetchTimeout[apiName])
372
- clearTimeout(fetchTimeout[apiName]);
373
- // set next request timeout
374
- fetchTimeout[apiName] = setTimeout(() => OpenapiSync(apiUrl, apiName, config, refetchInterval), refetchInterval);
375
- }
376
- }
377
- // compare new spec with old spec, continuing only if spec it different
378
- const prevSpec = (0, state_1.getState)(apiName);
379
- if ((0, lodash_2.isEqual)(prevSpec, spec))
380
- return;
381
- (0, state_1.setState)(apiName, spec);
382
- let endpointsFileContent = "";
383
- let typesFileContent = "";
384
- let sharedTypesFileContent = {};
385
- if (spec.components) {
386
- Object.keys(spec.components).forEach((key) => {
387
- if ([
388
- "schemas",
389
- "responses",
390
- "parameters",
391
- "examples",
392
- "requestBodies",
393
- "headers",
394
- "links",
395
- "callbacks",
396
- ].includes(key)) {
397
- // Create components (shared) types
398
- const components = spec.components[key];
399
- const componentInterfaces = {};
400
- const componentSchema = {};
401
- const contentKeys = Object.keys(components);
402
- // only need 1 schema so will us the first schema provided
403
- contentKeys.forEach((contentKey) => {
404
- var _a;
405
- /* const schema = (() => {
406
- switch (key) {
407
- case "parameters":
408
- return components[contentKey].schema;
409
- default:
410
- return components[contentKey];
411
- }
412
- })() as IOpenApSchemaSpec; */
413
- const schema = (((_a = components[contentKey]) === null || _a === void 0 ? void 0 : _a.schema)
414
- ? components[contentKey].schema
415
- : components[contentKey]);
416
- const typeCnt = `${parseSchemaToType(spec, schema, "", true, {
417
- noSharedImport: true,
418
- useComponentName: ["parameters"].includes(key),
419
- })}`;
420
- if (typeCnt) {
421
- const parts = contentKey.split(".");
422
- let currentLevel = componentInterfaces;
423
- let currentSchemaLevel = componentSchema;
424
- // Navigate or create the nested structure
425
- for (let i = 0; i < parts.length; i++) {
426
- const part = parts[i];
427
- if (i < parts.length - 1) {
428
- // If it's not the last part, create a nested object if it doesn't exist
429
- if (!(part in currentLevel)) {
430
- currentLevel[part] = {}; //<== This rely on js ability to assign value to origianl object by reference, so this assignment will be reflected in componentInterfaces
431
- currentSchemaLevel[part] = {}; //<== This rely on js ability to assign value to origianl object by reference, so this assignment will be reflected in componentSchema
432
- }
433
- currentLevel = currentLevel[part]; //<== This rely on js ability to assign value to origianl object by reference, so this assignment will be reflected in componentInterfaces
434
- currentSchemaLevel = currentSchemaLevel[part]; //<== This rely on js ability to assign value to origianl object by reference, so this assignment will be reflected in componentSchema
435
- }
436
- else {
437
- // This is the last part, assign the original schema value
438
- currentLevel[part] = typeCnt; //<== This rely on js ability to assign value to origianl object by reference, so this assignment will be reflected in componentInterfaces
439
- currentSchemaLevel[part] = schema; //<== This rely on js ability to assign value to origianl object by reference, so this assignment will be reflected in componentSchema
440
- }
441
- }
442
- }
443
- });
444
- // Generate TypeScript interfaces for each component
445
- Object.keys(componentInterfaces).forEach((key) => {
446
- var _a, _b, _c, _d;
447
- const name = getSharedComponentName(key);
448
- const cnt = componentInterfaces[key];
449
- let doc = "";
450
- 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) &&
451
- key in components &&
452
- (
453
- //@ts-expect-error
454
- (_c = components[key]) === null || _c === void 0 ? void 0 : _c.description)) {
455
- doc =
456
- " * " +
457
- //@ts-expect-error
458
- components[key].description
459
- .split("\n")
460
- .filter((line) => line.trim() !== "")
461
- .join(` \n *${" ".repeat(1)}`);
462
- }
463
- sharedTypesFileContent[key] =
464
- ((_d = sharedTypesFileContent[key]) !== null && _d !== void 0 ? _d : "") +
465
- (doc ? `/**\n${doc}\n */\n` : "") +
466
- "export type " +
467
- name +
468
- " = " +
469
- (typeof cnt === "string" ? cnt : (0, helpers_1.JSONStringify)(cnt)) +
470
- ";\n";
471
- });
472
- }
473
- });
474
- }
475
- const getBodySchemaType = (requestBody) => {
476
- let typeCnt = "";
477
- if (requestBody.content) {
478
- const contentKeys = Object.keys(requestBody.content);
479
- // only need 1 schema so will us the first schema provided
480
- if (contentKeys[0] && requestBody.content[contentKeys[0]].schema) {
481
- typeCnt += `${parseSchemaToType(spec, requestBody.content[contentKeys[0]].schema, "")}`;
482
- }
483
- }
484
- return typeCnt;
485
- };
486
- const treatEndpointUrl = (endpointUrl) => {
487
- var _a, _b, _c, _d, _e;
488
- 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) &&
489
- Array.isArray(config === null || config === void 0 ? void 0 : config.endpoints.value.replaceWords)) {
490
- let newEndpointUrl = endpointUrl;
491
- (_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) => {
492
- const regexp = new RegExp(replaceWord.replace, "g");
493
- newEndpointUrl = newEndpointUrl.replace(regexp, replaceWord.with || "");
494
- });
495
- return newEndpointUrl;
496
- }
497
- else {
498
- return endpointUrl;
499
- }
500
- };
501
- // Helper function to check if an endpoint should be excluded
502
- const shouldExcludeEndpoint = (path, method, tags = []) => {
503
- var _a, _b;
504
- const excludeConfig = (_a = config === null || config === void 0 ? void 0 : config.endpoints) === null || _a === void 0 ? void 0 : _a.exclude;
505
- const includeConfig = (_b = config === null || config === void 0 ? void 0 : config.endpoints) === null || _b === void 0 ? void 0 : _b.include;
506
- // If include is specified
507
- if (includeConfig) {
508
- // Check if endpoint matches include criteria
509
- const matchesIncludeTags = includeConfig.tags && includeConfig.tags.length > 0
510
- ? tags.some((tag) => includeConfig.tags.includes(tag))
511
- : true;
512
- const matchesIncludeEndpoints = includeConfig.endpoints && includeConfig.endpoints.length > 0
513
- ? includeConfig.endpoints.some((endpoint) => {
514
- const methodMatches = !endpoint.method ||
515
- endpoint.method.toLowerCase() === method.toLowerCase();
516
- // Use exact path match if path is provided
517
- if (endpoint.path) {
518
- return path === endpoint.path && methodMatches;
519
- }
520
- // Use regex match if regex is provided
521
- else if (endpoint.regex) {
522
- const pathRegex = new RegExp(endpoint.regex);
523
- return pathRegex.test(path) && methodMatches;
524
- }
525
- return false;
526
- })
527
- : true;
528
- // If include is specified but endpoint doesn't match, exclude it
529
- if (!matchesIncludeTags || !matchesIncludeEndpoints) {
530
- return true;
531
- }
532
- }
533
- // Check exclude criteria, it takes precedence over include
534
- if (excludeConfig) {
535
- // Check tags exclusion
536
- if (excludeConfig.tags && excludeConfig.tags.length > 0) {
537
- const hasExcludedTag = tags.some((tag) => excludeConfig.tags.includes(tag));
538
- if (hasExcludedTag)
539
- return true;
540
- }
541
- // Check endpoint exclusion
542
- if (excludeConfig.endpoints && excludeConfig.endpoints.length > 0) {
543
- const matchesExcludedEndpoint = excludeConfig.endpoints.some((endpoint) => {
544
- const methodMatches = !endpoint.method ||
545
- endpoint.method.toLowerCase() === method.toLowerCase();
546
- // Use exact path match if path is provided
547
- if (endpoint.path) {
548
- return path === endpoint.path && methodMatches;
549
- }
550
- // Use regex match if regex is provided
551
- else if (endpoint.regex) {
552
- const pathRegex = new RegExp(endpoint.regex);
553
- return pathRegex.test(path) && methodMatches;
554
- }
555
- return false;
556
- });
557
- if (matchesExcludedEndpoint)
558
- return true;
559
- }
560
- }
561
- return false;
562
- };
563
- Object.keys(spec.paths || {}).forEach((endpointPath) => {
564
- const endpointSpec = spec.paths[endpointPath];
565
- const endpointMethods = Object.keys(endpointSpec);
566
- endpointMethods.forEach((_method) => {
567
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z;
568
- const method = _method;
569
- const endpoint = (0, helpers_1.getEndpointDetails)(endpointPath, method);
570
- // Get endpoint tags for filtering
571
- const endpointTags = ((_a = endpointSpec[method]) === null || _a === void 0 ? void 0 : _a.tags) || [];
572
- // Check if this endpoint should be excluded
573
- if (shouldExcludeEndpoint(endpointPath, method, endpointTags)) {
574
- return; // Skip this endpoint
575
- }
576
- const endpointUrlTxt = (((_c = (_b = config === null || config === void 0 ? void 0 : config.endpoints) === null || _b === void 0 ? void 0 : _b.value) === null || _c === void 0 ? void 0 : _c.includeServer) ? serverUrl : "") +
577
- endpoint.pathParts
578
- .map((part) => {
579
- // check if part is a variable
580
- if (part[0] === "{" && part[part.length - 1] === "}") {
581
- const s = part.replace(/{/, "").replace(/}/, "");
582
- part = `\${${s}}`;
583
- }
584
- //api/<userId>
585
- else if (part[0] === "<" && part[part.length - 1] === ">") {
586
- const s = part.replace(/</, "").replace(/>/, "");
587
- part = `\${${s}}`;
588
- }
589
- //api/:userId
590
- else if (part[0] === ":") {
591
- const s = part.replace(/:/, "");
592
- part = `\${${s}}`;
593
- }
594
- return part;
595
- })
596
- .join("/");
597
- let endpointUrl = `"${endpointUrlTxt}"`;
598
- if (endpoint.variables.length > 0) {
599
- const params = endpoint.variables.map((v) => `${v}:string`).join(",");
600
- endpointUrl = `(${params})=> \`${endpointUrlTxt}\``;
601
- }
602
- //treat endpoint url
603
- endpointUrl = treatEndpointUrl(endpointUrl);
604
- const eSpec = endpointSpec[method];
605
- let queryTypeCnt = "";
606
- if (eSpec === null || eSpec === void 0 ? void 0 : eSpec.parameters) {
607
- // create query parameters types
608
- const parameters = eSpec === null || eSpec === void 0 ? void 0 : eSpec.parameters;
609
- parameters.forEach((param, i) => {
610
- if (param.$ref || (param.in === "query" && param.name)) {
611
- queryTypeCnt += `${parseSchemaToType(spec, param.$ref ? param : param.schema, param.name || "", param.required)}`;
612
- }
613
- });
614
- if (queryTypeCnt) {
615
- queryTypeCnt = `{\n${queryTypeCnt}}`;
616
- let name = `${endpoint.name}Query`;
617
- // Use operationId if configured and available
618
- if (((_e = (_d = config === null || config === void 0 ? void 0 : config.types) === null || _d === void 0 ? void 0 : _d.name) === null || _e === void 0 ? void 0 : _e.useOperationId) && (eSpec === null || eSpec === void 0 ? void 0 : eSpec.operationId)) {
619
- name = `${eSpec.operationId}Query`;
620
- }
621
- name = (0, helpers_1.capitalize)(`${typePrefix}${name}`);
622
- 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) {
623
- const formattedName = config === null || config === void 0 ? void 0 : config.types.name.format("endpoint", {
624
- code: "",
625
- type: "query",
626
- method,
627
- path: endpointPath,
628
- summary: eSpec === null || eSpec === void 0 ? void 0 : eSpec.summary,
629
- operationId: eSpec === null || eSpec === void 0 ? void 0 : eSpec.operationId,
630
- }, name);
631
- if (formattedName)
632
- name = `${typePrefix}${formattedName}`;
633
- }
634
- typesFileContent += `export type ${name} = ${queryTypeCnt};\n`;
635
- }
636
- }
637
- const requestBody = eSpec === null || eSpec === void 0 ? void 0 : eSpec.requestBody;
638
- let dtoTypeCnt = "";
639
- if (requestBody) {
640
- //create requestBody types
641
- dtoTypeCnt = getBodySchemaType(requestBody);
642
- if (dtoTypeCnt) {
643
- let name = `${endpoint.name}DTO`;
644
- // Use operationId if configured and available
645
- if (((_j = (_h = config === null || config === void 0 ? void 0 : config.types) === null || _h === void 0 ? void 0 : _h.name) === null || _j === void 0 ? void 0 : _j.useOperationId) && (eSpec === null || eSpec === void 0 ? void 0 : eSpec.operationId)) {
646
- name = `${eSpec.operationId}DTO`;
647
- }
648
- name = (0, helpers_1.capitalize)(`${typePrefix}${name}`);
649
- if ((_l = (_k = config === null || config === void 0 ? void 0 : config.types) === null || _k === void 0 ? void 0 : _k.name) === null || _l === void 0 ? void 0 : _l.format) {
650
- const formattedName = config === null || config === void 0 ? void 0 : config.types.name.format("endpoint", {
651
- code: "",
652
- type: "dto",
653
- method,
654
- path: endpointPath,
655
- summary: eSpec === null || eSpec === void 0 ? void 0 : eSpec.summary,
656
- operationId: eSpec === null || eSpec === void 0 ? void 0 : eSpec.operationId,
657
- }, name);
658
- if (formattedName)
659
- name = `${typePrefix}${formattedName}`;
660
- }
661
- typesFileContent += `export type ${name} = ${dtoTypeCnt};\n`;
662
- }
663
- }
664
- const responseTypeObject = {};
665
- let responseTypeCnt = "";
666
- if (eSpec === null || eSpec === void 0 ? void 0 : eSpec.responses) {
667
- // create request response types
668
- const responses = eSpec === null || eSpec === void 0 ? void 0 : eSpec.responses;
669
- const resCodes = Object.keys(responses);
670
- resCodes.forEach((code) => {
671
- var _a, _b, _c, _d;
672
- responseTypeCnt = getBodySchemaType(responses[code]);
673
- responseTypeObject[code] = responseTypeCnt;
674
- if (responseTypeCnt) {
675
- let name = `${endpoint.name}${code}Response`;
676
- // Use operationId if configured and available
677
- 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.useOperationId) && (eSpec === null || eSpec === void 0 ? void 0 : eSpec.operationId)) {
678
- name = `${eSpec.operationId}${code}Response`;
679
- }
680
- name = (0, helpers_1.capitalize)(`${typePrefix}${name}`);
681
- 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) {
682
- const formattedName = config === null || config === void 0 ? void 0 : config.types.name.format("endpoint", {
683
- code,
684
- type: "response",
685
- method,
686
- path: endpointPath,
687
- summary: eSpec === null || eSpec === void 0 ? void 0 : eSpec.summary,
688
- operationId: eSpec === null || eSpec === void 0 ? void 0 : eSpec.operationId,
689
- }, name);
690
- if (formattedName)
691
- name = `${typePrefix}${formattedName}`;
692
- }
693
- typesFileContent += `export type ${name} = ${responseTypeCnt};\n`;
694
- }
695
- });
696
- }
697
- // Function to format security requirements
698
- const formatSecuritySpec = (security) => {
699
- if (!security || !security.length)
700
- return "";
701
- return security
702
- .map((securityRequirement) => {
703
- const requirements = Object.entries(securityRequirement)
704
- .map(([scheme, scopes]) => {
705
- let sch = scheme;
706
- let scopeText = "";
707
- if (Array.isArray(scopes) && scopes.length) {
708
- scopeText = `\n - Scopes: [\`${scopes.join("`, `")}\`]`;
709
- sch = `**${sch}**`;
710
- }
711
- return `\n - ${sch}${scopeText}`;
712
- })
713
- .join("");
714
- return requirements;
715
- })
716
- .join("\n");
717
- };
718
- // Get formatted security specification
719
- const securitySpec = (eSpec === null || eSpec === void 0 ? void 0 : eSpec.security)
720
- ? formatSecuritySpec(eSpec.security)
721
- : "";
722
- let doc = "";
723
- if (!((_o = (_m = config === null || config === void 0 ? void 0 : config.endpoints) === null || _m === void 0 ? void 0 : _m.doc) === null || _o === void 0 ? void 0 : _o.disable)) {
724
- let curl = "";
725
- if ((_q = (_p = config === null || config === void 0 ? void 0 : config.endpoints) === null || _p === void 0 ? void 0 : _p.doc) === null || _q === void 0 ? void 0 : _q.showCurl) {
726
- // console.log("cirl data", {
727
- // body: eSpec?.requestBody,
728
- // bodyContent:
729
- // eSpec?.requestBody?.content["application/json"]?.schema
730
- // ?.properties,
731
- // security: eSpec?.security,
732
- // });
733
- const headers = {};
734
- let body = "";
735
- let extras = "";
736
- if ((_r = eSpec.requestBody) === null || _r === void 0 ? void 0 : _r.content) {
737
- const contentTypes = Object.keys(eSpec.requestBody.content);
738
- contentTypes.forEach((contentType) => {
739
- // console.log("requestBody content", {
740
- // contentType,
741
- // schema: eSpec.requestBody.content[contentType].schema,
742
- // });
743
- const schema = eSpec.requestBody.content[contentType].schema;
744
- if (schema) {
745
- if (Array.isArray(headers["Content-type"])) {
746
- headers["Content-type"].push(contentType);
747
- }
748
- else {
749
- headers["Content-type"] = [contentType];
750
- }
751
- const schemaType = getSchemaExamples(spec, schema);
752
- if (schemaType)
753
- body = schemaType;
754
- }
755
- });
756
- }
757
- if (eSpec === null || eSpec === void 0 ? void 0 : eSpec.security) {
758
- eSpec.security.forEach((securityItem) => {
759
- Object.keys(securityItem).forEach((security) => {
760
- var _a, _b;
761
- const securitySchema = (_b = (_a = spec.components) === null || _a === void 0 ? void 0 : _a.securitySchemes) === null || _b === void 0 ? void 0 : _b[security];
762
- if (securitySchema) {
763
- // headers["Authorization"] = securitySchema;
764
- if (securitySchema.type === "mutualTLS") {
765
- extras += `\n--cert client-certificate.crt \
766
- --key client-private-key.key \
767
- --cacert ca-certificate.crt`;
768
- }
769
- else if (securitySchema.type === "apiKey") {
770
- headers[(securitySchema === null || securitySchema === void 0 ? void 0 : securitySchema.name) || "X-API-KEY"] = `{API_KEY_VALUE}`;
771
- }
772
- else {
773
- 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"}}`;
774
- }
775
- }
776
- });
777
- });
778
- }
779
- const curlHeaders = {};
780
- Object.keys(headers).forEach((header) => {
781
- if (Array.isArray(headers[header])) {
782
- curlHeaders[header] = headers[header].join("; ");
783
- }
784
- else {
785
- curlHeaders[header] = headers[header];
786
- }
787
- });
788
- // console.log("curlHeaders", { headers, curlHeaders, body });
789
- curl = `\n\`\`\`bash
790
- ${(0, curl_generator_1.CurlGenerator)({
791
- url: serverUrl + endpointPath,
792
- method: method.toUpperCase(),
793
- headers: curlHeaders,
794
- body,
795
- })}${extras}
796
- \`\`\``;
797
- }
798
- doc = `/**${(eSpec === null || eSpec === void 0 ? void 0 : eSpec.description) ? `\n* ${eSpec === null || eSpec === void 0 ? void 0 : eSpec.description} ` : ""}
799
- * **Method**: \`${method.toUpperCase()}\`
800
- * **Summary**: ${(eSpec === null || eSpec === void 0 ? void 0 : eSpec.summary) || ""}
801
- * **Tags**: [${((_s = eSpec === null || eSpec === void 0 ? void 0 : eSpec.tags) === null || _s === void 0 ? void 0 : _s.join(", ")) || ""}]
802
- * **OperationId**: ${(eSpec === null || eSpec === void 0 ? void 0 : eSpec.operationId) || ""} ${queryTypeCnt
803
- ? `\n * **Query**: ${(0, helpers_1.renderTypeRefMD)(queryTypeCnt)} `
804
- : ""}${dtoTypeCnt ? `\n * **DTO**: ${(0, helpers_1.renderTypeRefMD)(dtoTypeCnt)} ` : ""}${responseTypeCnt
805
- ? `\n * **Response**: ${Object.entries(responseTypeObject)
806
- .map(([code, type]) => `\n - **${code}**: ${(0, helpers_1.renderTypeRefMD)(type, 2)} `)
807
- .join("")}`
808
- : ""}${securitySpec ? `\n * **Security**: ${securitySpec}\n` : ""}${curl}
809
- */\n`;
810
- }
811
- let name = ((_u = (_t = config === null || config === void 0 ? void 0 : config.endpoints) === null || _t === void 0 ? void 0 : _t.name) === null || _u === void 0 ? void 0 : _u.useOperationId) &&
812
- ((_v = eSpec === null || eSpec === void 0 ? void 0 : eSpec.operationId) === null || _v === void 0 ? void 0 : _v.length) > 0
813
- ? eSpec.operationId
814
- : `${endpoint.name}`;
815
- if ((_x = (_w = config === null || config === void 0 ? void 0 : config.endpoints) === null || _w === void 0 ? void 0 : _w.name) === null || _x === void 0 ? void 0 : _x.format) {
816
- const formattedName = config === null || config === void 0 ? void 0 : config.endpoints.name.format({
817
- method,
818
- path: endpointPath,
819
- summary: eSpec === null || eSpec === void 0 ? void 0 : eSpec.summary,
820
- operationId: eSpec === null || eSpec === void 0 ? void 0 : eSpec.operationId,
821
- }, name);
822
- if (formattedName)
823
- name = formattedName;
824
- }
825
- const content = {
826
- method: `"${method}"`,
827
- operationId: `"${eSpec === null || eSpec === void 0 ? void 0 : eSpec.operationId}"`,
828
- url: endpointUrl,
829
- tags: (eSpec === null || eSpec === void 0 ? void 0 : eSpec.tags) || [],
830
- };
831
- // Add the endpoint url
832
- endpointsFileContent += `${doc}export const ${endpointPrefix}${name} = ${((_z = (_y = config === null || config === void 0 ? void 0 : config.endpoints) === null || _y === void 0 ? void 0 : _y.value) === null || _z === void 0 ? void 0 : _z.type) === "object"
833
- ? (0, helpers_1.JSONStringify)(content)
834
- : endpointUrl};
835
- `;
836
- });
837
- });
838
- // Create the necessary directories
839
- const endpointsFilePath = path_1.default.join(rootUsingCwd, folderPath, "endpoints.ts");
840
- yield fs_1.default.promises.mkdir(path_1.default.dirname(endpointsFilePath), { recursive: true });
841
- // Create the file asynchronously
842
- yield fs_1.default.promises.writeFile(endpointsFilePath, endpointsFileContent);
843
- if (Object.values(sharedTypesFileContent).length > 0) {
844
- // Create the necessary directories
845
- const sharedTypesFilePath = path_1.default.join(rootUsingCwd, folderPath, "types", "shared.ts");
846
- yield fs_1.default.promises.mkdir(path_1.default.dirname(sharedTypesFilePath), {
847
- recursive: true,
848
- });
849
- // Create the file asynchronously
850
- yield fs_1.default.promises.writeFile(sharedTypesFilePath, Object.values(sharedTypesFileContent).join("\n"));
851
- }
852
- if (typesFileContent.length > 0) {
853
- // Create the necessary directories
854
- const typesFilePath = path_1.default.join(rootUsingCwd, folderPath, "types", "index.ts");
855
- yield fs_1.default.promises.mkdir(path_1.default.dirname(typesFilePath), { recursive: true });
856
- // Create the file asynchronously
857
- yield fs_1.default.promises.writeFile(typesFilePath, `${Object.values(sharedTypesFileContent).length > 0
858
- ? `import * as Shared from "./shared";\n\n`
859
- : ""}${typesFileContent}`);
860
- }
861
- });
862
- exports.default = OpenapiSync;