swaggular 0.2.2 → 0.2.3

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,192 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.toCamelCase = toCamelCase;
4
- exports.toExtra = toExtra;
5
- exports.generateBaseUrl = generateBaseUrl;
6
- exports.transformGroupedPathsToAngularServices = transformGroupedPathsToAngularServices;
7
- const generate_imports_1 = require("../utils/generate-imports");
8
- const method_builders_1 = require("../utils/method-builders");
9
- /* ============================================================
10
- * LOW-LEVEL HELPERS
11
- * ============================================================ */
12
- function isVariable(segment) {
13
- return /^\{.+\}$/.test(segment);
14
- }
15
- function kebabToPascal(value) {
16
- return value
17
- .split("-")
18
- .map((v) => v.charAt(0).toUpperCase() + v.slice(1))
19
- .join("");
20
- }
21
- function extractPathVariables(path) {
22
- return path
23
- .split("/")
24
- .filter(isVariable)
25
- .map((v) => v.slice(1, -1));
26
- }
27
- function endsWithVariable(path) {
28
- const parts = path.split("/").filter(Boolean);
29
- return isVariable(parts[parts.length - 1]);
30
- }
31
- /**
32
- * Detecta si la ruta es hija del grupo y devuelve el nombre del recurso hijo
33
- * /A/{id}/B/{x} -> B
34
- */
35
- function getChildResource(path, baseSegments) {
36
- const segments = path
37
- .split("/")
38
- .filter(Boolean)
39
- .filter((s) => s !== "api");
40
- let count = 0;
41
- for (const seg of segments) {
42
- if (isVariable(seg))
43
- continue;
44
- count++;
45
- if (count > baseSegments.length) {
46
- return seg;
47
- }
48
- }
49
- return null;
50
- }
51
- /* ============================================================
52
- * METHOD NAME RESOLUTION (TU DICCIONARIO)
53
- * ============================================================ */
54
- function resolveMethodName(http, endsInVar, child, putNoVarAlreadyExists = false) {
55
- let base;
56
- switch (http) {
57
- case "get":
58
- base = endsInVar ? "get" : "getAll";
59
- break;
60
- case "post":
61
- base = "create";
62
- break;
63
- case "put":
64
- base = endsInVar
65
- ? "update"
66
- : putNoVarAlreadyExists
67
- ? "updateAll"
68
- : "update";
69
- break;
70
- case "delete":
71
- base = "delete";
72
- break;
73
- case "patch":
74
- base = "patch";
75
- break;
76
- }
77
- return child ? base + kebabToPascal(child) : base;
78
- }
79
- function toCamelCase(value) {
80
- const firstCharacter = value.at(0);
81
- return firstCharacter?.toLowerCase() + value.slice(1);
82
- }
83
- function toExtra(segments) {
84
- let path = ``;
85
- segments.forEach((s) => {
86
- const isVariable = s.startsWith("{");
87
- path += isVariable ? `/\${${toCamelCase(s.slice(1, -1))}}` : `/${s}`;
88
- });
89
- return path;
90
- }
91
- function generateBaseUrl(baseSegments, paths) {
92
- const splitted = paths[0].split("/").filter(Boolean);
93
- const foundIndex = splitted.findIndex((s) => s === baseSegments[baseSegments.length - 1]);
94
- const foundVariable = splitted.findIndex((s) => s.includes("{"));
95
- if (foundIndex > foundVariable && foundVariable >= 0) {
96
- const base = "/" + splitted.slice(0, foundVariable).join("/");
97
- return base;
98
- }
99
- return "/" + splitted.slice(0, foundIndex + 1).join("/");
100
- }
101
- /* ============================================================
102
- * 🚀 MAIN TRANSFORMER
103
- * ============================================================ */
104
- function transformGroupedPathsToAngularServices(grouped, openApiPaths) {
105
- const services = [];
106
- const parametersTypes = {};
107
- for (const group of Object.values(grouped)) {
108
- const groupName = group.groupName;
109
- const baseUrl = generateBaseUrl(group.baseSegments, group.paths);
110
- const methods = [];
111
- const imports = [];
112
- let putWithoutVarExists = false;
113
- for (const path of group.paths) {
114
- const ops = openApiPaths[path];
115
- if (!ops)
116
- continue;
117
- const variables = extractPathVariables(path);
118
- const endsInVar = endsWithVariable(path);
119
- const child = getChildResource(path, group.baseSegments);
120
- for (const http of Object.keys(ops)) {
121
- const op = ops[http];
122
- const methodName = resolveMethodName(http, endsInVar, child ?? undefined, putWithoutVarExists);
123
- if (http === "put" && !endsInVar) {
124
- if (putWithoutVarExists)
125
- continue;
126
- putWithoutVarExists = true;
127
- }
128
- /* =====================
129
- * PARAMS
130
- * ===================== */
131
- const params = [];
132
- variables.forEach((v) => params.push(`${v}: string`));
133
- let hasParameters = false;
134
- // QUERY PARAMS (group-scoped)
135
- if (http === "get" && op.parameters?.some((p) => p.in === "query")) {
136
- hasParameters = true;
137
- params.push(`parameters?: ${groupName}Parameters`);
138
- imports.push(`${groupName}Parameters`);
139
- }
140
- // REQUEST BODY (group-scoped + validated against schemas)
141
- let requestBodyType = (0, method_builders_1.computeRequestBodyType)(op.requestBody);
142
- if (requestBodyType) {
143
- params.push(`requestBody: ${requestBodyType}`);
144
- imports.push(requestBodyType);
145
- if (requestBodyType.endsWith("Parameters")) {
146
- parametersTypes[methodName] = {
147
- method: http,
148
- parameterType: requestBodyType,
149
- };
150
- }
151
- }
152
- /* =====================
153
- * RESPONSE TYPE (group-scoped)
154
- * ===================== */
155
- let responseType = (0, method_builders_1.computeResponseType)(op.responses?.["200"]);
156
- imports.push(responseType);
157
- /* =====================
158
- * METHOD BODY
159
- * ===================== */
160
- let body = "";
161
- if (http === "get") {
162
- body = (0, method_builders_1.buildGetContent)(responseType, path, baseUrl, hasParameters);
163
- }
164
- if (http === "post") {
165
- body = (0, method_builders_1.buildPostContent)(responseType, path, baseUrl, !!requestBodyType);
166
- }
167
- if (http === "put") {
168
- body = (0, method_builders_1.buildPutContent)(responseType, path, baseUrl, !!requestBodyType);
169
- }
170
- if (http === "patch") {
171
- body = (0, method_builders_1.buildPatchContent)(responseType, path, baseUrl, !!requestBodyType);
172
- }
173
- if (http === "delete") {
174
- body = (0, method_builders_1.buildDeleteContent)(responseType, path, baseUrl, hasParameters);
175
- }
176
- methods.push(`\t${methodName}(${params.join(", ")}): Observable<${responseType}> {
177
- ${body}
178
- \t}\n`);
179
- }
180
- }
181
- services.push({
182
- name: groupName,
183
- baseUrl,
184
- methods: methods.join("\n"),
185
- imports: (0, generate_imports_1.getImports)(imports).join(", "),
186
- });
187
- }
188
- return {
189
- forTemplate: services,
190
- parametersTypes,
191
- };
192
- }
@@ -1,16 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.joinWithTemplates = joinWithTemplates;
4
- const angular_template_1 = require("../templates/angular-template");
5
- function joinWithTemplates(services) {
6
- const templates = [];
7
- services.forEach((s) => {
8
- if (s.baseUrl.trim() === "" ||
9
- s.methods.trim() === "" ||
10
- s.name.trim() === "") {
11
- return;
12
- }
13
- templates.push((0, angular_template_1.angularServiceTemplate)(s));
14
- });
15
- return templates;
16
- }
@@ -1,8 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.splitPaths = splitPaths;
4
- const grouping_paths_1 = require("../utils/grouping-paths");
5
- function splitPaths(swagger) {
6
- const groupedPaths = (0, grouping_paths_1.groupPaths)(swagger.paths);
7
- return groupedPaths;
8
- }
@@ -1,33 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.primitivesTypes = void 0;
4
- exports.getImports = getImports;
5
- exports.primitivesTypes = [
6
- "string",
7
- "number",
8
- "boolean",
9
- "void",
10
- "any",
11
- "blob",
12
- "file",
13
- ];
14
- function getImports(typeNames) {
15
- const realImports = new Set();
16
- for (const typeName of typeNames) {
17
- const transformedTypeName = typeName
18
- .replaceAll("[", "")
19
- .replaceAll("]", "");
20
- if (exports.primitivesTypes.includes(transformedTypeName.toLowerCase())) {
21
- continue;
22
- }
23
- if (transformedTypeName.includes("<")) {
24
- const types = transformedTypeName.replaceAll(">", "").split("<");
25
- types.forEach((t) => {
26
- realImports.add(t.trim());
27
- });
28
- continue;
29
- }
30
- realImports.add(transformedTypeName);
31
- }
32
- return Array.from(realImports);
33
- }
@@ -1,68 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.groupPaths = groupPaths;
4
- function isVariable(segment) {
5
- return /^\{.+\}$/.test(segment);
6
- }
7
- function normalizeSegment(segment) {
8
- return segment
9
- .split("-")
10
- .map((s) => s.charAt(0).toUpperCase() + s.slice(1))
11
- .join("");
12
- }
13
- function toPascalCase(segments) {
14
- return segments.map(normalizeSegment).join("");
15
- }
16
- function extractNonVariableSegments(path) {
17
- return path
18
- .split("/")
19
- .filter(Boolean)
20
- .filter((s) => s !== "api")
21
- .filter((s) => !isVariable(s));
22
- }
23
- function groupPaths(paths) {
24
- const temp = {};
25
- // 1️⃣ recolectar segmentos NO variables (ignorando /api) pero guardar el path original
26
- for (const originalPath of Object.keys(paths)) {
27
- if (!originalPath.startsWith("/api/"))
28
- continue;
29
- const clean = originalPath.replace(/^\/api\//, "");
30
- const segments = clean.split("/").filter((s) => s && !isVariable(s));
31
- if (segments.length === 0)
32
- continue;
33
- const root = segments[0];
34
- if (!temp[root])
35
- temp[root] = [];
36
- temp[root].push({
37
- originalPath,
38
- segments,
39
- });
40
- }
41
- const groups = {};
42
- // 2️⃣ decidir si colapsa por root o usa deep=2
43
- for (const [root, entries] of Object.entries(temp)) {
44
- const hasDeeperStructure = entries.some((e) => e.segments.length >= 3);
45
- for (const entry of entries) {
46
- let baseSegments;
47
- if (!hasDeeperStructure) {
48
- // colapsa por root común
49
- baseSegments = [root];
50
- }
51
- else {
52
- // deep máximo = 2
53
- baseSegments = entry.segments.slice(0, 2);
54
- }
55
- const groupName = toPascalCase(baseSegments);
56
- if (!groups[groupName]) {
57
- groups[groupName] = {
58
- groupName,
59
- baseSegments,
60
- paths: [],
61
- };
62
- }
63
- // ✅ path completo, con /api y variables
64
- groups[groupName].paths.push(entry.originalPath);
65
- }
66
- }
67
- return groups;
68
- }
@@ -1,77 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.computeResponseType = computeResponseType;
4
- exports.computeRequestBodyType = computeRequestBodyType;
5
- exports.buildUrl = buildUrl;
6
- exports.buildGetContent = buildGetContent;
7
- exports.buildPutContent = buildPutContent;
8
- exports.buildPostContent = buildPostContent;
9
- exports.buildDeleteContent = buildDeleteContent;
10
- exports.buildPatchContent = buildPatchContent;
11
- const build_types_1 = require("./build-types");
12
- const to_case_1 = require("./to-case");
13
- function computeResponseType(successSchema) {
14
- return (0, build_types_1.buildTypes)(successSchema, "void");
15
- }
16
- function computeRequestBodyType(requestBodySchema) {
17
- const content = requestBodySchema?.content;
18
- if (!content || Object.keys(content).length === 0)
19
- return null;
20
- return (0, build_types_1.buildTypes)(requestBodySchema, "any");
21
- }
22
- function buildUrl(path, baseUrl) {
23
- const leftover = path.replace(baseUrl, "");
24
- const segments = leftover.split("/").filter(Boolean);
25
- let finalUrl = `\`\${this.baseUrl}`;
26
- segments.forEach((s) => {
27
- if (s.startsWith("{") && s.endsWith("}")) {
28
- const id = (0, to_case_1.lowerFirst)(s.replace("{", "").replace("}", ""));
29
- finalUrl += `/\${${id}}`;
30
- }
31
- else {
32
- finalUrl += `/${s}`;
33
- }
34
- });
35
- finalUrl += `\``;
36
- return finalUrl;
37
- }
38
- function buildGetContent(responseType, path, baseUrl, hasParameters) {
39
- const finalUrl = buildUrl(path, baseUrl);
40
- if (hasParameters) {
41
- return `\t\tconst params = HttpHelper.toHttpParams(parameters ?? {});
42
- \t\treturn this.http.get<${responseType}>(${finalUrl}, { params });`;
43
- }
44
- if (responseType === "Blob") {
45
- return `\t\treturn this.http.get(${finalUrl}, { responseType: 'blob' });`;
46
- }
47
- return `\t\treturn this.http.get<${responseType}>(${finalUrl});`;
48
- }
49
- function buildPutContent(responseType, path, baseUrl, hasRequestBody) {
50
- const finalUrl = buildUrl(path, baseUrl);
51
- if (!hasRequestBody) {
52
- return `\t\treturn this.http.put<${responseType}>(${finalUrl});`;
53
- }
54
- return `\t\treturn this.http.put<${responseType}>(${finalUrl}, requestBody);`;
55
- }
56
- function buildPostContent(responseType, path, baseUrl, hasRequestBody) {
57
- const finalUrl = buildUrl(path, baseUrl);
58
- if (!hasRequestBody) {
59
- return `\t\treturn this.http.post<${responseType}>(${finalUrl});`;
60
- }
61
- return `\t\treturn this.http.post<${responseType}>(${finalUrl}, requestBody);`;
62
- }
63
- function buildDeleteContent(responseType, path, baseUrl, hasParameters) {
64
- const finalUrl = buildUrl(path, baseUrl);
65
- if (hasParameters) {
66
- return `\t\tconst params = HttpHelper.toHttpParams(parameters ?? {});
67
- \t\treturn this.http.delete<${responseType}>(${finalUrl}, { params });`;
68
- }
69
- return `\t\treturn this.http.delete<${responseType}>(${finalUrl});`;
70
- }
71
- function buildPatchContent(responseType, path, baseUrl, hasRequestBody) {
72
- const finalUrl = buildUrl(path, baseUrl);
73
- if (!hasRequestBody) {
74
- return `\t\treturn this.http.patch<${responseType}>(${finalUrl});`;
75
- }
76
- return `\t\treturn this.http.patch<${responseType}>(${finalUrl}, requestBody);`;
77
- }
@@ -1,47 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.kebabToCamelCase = kebabToCamelCase;
4
- exports.kebabToPascalCase = kebabToPascalCase;
5
- exports.toThisType = toThisType;
6
- exports.lowerFirst = lowerFirst;
7
- exports.upFirst = upFirst;
8
- exports.toKebabCase = toKebabCase;
9
- exports.normalizeSegment = normalizeSegment;
10
- exports.toPascalCase = toPascalCase;
11
- function kebabToCamelCase(str) {
12
- return str.replace(/-([a-z])/g, (_, char) => char.toUpperCase());
13
- }
14
- /**
15
- *
16
- * @param str :
17
- * @returns
18
- */
19
- function kebabToPascalCase(str) {
20
- const camel = str.replace(/-([a-z])/g, (_, char) => char.toUpperCase());
21
- return camel.charAt(0).toUpperCase() + camel.slice(1);
22
- }
23
- function toThisType(str) {
24
- return kebabToPascalCase(str).replace(/s$/, "");
25
- }
26
- function lowerFirst(str) {
27
- return str.charAt(0).toLowerCase() + str.slice(1);
28
- }
29
- function upFirst(str) {
30
- return str.charAt(0).toUpperCase() + str.slice(1);
31
- }
32
- function toKebabCase(input) {
33
- const transformedInput = input.replaceAll("Dto", "");
34
- return (transformedInput.length > 0 ? transformedInput : input)
35
- .replace(/([a-z0-9])([A-Z])/g, "$1-$2")
36
- .replace(/([A-Z])([A-Z][a-z])/g, "$1-$2")
37
- .toLowerCase();
38
- }
39
- function normalizeSegment(segment) {
40
- return segment
41
- .split("-")
42
- .map((s) => s.charAt(0).toUpperCase() + s.slice(1))
43
- .join("");
44
- }
45
- function toPascalCase(segments) {
46
- return segments.map(normalizeSegment).join("");
47
- }