swaggular 0.1.2 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/variables.js +4 -6
- package/dist/index.js +9 -9
- package/dist/parsers/path-grouper.js +2 -0
- package/dist/renderers/generate-comments.js +4 -3
- package/dist/renderers/generate-service.d.ts +2 -1
- package/dist/renderers/generate-service.js +66 -23
- package/dist/templates/services/angular-template.d.ts +3 -0
- package/dist/templates/services/angular-template.js +2 -2
- package/dist/templates/services/http-params-handler.d.ts +9 -0
- package/dist/templates/services/http-params-handler.js +9 -0
- package/dist/templates/types/extends-from-types.d.ts +5 -0
- package/dist/templates/types/extends-from-types.js +5 -0
- package/dist/templates/types/generic-types.d.ts +5 -0
- package/dist/templates/types/generic-types.js +5 -0
- package/dist/types/parsed-args.d.ts +3 -1
- package/dist/utils/path-utils.d.ts +0 -1
- package/dist/utils/path-utils.js +23 -19
- package/package.json +9 -1
package/dist/cli/variables.js
CHANGED
|
@@ -4,20 +4,18 @@ exports.toVariables = toVariables;
|
|
|
4
4
|
function toVariables(parsed) {
|
|
5
5
|
const variables = {};
|
|
6
6
|
if (parsed.args.mode) {
|
|
7
|
-
variables.groupingMode = parsed.args.mode;
|
|
7
|
+
variables.groupingMode = parsed.args.mode || 'path';
|
|
8
8
|
}
|
|
9
9
|
if (parsed.args.segmentsToIgnore) {
|
|
10
10
|
if (typeof parsed.args.segmentsToIgnore === 'string') {
|
|
11
11
|
variables.segmentsToIgnore = parsed.args.segmentsToIgnore.split(',');
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
|
-
if (parsed.args.ignoreVariables) {
|
|
15
|
-
variables.ignoreVariables =
|
|
16
|
-
parsed.args.ignoreVariables === 'true' || parsed.args.ignoreVariables === true;
|
|
17
|
-
}
|
|
18
14
|
return {
|
|
15
|
+
input: parsed.args.input || 'swagger.json',
|
|
16
|
+
output: parsed.args.output || 'results',
|
|
17
|
+
noGenerate: parsed.args.noGenerate || false,
|
|
19
18
|
groupingMode: variables.groupingMode || 'path',
|
|
20
19
|
segmentsToIgnore: variables.segmentsToIgnore || ['api'],
|
|
21
|
-
ignoreVariables: variables.ignoreVariables || true,
|
|
22
20
|
};
|
|
23
21
|
}
|
package/dist/index.js
CHANGED
|
@@ -16,25 +16,25 @@ async function main() {
|
|
|
16
16
|
try {
|
|
17
17
|
const parsed = (0, args_1.getParseArgs)(process.argv.slice(2));
|
|
18
18
|
const variables = (0, variables_1.toVariables)(parsed);
|
|
19
|
-
swagger_parser_1.SwaggerParser.parse(
|
|
19
|
+
swagger_parser_1.SwaggerParser.parse(variables.input, {
|
|
20
20
|
mode: variables.groupingMode,
|
|
21
21
|
segmentsToIgnore: variables.segmentsToIgnore,
|
|
22
|
-
ignoreVariables:
|
|
22
|
+
ignoreVariables: true,
|
|
23
23
|
});
|
|
24
24
|
(0, generate_interface_1.generateInterfaces)();
|
|
25
25
|
(0, generate_service_1.generateServices)();
|
|
26
26
|
const interfaceFiles = (0, generate_interface_1.generateInterfacesFiles)();
|
|
27
27
|
const serviceFiles = (0, generate_service_1.generateServiceFiles)();
|
|
28
|
-
if (
|
|
29
|
-
console.log('
|
|
28
|
+
if (variables.noGenerate) {
|
|
29
|
+
console.log('Files not generated');
|
|
30
30
|
return;
|
|
31
31
|
}
|
|
32
|
-
if (fs_1.default.existsSync(
|
|
33
|
-
fs_1.default.rmSync(
|
|
32
|
+
if (fs_1.default.existsSync(variables.output)) {
|
|
33
|
+
fs_1.default.rmSync(variables.output, { recursive: true, force: true });
|
|
34
34
|
}
|
|
35
|
-
await (0, create_file_1.createFileFromFileContents)(
|
|
36
|
-
await (0, create_file_1.createFileFromFileContents)(
|
|
37
|
-
console.log('
|
|
35
|
+
await (0, create_file_1.createFileFromFileContents)(`${variables.output}/models`, interfaceFiles);
|
|
36
|
+
await (0, create_file_1.createFileFromFileContents)(variables.output, serviceFiles);
|
|
37
|
+
console.log('Files created successfully');
|
|
38
38
|
}
|
|
39
39
|
catch (err) {
|
|
40
40
|
console.error('Failed to read JSON:', err);
|
|
@@ -194,6 +194,8 @@ class PathGrouper {
|
|
|
194
194
|
const common = [];
|
|
195
195
|
for (let i = 0; i < firstPath.length; i++) {
|
|
196
196
|
const segment = firstPath[i];
|
|
197
|
+
if ((0, path_utils_1.isVariable)(segment))
|
|
198
|
+
break;
|
|
197
199
|
if (pathSegments.every((ps) => ps[i] === segment)) {
|
|
198
200
|
common.push(segment);
|
|
199
201
|
}
|
|
@@ -26,8 +26,9 @@ function generateInterfaceComments(param) {
|
|
|
26
26
|
}
|
|
27
27
|
function generateServiceComments(summary, responseType, parameters) {
|
|
28
28
|
const summarySplited = [];
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
const summaryWords = summary.split(' ');
|
|
30
|
+
for (let i = 0; i < summaryWords.length; i += 10) {
|
|
31
|
+
summarySplited.push(summaryWords.slice(i, i + 10).join(' '));
|
|
31
32
|
}
|
|
32
33
|
const comments = summarySplited;
|
|
33
34
|
if (parameters && parameters.length > 0) {
|
|
@@ -36,5 +37,5 @@ function generateServiceComments(summary, responseType, parameters) {
|
|
|
36
37
|
if (responseType) {
|
|
37
38
|
comments.push(`@returns Observable<${responseType}>`);
|
|
38
39
|
}
|
|
39
|
-
return `\t/**\n${comments.map((c) => `\t* ${c}\n`).join('')}
|
|
40
|
+
return `\t/**\n${comments.map((c) => `\t* ${c}\n`).join('')} */`;
|
|
40
41
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { OpenAPIV3 } from 'openapi-types';
|
|
1
2
|
import { FileContent } from '../types/file-content';
|
|
2
3
|
import { GroupedPath } from '../types/grouped-paths';
|
|
3
4
|
import { ServiceDataMethod } from '../types/service-data';
|
|
@@ -6,4 +7,4 @@ import { ServiceDataMethod } from '../types/service-data';
|
|
|
6
7
|
*/
|
|
7
8
|
export declare function generateServices(): void;
|
|
8
9
|
export declare function generateServiceFiles(locations?: Record<string, string[]>): FileContent[];
|
|
9
|
-
export declare function buildMethods(groupedPath: GroupedPath): ServiceDataMethod[];
|
|
10
|
+
export declare function buildMethods(groupedPath: GroupedPath, pathData: OpenAPIV3.PathsObject): ServiceDataMethod[];
|
|
@@ -22,21 +22,17 @@ function generateServices() {
|
|
|
22
22
|
if (!groupedPaths || !paths)
|
|
23
23
|
return;
|
|
24
24
|
for (const [key, value] of Object.entries(groupedPaths)) {
|
|
25
|
-
const serviceMethods = buildMethods(value);
|
|
25
|
+
const serviceMethods = buildMethods(value, paths);
|
|
26
26
|
const imports = new Set();
|
|
27
27
|
serviceMethods.forEach((method) => {
|
|
28
|
-
|
|
29
|
-
imports.add(method.responseType);
|
|
30
|
-
}
|
|
28
|
+
addTypeToImports(method.responseType, imports);
|
|
31
29
|
method.parameters.forEach((param) => {
|
|
32
|
-
|
|
33
|
-
imports.add(param.type);
|
|
34
|
-
}
|
|
30
|
+
addTypeToImports(param.type, imports);
|
|
35
31
|
});
|
|
36
32
|
});
|
|
37
33
|
const serviceData = {
|
|
38
34
|
name: key,
|
|
39
|
-
imports: Array.from(imports),
|
|
35
|
+
imports: Array.from(imports).sort(),
|
|
40
36
|
baseUrl: value.baseUrl,
|
|
41
37
|
methods: serviceMethods,
|
|
42
38
|
};
|
|
@@ -44,6 +40,22 @@ function generateServices() {
|
|
|
44
40
|
}
|
|
45
41
|
service_state_1.serviceState.addServices(servicesData);
|
|
46
42
|
}
|
|
43
|
+
function addTypeToImports(type, imports) {
|
|
44
|
+
if (!type || (0, type_guard_1.isNativeType)(type))
|
|
45
|
+
return;
|
|
46
|
+
const baseType = type.replace('[]', '');
|
|
47
|
+
if (baseType.includes('<')) {
|
|
48
|
+
const parts = baseType.split(/[<>]/);
|
|
49
|
+
parts.forEach((p) => {
|
|
50
|
+
if (p && !(0, type_guard_1.isNativeType)(p)) {
|
|
51
|
+
imports.add(p);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
imports.add(baseType);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
47
59
|
function generateServiceFiles(locations) {
|
|
48
60
|
const services = Object.values(service_state_1.serviceState.services);
|
|
49
61
|
const filesContent = [];
|
|
@@ -71,22 +83,22 @@ function generateServiceFiles(locations) {
|
|
|
71
83
|
}
|
|
72
84
|
return filesContent;
|
|
73
85
|
}
|
|
74
|
-
function buildMethods(groupedPath) {
|
|
86
|
+
function buildMethods(groupedPath, pathData) {
|
|
75
87
|
const methods = [];
|
|
76
|
-
const pathData = swagger_state_1.swaggerState.getPaths();
|
|
77
88
|
const usedNames = [];
|
|
78
89
|
for (const path of groupedPath.paths) {
|
|
79
90
|
if (!pathData || !pathData[path])
|
|
80
91
|
continue;
|
|
81
|
-
const pathItem =
|
|
82
|
-
|
|
92
|
+
const pathItem = pathData[path];
|
|
93
|
+
const operations = pathItemToMethods(pathItem);
|
|
94
|
+
for (const [method, operation] of Object.entries(operations)) {
|
|
83
95
|
const name = buildMethodName(method, path, groupedPath, usedNames);
|
|
84
96
|
usedNames.push(name);
|
|
85
|
-
const parameters = buildParameters(operation.parameters
|
|
97
|
+
const parameters = buildParameters(operation, pathItem.parameters);
|
|
86
98
|
const responseType = buildResponseType(operation.responses);
|
|
87
99
|
methods.push({
|
|
88
100
|
name,
|
|
89
|
-
path: (0, path_utils_1.
|
|
101
|
+
path: (0, path_utils_1.getExtraSegments)(path, groupedPath.baseUrl).join('/'),
|
|
90
102
|
method: method,
|
|
91
103
|
parameters,
|
|
92
104
|
responseType,
|
|
@@ -114,16 +126,20 @@ function buildMethodName(method, path, groupedPath, usedNames) {
|
|
|
114
126
|
patch: 'patch',
|
|
115
127
|
};
|
|
116
128
|
const prefix = dict[method];
|
|
117
|
-
const
|
|
129
|
+
const extraSegments = (0, path_utils_1.getExtraSegments)(path, groupedPath.baseUrl);
|
|
130
|
+
// Create name segments, removing variables from name
|
|
131
|
+
const nameSegments = extraSegments.map((s) => s.replace(/[{}]/g, ''));
|
|
132
|
+
const extra = (0, string_utils_1.kebabToPascalCase)(nameSegments.join(''));
|
|
118
133
|
let name = prefix + (0, string_utils_1.upFirst)(extra);
|
|
119
134
|
if (usedNames.includes(name)) {
|
|
120
135
|
name += (0, string_utils_1.upFirst)(method);
|
|
121
136
|
}
|
|
122
137
|
return name;
|
|
123
138
|
}
|
|
124
|
-
function buildParameters(
|
|
139
|
+
function buildParameters(operation, pathParameters) {
|
|
125
140
|
const results = [];
|
|
126
|
-
|
|
141
|
+
const allParams = [...(pathParameters ?? []), ...(operation.parameters ?? [])];
|
|
142
|
+
for (const param of allParams) {
|
|
127
143
|
if ((0, type_guard_1.isReference)(param)) {
|
|
128
144
|
const ref = param.$ref.split('/').pop();
|
|
129
145
|
results.push({
|
|
@@ -141,12 +157,30 @@ function buildParameters(parameters) {
|
|
|
141
157
|
type: (0, build_types_1.switchTypeJson)(param.schema),
|
|
142
158
|
});
|
|
143
159
|
}
|
|
144
|
-
//
|
|
145
|
-
|
|
160
|
+
// Handle requestBody in V3
|
|
161
|
+
if (operation.requestBody) {
|
|
162
|
+
let bodyType = 'any';
|
|
163
|
+
if (!(0, type_guard_1.isReference)(operation.requestBody)) {
|
|
164
|
+
const content = operation.requestBody.content?.['application/json'] ||
|
|
165
|
+
operation.requestBody.content?.['multipart/form-data'];
|
|
166
|
+
if (content && content.schema) {
|
|
167
|
+
bodyType = (0, build_types_1.switchTypeJson)(content.schema);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
bodyType = operation.requestBody.$ref.split('/').pop();
|
|
172
|
+
}
|
|
173
|
+
results.push({
|
|
174
|
+
name: bodyType === 'FormData' ? 'formData' : 'body',
|
|
175
|
+
in: 'body',
|
|
176
|
+
required: true,
|
|
177
|
+
type: bodyType,
|
|
178
|
+
});
|
|
179
|
+
}
|
|
146
180
|
return results;
|
|
147
181
|
}
|
|
148
182
|
function buildResponseType(responses) {
|
|
149
|
-
const success = responses['200'] || responses['201'] || responses['default'];
|
|
183
|
+
const success = responses['200'] || responses['201'] || responses['204'] || responses['default'];
|
|
150
184
|
if (!success)
|
|
151
185
|
return 'any';
|
|
152
186
|
if ((0, type_guard_1.isReference)(success))
|
|
@@ -160,19 +194,28 @@ function buildMethodTemplate(method) {
|
|
|
160
194
|
const params = method.parameters
|
|
161
195
|
.map((p) => `${p.name}${p.required ? '' : '?'}: ${p.type}`)
|
|
162
196
|
.join(', ');
|
|
163
|
-
|
|
197
|
+
let pathStr = method.path
|
|
164
198
|
.split('/')
|
|
199
|
+
.filter((s) => s !== '')
|
|
165
200
|
.map((s) => ((0, path_utils_1.isVariable)(s) ? `\${${s.replace(/[{}]/g, '')}}` : s))
|
|
166
201
|
.join('/');
|
|
202
|
+
if (pathStr) {
|
|
203
|
+
pathStr = '/' + pathStr;
|
|
204
|
+
}
|
|
167
205
|
const queryParams = method.parameters.filter((p) => p.in === 'query');
|
|
168
206
|
const bodyParam = method.parameters.find((p) => p.in === 'body');
|
|
169
207
|
let options = '';
|
|
170
208
|
if (queryParams.length > 0) {
|
|
171
209
|
options = `, { params: HttpHelper.toHttpParams({ ${queryParams.map((p) => p.name).join(', ')} }) }`;
|
|
172
210
|
}
|
|
173
|
-
const
|
|
211
|
+
const url = `\`\${this.baseUrl}${pathStr}\``;
|
|
212
|
+
const methodCall = bodyParam
|
|
213
|
+
? `this.http.${method.method}<${method.responseType}>(${url}, ${bodyParam.name}${options})`
|
|
214
|
+
: ['post', 'put', 'patch'].includes(method.method)
|
|
215
|
+
? `this.http.${method.method}<${method.responseType}>(${url}, {}${options})`
|
|
216
|
+
: `this.http.${method.method}<${method.responseType}>(${url}${options})`;
|
|
174
217
|
return `${method.comments}
|
|
175
218
|
${method.name}(${params}): Observable<${method.responseType}> {
|
|
176
|
-
return ${
|
|
219
|
+
return ${methodCall};
|
|
177
220
|
}`;
|
|
178
221
|
}
|
|
@@ -7,7 +7,7 @@ const angularTemplate = (params) => {
|
|
|
7
7
|
import { HttpClient } from "@angular/common/http";
|
|
8
8
|
import { Observable } from "rxjs";
|
|
9
9
|
import { inject, Injectable } from '@angular/core';
|
|
10
|
-
import { ${params.imports} } from '
|
|
10
|
+
import { ${params.imports} } from '../models';
|
|
11
11
|
${params.hasHttpParamsHandler ? (0, http_params_handler_1.httpParamsHandlerImport)() : ''}
|
|
12
12
|
|
|
13
13
|
@Injectable({
|
|
@@ -15,7 +15,7 @@ ${params.hasHttpParamsHandler ? (0, http_params_handler_1.httpParamsHandlerImpor
|
|
|
15
15
|
})
|
|
16
16
|
export class ${params.name}Service {
|
|
17
17
|
|
|
18
|
-
private readonly baseUrl =
|
|
18
|
+
private readonly baseUrl = \`${params.baseUrl}\`;
|
|
19
19
|
private readonly http = inject(HttpClient);
|
|
20
20
|
|
|
21
21
|
${params.methods}
|
|
@@ -1,2 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Modify this function according to your needs and your template.
|
|
3
|
+
* This function is used to handle the http params and how you want it to be
|
|
4
|
+
* used in your service.
|
|
5
|
+
*/
|
|
1
6
|
export declare function httpParamsHandler(params: any): string;
|
|
7
|
+
/**
|
|
8
|
+
* Modify this function according to your needs and your template.
|
|
9
|
+
* This function is used to import anything you need to handle the http params.
|
|
10
|
+
*/
|
|
2
11
|
export declare function httpParamsHandlerImport(): string;
|
|
@@ -2,11 +2,20 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.httpParamsHandler = httpParamsHandler;
|
|
4
4
|
exports.httpParamsHandlerImport = httpParamsHandlerImport;
|
|
5
|
+
/**
|
|
6
|
+
* Modify this function according to your needs and your template.
|
|
7
|
+
* This function is used to handle the http params and how you want it to be
|
|
8
|
+
* used in your service.
|
|
9
|
+
*/
|
|
5
10
|
function httpParamsHandler(params) {
|
|
6
11
|
return `
|
|
7
12
|
const params = HttpHelper.toHttpParams(${params} || {})
|
|
8
13
|
`;
|
|
9
14
|
}
|
|
15
|
+
/**
|
|
16
|
+
* Modify this function according to your needs and your template.
|
|
17
|
+
* This function is used to import anything you need to handle the http params.
|
|
18
|
+
*/
|
|
10
19
|
function httpParamsHandlerImport() {
|
|
11
20
|
return `import { HttpHelper } from '@umss/shared/utils';`;
|
|
12
21
|
}
|
|
@@ -1,3 +1,8 @@
|
|
|
1
1
|
import { InterfaceData } from '../../types/interface-data';
|
|
2
|
+
/**
|
|
3
|
+
* Modify this to add your extends from types.
|
|
4
|
+
* This will be used by the extends from types function
|
|
5
|
+
* to determine if a new interface extends from one of the extends from types.
|
|
6
|
+
*/
|
|
2
7
|
export declare const extendsFromTypes: InterfaceData[];
|
|
3
8
|
export declare function computeExtendsFromType(newInterface: InterfaceData): InterfaceData;
|
|
@@ -2,6 +2,11 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.extendsFromTypes = void 0;
|
|
4
4
|
exports.computeExtendsFromType = computeExtendsFromType;
|
|
5
|
+
/**
|
|
6
|
+
* Modify this to add your extends from types.
|
|
7
|
+
* This will be used by the extends from types function
|
|
8
|
+
* to determine if a new interface extends from one of the extends from types.
|
|
9
|
+
*/
|
|
5
10
|
exports.extendsFromTypes = [
|
|
6
11
|
{
|
|
7
12
|
name: 'PagedRequestDto',
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import { InterfaceData } from '../../types/interface-data';
|
|
2
|
+
/**
|
|
3
|
+
* Modify this to add your generic types.
|
|
4
|
+
* This will be used by the generic types function
|
|
5
|
+
* to determine if a new interface is a generic type.
|
|
6
|
+
*/
|
|
2
7
|
export declare const genericTypesData: InterfaceData[];
|
|
3
8
|
export declare function isGenericType(newInterface: InterfaceData): InterfaceData | undefined;
|
|
4
9
|
export declare function computeGenericType(newInterface: InterfaceData, genericType: InterfaceData): string;
|
|
@@ -3,6 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.genericTypesData = void 0;
|
|
4
4
|
exports.isGenericType = isGenericType;
|
|
5
5
|
exports.computeGenericType = computeGenericType;
|
|
6
|
+
/**
|
|
7
|
+
* Modify this to add your generic types.
|
|
8
|
+
* This will be used by the generic types function
|
|
9
|
+
* to determine if a new interface is a generic type.
|
|
10
|
+
*/
|
|
6
11
|
exports.genericTypesData = [
|
|
7
12
|
{
|
|
8
13
|
name: 'PagedResultDto',
|
|
@@ -3,5 +3,4 @@ export declare function getExtraSegments(fullPath: string, baseUrl: string): str
|
|
|
3
3
|
export declare function removeVariablesFromPath(path: string): string;
|
|
4
4
|
export declare function createBaseUrl(baseSegments: string[]): string;
|
|
5
5
|
export declare function findCommonBaseUrl(paths: string[]): string;
|
|
6
|
-
export declare function pathWithoutVariables(segments: string[]): string;
|
|
7
6
|
export declare function standarizedPath(path: string): string;
|
package/dist/utils/path-utils.js
CHANGED
|
@@ -5,54 +5,58 @@ exports.getExtraSegments = getExtraSegments;
|
|
|
5
5
|
exports.removeVariablesFromPath = removeVariablesFromPath;
|
|
6
6
|
exports.createBaseUrl = createBaseUrl;
|
|
7
7
|
exports.findCommonBaseUrl = findCommonBaseUrl;
|
|
8
|
-
exports.pathWithoutVariables = pathWithoutVariables;
|
|
9
8
|
exports.standarizedPath = standarizedPath;
|
|
10
9
|
function isVariable(segment) {
|
|
11
10
|
return /^\{.+\}$/.test(segment);
|
|
12
11
|
}
|
|
13
12
|
function getExtraSegments(fullPath, baseUrl) {
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
const p1 = fullPath.split('/').filter((s) => s !== '');
|
|
14
|
+
const p2 = baseUrl.split('/').filter((s) => s !== '');
|
|
15
|
+
// Find where baseUrl ends in fullPath
|
|
16
|
+
let i = 0;
|
|
17
|
+
while (i < p1.length && i < p2.length && p1[i].toLowerCase() === p2[i].toLowerCase()) {
|
|
18
|
+
i++;
|
|
16
19
|
}
|
|
17
|
-
|
|
18
|
-
return path.split('/').filter((p) => p !== '');
|
|
20
|
+
return p1.slice(i);
|
|
19
21
|
}
|
|
20
22
|
function removeVariablesFromPath(path) {
|
|
21
|
-
return path.replace(
|
|
23
|
+
return path.replace(/\{.+?\}/g, '');
|
|
22
24
|
}
|
|
23
25
|
function createBaseUrl(baseSegments) {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
const filtered = baseSegments.filter((s) => s !== '');
|
|
27
|
+
if (filtered.length === 0)
|
|
28
|
+
return '/api';
|
|
29
|
+
if (filtered[0].toLowerCase() === 'api')
|
|
30
|
+
return '/' + filtered.join('/');
|
|
31
|
+
return '/api/' + filtered.join('/');
|
|
29
32
|
}
|
|
30
33
|
function findCommonBaseUrl(paths) {
|
|
31
34
|
if (!paths || paths.length === 0)
|
|
32
35
|
return '';
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
+
const splittedPaths = paths.map((p) => p.split('/').filter((s) => s !== ''));
|
|
37
|
+
if (splittedPaths.length === 1)
|
|
38
|
+
return createBaseUrl(pathSegmentsWithoutVariables(splittedPaths[0]));
|
|
36
39
|
const firstPath = splittedPaths[0];
|
|
37
40
|
const commonSegments = [];
|
|
38
41
|
for (let i = 0; i < firstPath.length; i++) {
|
|
39
42
|
const segment = firstPath[i];
|
|
40
43
|
const isCommon = splittedPaths.every((p) => p[i] === segment);
|
|
41
|
-
|
|
44
|
+
const isVariableSegment = isVariable(segment);
|
|
45
|
+
if (isCommon && !isVariableSegment) {
|
|
42
46
|
commonSegments.push(segment);
|
|
43
47
|
}
|
|
44
48
|
else {
|
|
45
49
|
break;
|
|
46
50
|
}
|
|
47
51
|
}
|
|
48
|
-
return
|
|
52
|
+
return createBaseUrl(commonSegments);
|
|
49
53
|
}
|
|
50
|
-
function
|
|
54
|
+
function pathSegmentsWithoutVariables(segments) {
|
|
51
55
|
const firstVariableIndex = segments.findIndex((segment) => isVariable(segment));
|
|
52
56
|
if (firstVariableIndex !== -1) {
|
|
53
|
-
return segments.slice(0, firstVariableIndex)
|
|
57
|
+
return segments.slice(0, firstVariableIndex);
|
|
54
58
|
}
|
|
55
|
-
return segments
|
|
59
|
+
return segments;
|
|
56
60
|
}
|
|
57
61
|
function standarizedPath(path) {
|
|
58
62
|
const splitted = path.split('/');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "swaggular",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"bin": {
|
|
@@ -11,6 +11,14 @@
|
|
|
11
11
|
"README.md",
|
|
12
12
|
"LICENSE"
|
|
13
13
|
],
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "https://github.com/AlexMA2/swaggular.git"
|
|
17
|
+
},
|
|
18
|
+
"bugs": {
|
|
19
|
+
"url": "https://github.com/AlexMA2/swaggular/issues"
|
|
20
|
+
},
|
|
21
|
+
"homepage": "https://github.com/AlexMA2/swaggular#readme",
|
|
14
22
|
"scripts": {
|
|
15
23
|
"start": "node dist/index.js",
|
|
16
24
|
"serve": "npm run build && node dist/index.js",
|