enlace-openapi 0.0.1-beta.4 → 0.0.1-beta.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +27 -6
- package/dist/cli.mjs +27 -6
- package/dist/index.d.mts +6 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.js +27 -6
- package/dist/index.mjs +27 -6
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -84,7 +84,7 @@ function typeToSchema(type, ctx) {
|
|
|
84
84
|
);
|
|
85
85
|
const hasNull = type.types.some((t) => t.flags & import_typescript.default.TypeFlags.Null);
|
|
86
86
|
if (nonNullTypes.length === 1 && hasNull) {
|
|
87
|
-
const schema = typeToSchema(nonNullTypes[0], ctx);
|
|
87
|
+
const schema = typeToSchema(nonNullTypes[0], { ...ctx, depth: ctx.depth + 1 });
|
|
88
88
|
return { ...schema, nullable: true };
|
|
89
89
|
}
|
|
90
90
|
if (nonNullTypes.every((t) => t.isStringLiteral())) {
|
|
@@ -99,19 +99,20 @@ function typeToSchema(type, ctx) {
|
|
|
99
99
|
enum: nonNullTypes.map((t) => t.value)
|
|
100
100
|
};
|
|
101
101
|
}
|
|
102
|
+
const nextCtx = { ...ctx, depth: ctx.depth + 1 };
|
|
102
103
|
return {
|
|
103
|
-
oneOf: nonNullTypes.map((t) => typeToSchema(t,
|
|
104
|
+
oneOf: nonNullTypes.map((t) => typeToSchema(t, nextCtx))
|
|
104
105
|
};
|
|
105
106
|
}
|
|
106
107
|
if (type.isIntersection()) {
|
|
107
|
-
return intersectionTypeToSchema(type, ctx);
|
|
108
|
+
return intersectionTypeToSchema(type, { ...ctx, depth: ctx.depth + 1 });
|
|
108
109
|
}
|
|
109
110
|
if (checker.isArrayType(type)) {
|
|
110
111
|
const typeArgs = type.typeArguments;
|
|
111
112
|
if (typeArgs?.[0]) {
|
|
112
113
|
return {
|
|
113
114
|
type: "array",
|
|
114
|
-
items: typeToSchema(typeArgs[0], ctx)
|
|
115
|
+
items: typeToSchema(typeArgs[0], { ...ctx, depth: ctx.depth + 1 })
|
|
115
116
|
};
|
|
116
117
|
}
|
|
117
118
|
return { type: "array" };
|
|
@@ -417,12 +418,17 @@ function formDataTypeToSchema(formDataType, ctx) {
|
|
|
417
418
|
function generateOpenAPISpec(endpoints, schemas, options = {}) {
|
|
418
419
|
const { title = "API", version = "1.0.0", description, baseUrl } = options;
|
|
419
420
|
const paths = {};
|
|
421
|
+
const tagSet = /* @__PURE__ */ new Set();
|
|
420
422
|
for (const endpoint of endpoints) {
|
|
421
423
|
if (!paths[endpoint.path]) {
|
|
422
424
|
paths[endpoint.path] = {};
|
|
423
425
|
}
|
|
424
426
|
const pathItem = paths[endpoint.path];
|
|
425
|
-
const
|
|
427
|
+
const tag = getTagFromPath(endpoint.path);
|
|
428
|
+
const operation = createOperation(endpoint, tag);
|
|
429
|
+
if (tag) {
|
|
430
|
+
tagSet.add(tag);
|
|
431
|
+
}
|
|
426
432
|
pathItem[endpoint.method] = operation;
|
|
427
433
|
if (endpoint.pathParams.length > 0 && !pathItem.parameters) {
|
|
428
434
|
pathItem.parameters = endpoint.pathParams.map((param) => ({
|
|
@@ -433,6 +439,7 @@ function generateOpenAPISpec(endpoints, schemas, options = {}) {
|
|
|
433
439
|
}));
|
|
434
440
|
}
|
|
435
441
|
}
|
|
442
|
+
const tags = [...tagSet].sort().map((name) => ({ name }));
|
|
436
443
|
const spec = {
|
|
437
444
|
openapi: "3.0.0",
|
|
438
445
|
info: {
|
|
@@ -447,6 +454,9 @@ function generateOpenAPISpec(endpoints, schemas, options = {}) {
|
|
|
447
454
|
if (baseUrl) {
|
|
448
455
|
spec.servers = [{ url: baseUrl }];
|
|
449
456
|
}
|
|
457
|
+
if (tags.length > 0) {
|
|
458
|
+
spec.tags = tags;
|
|
459
|
+
}
|
|
450
460
|
if (schemas.size > 0) {
|
|
451
461
|
spec.components = {
|
|
452
462
|
schemas: Object.fromEntries(schemas)
|
|
@@ -454,7 +464,15 @@ function generateOpenAPISpec(endpoints, schemas, options = {}) {
|
|
|
454
464
|
}
|
|
455
465
|
return spec;
|
|
456
466
|
}
|
|
457
|
-
function
|
|
467
|
+
function getTagFromPath(path2) {
|
|
468
|
+
const segments = path2.split("/").filter(Boolean);
|
|
469
|
+
const firstSegment = segments[0];
|
|
470
|
+
if (!firstSegment || firstSegment.startsWith("{")) {
|
|
471
|
+
return void 0;
|
|
472
|
+
}
|
|
473
|
+
return firstSegment;
|
|
474
|
+
}
|
|
475
|
+
function createOperation(endpoint, tag) {
|
|
458
476
|
const operation = {
|
|
459
477
|
responses: {
|
|
460
478
|
"200": {
|
|
@@ -462,6 +480,9 @@ function createOperation(endpoint) {
|
|
|
462
480
|
}
|
|
463
481
|
}
|
|
464
482
|
};
|
|
483
|
+
if (tag) {
|
|
484
|
+
operation.tags = [tag];
|
|
485
|
+
}
|
|
465
486
|
if (hasContent(endpoint.responseSchema)) {
|
|
466
487
|
operation.responses["200"].content = {
|
|
467
488
|
"application/json": {
|
package/dist/cli.mjs
CHANGED
|
@@ -61,7 +61,7 @@ function typeToSchema(type, ctx) {
|
|
|
61
61
|
);
|
|
62
62
|
const hasNull = type.types.some((t) => t.flags & ts.TypeFlags.Null);
|
|
63
63
|
if (nonNullTypes.length === 1 && hasNull) {
|
|
64
|
-
const schema = typeToSchema(nonNullTypes[0], ctx);
|
|
64
|
+
const schema = typeToSchema(nonNullTypes[0], { ...ctx, depth: ctx.depth + 1 });
|
|
65
65
|
return { ...schema, nullable: true };
|
|
66
66
|
}
|
|
67
67
|
if (nonNullTypes.every((t) => t.isStringLiteral())) {
|
|
@@ -76,19 +76,20 @@ function typeToSchema(type, ctx) {
|
|
|
76
76
|
enum: nonNullTypes.map((t) => t.value)
|
|
77
77
|
};
|
|
78
78
|
}
|
|
79
|
+
const nextCtx = { ...ctx, depth: ctx.depth + 1 };
|
|
79
80
|
return {
|
|
80
|
-
oneOf: nonNullTypes.map((t) => typeToSchema(t,
|
|
81
|
+
oneOf: nonNullTypes.map((t) => typeToSchema(t, nextCtx))
|
|
81
82
|
};
|
|
82
83
|
}
|
|
83
84
|
if (type.isIntersection()) {
|
|
84
|
-
return intersectionTypeToSchema(type, ctx);
|
|
85
|
+
return intersectionTypeToSchema(type, { ...ctx, depth: ctx.depth + 1 });
|
|
85
86
|
}
|
|
86
87
|
if (checker.isArrayType(type)) {
|
|
87
88
|
const typeArgs = type.typeArguments;
|
|
88
89
|
if (typeArgs?.[0]) {
|
|
89
90
|
return {
|
|
90
91
|
type: "array",
|
|
91
|
-
items: typeToSchema(typeArgs[0], ctx)
|
|
92
|
+
items: typeToSchema(typeArgs[0], { ...ctx, depth: ctx.depth + 1 })
|
|
92
93
|
};
|
|
93
94
|
}
|
|
94
95
|
return { type: "array" };
|
|
@@ -394,12 +395,17 @@ function formDataTypeToSchema(formDataType, ctx) {
|
|
|
394
395
|
function generateOpenAPISpec(endpoints, schemas, options = {}) {
|
|
395
396
|
const { title = "API", version = "1.0.0", description, baseUrl } = options;
|
|
396
397
|
const paths = {};
|
|
398
|
+
const tagSet = /* @__PURE__ */ new Set();
|
|
397
399
|
for (const endpoint of endpoints) {
|
|
398
400
|
if (!paths[endpoint.path]) {
|
|
399
401
|
paths[endpoint.path] = {};
|
|
400
402
|
}
|
|
401
403
|
const pathItem = paths[endpoint.path];
|
|
402
|
-
const
|
|
404
|
+
const tag = getTagFromPath(endpoint.path);
|
|
405
|
+
const operation = createOperation(endpoint, tag);
|
|
406
|
+
if (tag) {
|
|
407
|
+
tagSet.add(tag);
|
|
408
|
+
}
|
|
403
409
|
pathItem[endpoint.method] = operation;
|
|
404
410
|
if (endpoint.pathParams.length > 0 && !pathItem.parameters) {
|
|
405
411
|
pathItem.parameters = endpoint.pathParams.map((param) => ({
|
|
@@ -410,6 +416,7 @@ function generateOpenAPISpec(endpoints, schemas, options = {}) {
|
|
|
410
416
|
}));
|
|
411
417
|
}
|
|
412
418
|
}
|
|
419
|
+
const tags = [...tagSet].sort().map((name) => ({ name }));
|
|
413
420
|
const spec = {
|
|
414
421
|
openapi: "3.0.0",
|
|
415
422
|
info: {
|
|
@@ -424,6 +431,9 @@ function generateOpenAPISpec(endpoints, schemas, options = {}) {
|
|
|
424
431
|
if (baseUrl) {
|
|
425
432
|
spec.servers = [{ url: baseUrl }];
|
|
426
433
|
}
|
|
434
|
+
if (tags.length > 0) {
|
|
435
|
+
spec.tags = tags;
|
|
436
|
+
}
|
|
427
437
|
if (schemas.size > 0) {
|
|
428
438
|
spec.components = {
|
|
429
439
|
schemas: Object.fromEntries(schemas)
|
|
@@ -431,7 +441,15 @@ function generateOpenAPISpec(endpoints, schemas, options = {}) {
|
|
|
431
441
|
}
|
|
432
442
|
return spec;
|
|
433
443
|
}
|
|
434
|
-
function
|
|
444
|
+
function getTagFromPath(path2) {
|
|
445
|
+
const segments = path2.split("/").filter(Boolean);
|
|
446
|
+
const firstSegment = segments[0];
|
|
447
|
+
if (!firstSegment || firstSegment.startsWith("{")) {
|
|
448
|
+
return void 0;
|
|
449
|
+
}
|
|
450
|
+
return firstSegment;
|
|
451
|
+
}
|
|
452
|
+
function createOperation(endpoint, tag) {
|
|
435
453
|
const operation = {
|
|
436
454
|
responses: {
|
|
437
455
|
"200": {
|
|
@@ -439,6 +457,9 @@ function createOperation(endpoint) {
|
|
|
439
457
|
}
|
|
440
458
|
}
|
|
441
459
|
};
|
|
460
|
+
if (tag) {
|
|
461
|
+
operation.tags = [tag];
|
|
462
|
+
}
|
|
442
463
|
if (hasContent(endpoint.responseSchema)) {
|
|
443
464
|
operation.responses["200"].content = {
|
|
444
465
|
"application/json": {
|
package/dist/index.d.mts
CHANGED
|
@@ -56,6 +56,10 @@ type OpenAPIPathItem = {
|
|
|
56
56
|
delete?: OpenAPIOperation;
|
|
57
57
|
parameters?: OpenAPIParameter[];
|
|
58
58
|
};
|
|
59
|
+
type OpenAPITag = {
|
|
60
|
+
name: string;
|
|
61
|
+
description?: string;
|
|
62
|
+
};
|
|
59
63
|
type OpenAPISpec = {
|
|
60
64
|
openapi: "3.0.0";
|
|
61
65
|
info: {
|
|
@@ -67,6 +71,7 @@ type OpenAPISpec = {
|
|
|
67
71
|
url: string;
|
|
68
72
|
description?: string;
|
|
69
73
|
}[];
|
|
74
|
+
tags?: OpenAPITag[];
|
|
70
75
|
paths: Record<string, OpenAPIPathItem>;
|
|
71
76
|
components?: {
|
|
72
77
|
schemas?: Record<string, JSONSchema>;
|
|
@@ -105,4 +110,4 @@ type GeneratorOptions = {
|
|
|
105
110
|
};
|
|
106
111
|
declare function generateOpenAPISpec(endpoints: ParsedEndpoint[], schemas: Map<string, JSONSchema>, options?: GeneratorOptions): OpenAPISpec;
|
|
107
112
|
|
|
108
|
-
export { type CLIOptions, type JSONSchema, type OpenAPIOperation, type OpenAPIParameter, type OpenAPIPathItem, type OpenAPIRequestBody, type OpenAPISpec, type ParsedEndpoint, generateOpenAPISpec, parseSchema };
|
|
113
|
+
export { type CLIOptions, type JSONSchema, type OpenAPIOperation, type OpenAPIParameter, type OpenAPIPathItem, type OpenAPIRequestBody, type OpenAPISpec, type OpenAPITag, type ParsedEndpoint, generateOpenAPISpec, parseSchema };
|
package/dist/index.d.ts
CHANGED
|
@@ -56,6 +56,10 @@ type OpenAPIPathItem = {
|
|
|
56
56
|
delete?: OpenAPIOperation;
|
|
57
57
|
parameters?: OpenAPIParameter[];
|
|
58
58
|
};
|
|
59
|
+
type OpenAPITag = {
|
|
60
|
+
name: string;
|
|
61
|
+
description?: string;
|
|
62
|
+
};
|
|
59
63
|
type OpenAPISpec = {
|
|
60
64
|
openapi: "3.0.0";
|
|
61
65
|
info: {
|
|
@@ -67,6 +71,7 @@ type OpenAPISpec = {
|
|
|
67
71
|
url: string;
|
|
68
72
|
description?: string;
|
|
69
73
|
}[];
|
|
74
|
+
tags?: OpenAPITag[];
|
|
70
75
|
paths: Record<string, OpenAPIPathItem>;
|
|
71
76
|
components?: {
|
|
72
77
|
schemas?: Record<string, JSONSchema>;
|
|
@@ -105,4 +110,4 @@ type GeneratorOptions = {
|
|
|
105
110
|
};
|
|
106
111
|
declare function generateOpenAPISpec(endpoints: ParsedEndpoint[], schemas: Map<string, JSONSchema>, options?: GeneratorOptions): OpenAPISpec;
|
|
107
112
|
|
|
108
|
-
export { type CLIOptions, type JSONSchema, type OpenAPIOperation, type OpenAPIParameter, type OpenAPIPathItem, type OpenAPIRequestBody, type OpenAPISpec, type ParsedEndpoint, generateOpenAPISpec, parseSchema };
|
|
113
|
+
export { type CLIOptions, type JSONSchema, type OpenAPIOperation, type OpenAPIParameter, type OpenAPIPathItem, type OpenAPIRequestBody, type OpenAPISpec, type OpenAPITag, type ParsedEndpoint, generateOpenAPISpec, parseSchema };
|
package/dist/index.js
CHANGED
|
@@ -92,7 +92,7 @@ function typeToSchema(type, ctx) {
|
|
|
92
92
|
);
|
|
93
93
|
const hasNull = type.types.some((t) => t.flags & import_typescript.default.TypeFlags.Null);
|
|
94
94
|
if (nonNullTypes.length === 1 && hasNull) {
|
|
95
|
-
const schema = typeToSchema(nonNullTypes[0], ctx);
|
|
95
|
+
const schema = typeToSchema(nonNullTypes[0], { ...ctx, depth: ctx.depth + 1 });
|
|
96
96
|
return { ...schema, nullable: true };
|
|
97
97
|
}
|
|
98
98
|
if (nonNullTypes.every((t) => t.isStringLiteral())) {
|
|
@@ -107,19 +107,20 @@ function typeToSchema(type, ctx) {
|
|
|
107
107
|
enum: nonNullTypes.map((t) => t.value)
|
|
108
108
|
};
|
|
109
109
|
}
|
|
110
|
+
const nextCtx = { ...ctx, depth: ctx.depth + 1 };
|
|
110
111
|
return {
|
|
111
|
-
oneOf: nonNullTypes.map((t) => typeToSchema(t,
|
|
112
|
+
oneOf: nonNullTypes.map((t) => typeToSchema(t, nextCtx))
|
|
112
113
|
};
|
|
113
114
|
}
|
|
114
115
|
if (type.isIntersection()) {
|
|
115
|
-
return intersectionTypeToSchema(type, ctx);
|
|
116
|
+
return intersectionTypeToSchema(type, { ...ctx, depth: ctx.depth + 1 });
|
|
116
117
|
}
|
|
117
118
|
if (checker.isArrayType(type)) {
|
|
118
119
|
const typeArgs = type.typeArguments;
|
|
119
120
|
if (typeArgs?.[0]) {
|
|
120
121
|
return {
|
|
121
122
|
type: "array",
|
|
122
|
-
items: typeToSchema(typeArgs[0], ctx)
|
|
123
|
+
items: typeToSchema(typeArgs[0], { ...ctx, depth: ctx.depth + 1 })
|
|
123
124
|
};
|
|
124
125
|
}
|
|
125
126
|
return { type: "array" };
|
|
@@ -425,12 +426,17 @@ function formDataTypeToSchema(formDataType, ctx) {
|
|
|
425
426
|
function generateOpenAPISpec(endpoints, schemas, options = {}) {
|
|
426
427
|
const { title = "API", version = "1.0.0", description, baseUrl } = options;
|
|
427
428
|
const paths = {};
|
|
429
|
+
const tagSet = /* @__PURE__ */ new Set();
|
|
428
430
|
for (const endpoint of endpoints) {
|
|
429
431
|
if (!paths[endpoint.path]) {
|
|
430
432
|
paths[endpoint.path] = {};
|
|
431
433
|
}
|
|
432
434
|
const pathItem = paths[endpoint.path];
|
|
433
|
-
const
|
|
435
|
+
const tag = getTagFromPath(endpoint.path);
|
|
436
|
+
const operation = createOperation(endpoint, tag);
|
|
437
|
+
if (tag) {
|
|
438
|
+
tagSet.add(tag);
|
|
439
|
+
}
|
|
434
440
|
pathItem[endpoint.method] = operation;
|
|
435
441
|
if (endpoint.pathParams.length > 0 && !pathItem.parameters) {
|
|
436
442
|
pathItem.parameters = endpoint.pathParams.map((param) => ({
|
|
@@ -441,6 +447,7 @@ function generateOpenAPISpec(endpoints, schemas, options = {}) {
|
|
|
441
447
|
}));
|
|
442
448
|
}
|
|
443
449
|
}
|
|
450
|
+
const tags = [...tagSet].sort().map((name) => ({ name }));
|
|
444
451
|
const spec = {
|
|
445
452
|
openapi: "3.0.0",
|
|
446
453
|
info: {
|
|
@@ -455,6 +462,9 @@ function generateOpenAPISpec(endpoints, schemas, options = {}) {
|
|
|
455
462
|
if (baseUrl) {
|
|
456
463
|
spec.servers = [{ url: baseUrl }];
|
|
457
464
|
}
|
|
465
|
+
if (tags.length > 0) {
|
|
466
|
+
spec.tags = tags;
|
|
467
|
+
}
|
|
458
468
|
if (schemas.size > 0) {
|
|
459
469
|
spec.components = {
|
|
460
470
|
schemas: Object.fromEntries(schemas)
|
|
@@ -462,7 +472,15 @@ function generateOpenAPISpec(endpoints, schemas, options = {}) {
|
|
|
462
472
|
}
|
|
463
473
|
return spec;
|
|
464
474
|
}
|
|
465
|
-
function
|
|
475
|
+
function getTagFromPath(path2) {
|
|
476
|
+
const segments = path2.split("/").filter(Boolean);
|
|
477
|
+
const firstSegment = segments[0];
|
|
478
|
+
if (!firstSegment || firstSegment.startsWith("{")) {
|
|
479
|
+
return void 0;
|
|
480
|
+
}
|
|
481
|
+
return firstSegment;
|
|
482
|
+
}
|
|
483
|
+
function createOperation(endpoint, tag) {
|
|
466
484
|
const operation = {
|
|
467
485
|
responses: {
|
|
468
486
|
"200": {
|
|
@@ -470,6 +488,9 @@ function createOperation(endpoint) {
|
|
|
470
488
|
}
|
|
471
489
|
}
|
|
472
490
|
};
|
|
491
|
+
if (tag) {
|
|
492
|
+
operation.tags = [tag];
|
|
493
|
+
}
|
|
473
494
|
if (hasContent(endpoint.responseSchema)) {
|
|
474
495
|
operation.responses["200"].content = {
|
|
475
496
|
"application/json": {
|
package/dist/index.mjs
CHANGED
|
@@ -55,7 +55,7 @@ function typeToSchema(type, ctx) {
|
|
|
55
55
|
);
|
|
56
56
|
const hasNull = type.types.some((t) => t.flags & ts.TypeFlags.Null);
|
|
57
57
|
if (nonNullTypes.length === 1 && hasNull) {
|
|
58
|
-
const schema = typeToSchema(nonNullTypes[0], ctx);
|
|
58
|
+
const schema = typeToSchema(nonNullTypes[0], { ...ctx, depth: ctx.depth + 1 });
|
|
59
59
|
return { ...schema, nullable: true };
|
|
60
60
|
}
|
|
61
61
|
if (nonNullTypes.every((t) => t.isStringLiteral())) {
|
|
@@ -70,19 +70,20 @@ function typeToSchema(type, ctx) {
|
|
|
70
70
|
enum: nonNullTypes.map((t) => t.value)
|
|
71
71
|
};
|
|
72
72
|
}
|
|
73
|
+
const nextCtx = { ...ctx, depth: ctx.depth + 1 };
|
|
73
74
|
return {
|
|
74
|
-
oneOf: nonNullTypes.map((t) => typeToSchema(t,
|
|
75
|
+
oneOf: nonNullTypes.map((t) => typeToSchema(t, nextCtx))
|
|
75
76
|
};
|
|
76
77
|
}
|
|
77
78
|
if (type.isIntersection()) {
|
|
78
|
-
return intersectionTypeToSchema(type, ctx);
|
|
79
|
+
return intersectionTypeToSchema(type, { ...ctx, depth: ctx.depth + 1 });
|
|
79
80
|
}
|
|
80
81
|
if (checker.isArrayType(type)) {
|
|
81
82
|
const typeArgs = type.typeArguments;
|
|
82
83
|
if (typeArgs?.[0]) {
|
|
83
84
|
return {
|
|
84
85
|
type: "array",
|
|
85
|
-
items: typeToSchema(typeArgs[0], ctx)
|
|
86
|
+
items: typeToSchema(typeArgs[0], { ...ctx, depth: ctx.depth + 1 })
|
|
86
87
|
};
|
|
87
88
|
}
|
|
88
89
|
return { type: "array" };
|
|
@@ -388,12 +389,17 @@ function formDataTypeToSchema(formDataType, ctx) {
|
|
|
388
389
|
function generateOpenAPISpec(endpoints, schemas, options = {}) {
|
|
389
390
|
const { title = "API", version = "1.0.0", description, baseUrl } = options;
|
|
390
391
|
const paths = {};
|
|
392
|
+
const tagSet = /* @__PURE__ */ new Set();
|
|
391
393
|
for (const endpoint of endpoints) {
|
|
392
394
|
if (!paths[endpoint.path]) {
|
|
393
395
|
paths[endpoint.path] = {};
|
|
394
396
|
}
|
|
395
397
|
const pathItem = paths[endpoint.path];
|
|
396
|
-
const
|
|
398
|
+
const tag = getTagFromPath(endpoint.path);
|
|
399
|
+
const operation = createOperation(endpoint, tag);
|
|
400
|
+
if (tag) {
|
|
401
|
+
tagSet.add(tag);
|
|
402
|
+
}
|
|
397
403
|
pathItem[endpoint.method] = operation;
|
|
398
404
|
if (endpoint.pathParams.length > 0 && !pathItem.parameters) {
|
|
399
405
|
pathItem.parameters = endpoint.pathParams.map((param) => ({
|
|
@@ -404,6 +410,7 @@ function generateOpenAPISpec(endpoints, schemas, options = {}) {
|
|
|
404
410
|
}));
|
|
405
411
|
}
|
|
406
412
|
}
|
|
413
|
+
const tags = [...tagSet].sort().map((name) => ({ name }));
|
|
407
414
|
const spec = {
|
|
408
415
|
openapi: "3.0.0",
|
|
409
416
|
info: {
|
|
@@ -418,6 +425,9 @@ function generateOpenAPISpec(endpoints, schemas, options = {}) {
|
|
|
418
425
|
if (baseUrl) {
|
|
419
426
|
spec.servers = [{ url: baseUrl }];
|
|
420
427
|
}
|
|
428
|
+
if (tags.length > 0) {
|
|
429
|
+
spec.tags = tags;
|
|
430
|
+
}
|
|
421
431
|
if (schemas.size > 0) {
|
|
422
432
|
spec.components = {
|
|
423
433
|
schemas: Object.fromEntries(schemas)
|
|
@@ -425,7 +435,15 @@ function generateOpenAPISpec(endpoints, schemas, options = {}) {
|
|
|
425
435
|
}
|
|
426
436
|
return spec;
|
|
427
437
|
}
|
|
428
|
-
function
|
|
438
|
+
function getTagFromPath(path2) {
|
|
439
|
+
const segments = path2.split("/").filter(Boolean);
|
|
440
|
+
const firstSegment = segments[0];
|
|
441
|
+
if (!firstSegment || firstSegment.startsWith("{")) {
|
|
442
|
+
return void 0;
|
|
443
|
+
}
|
|
444
|
+
return firstSegment;
|
|
445
|
+
}
|
|
446
|
+
function createOperation(endpoint, tag) {
|
|
429
447
|
const operation = {
|
|
430
448
|
responses: {
|
|
431
449
|
"200": {
|
|
@@ -433,6 +451,9 @@ function createOperation(endpoint) {
|
|
|
433
451
|
}
|
|
434
452
|
}
|
|
435
453
|
};
|
|
454
|
+
if (tag) {
|
|
455
|
+
operation.tags = [tag];
|
|
456
|
+
}
|
|
436
457
|
if (hasContent(endpoint.responseSchema)) {
|
|
437
458
|
operation.responses["200"].content = {
|
|
438
459
|
"application/json": {
|