react-query-lightbase-codegen 3.0.0 → 3.1.0
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/generator/clientGenerator.js +34 -12
- package/dist/generator/reactQueryGenerator.js +4 -5
- package/dist/generator/schemaGenerator.js +4 -1
- package/dist/utils.d.ts +2 -1
- package/dist/utils.js +9 -7
- package/package.json +1 -1
- package/src/generator/clientGenerator.ts +34 -14
- package/src/generator/reactQueryGenerator.ts +5 -5
- package/src/generator/schemaGenerator.ts +4 -1
- package/src/utils.ts +10 -7
|
@@ -3,9 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.generateApiClient = generateApiClient;
|
|
4
4
|
const utils_1 = require("../utils");
|
|
5
5
|
function generateAxiosMethod(operation, spec) {
|
|
6
|
-
const { method, path, operationId, summary, description, parameters, requestBody, responses } = operation;
|
|
6
|
+
const { method, path, operationId, summary, description, deprecated, parameters, requestBody, responses } = operation;
|
|
7
7
|
// Generate JSDoc
|
|
8
8
|
const jsDocLines = ["/**"];
|
|
9
|
+
if (deprecated)
|
|
10
|
+
jsDocLines.push(" * @deprecated");
|
|
9
11
|
if (summary)
|
|
10
12
|
jsDocLines.push(` * ${summary}`);
|
|
11
13
|
if (description)
|
|
@@ -19,14 +21,17 @@ function generateAxiosMethod(operation, spec) {
|
|
|
19
21
|
? "query."
|
|
20
22
|
: param.in === "header"
|
|
21
23
|
? "headers."
|
|
22
|
-
: ""
|
|
24
|
+
: param.in === "cookie"
|
|
25
|
+
? "cookies."
|
|
26
|
+
: "";
|
|
23
27
|
jsDocLines.push(` * @param ${prefix}${param.name}${desc}`);
|
|
24
28
|
});
|
|
25
29
|
if (requestBody && "description" in requestBody) {
|
|
26
30
|
jsDocLines.push(` * @param data - ${requestBody.description}`);
|
|
27
31
|
}
|
|
28
|
-
// Add return type description
|
|
29
|
-
const responseDetails = Object.entries(responses).find(([code]) => code.startsWith("2"))
|
|
32
|
+
// Add return type description - prefer 2xx responses, fall back to "default"
|
|
33
|
+
const responseDetails = Object.entries(responses).find(([code]) => code.startsWith("2")) ||
|
|
34
|
+
Object.entries(responses).find(([code]) => code === "default");
|
|
30
35
|
if (responseDetails) {
|
|
31
36
|
const [code, response] = responseDetails;
|
|
32
37
|
const responseObj = response;
|
|
@@ -47,6 +52,7 @@ function generateAxiosMethod(operation, spec) {
|
|
|
47
52
|
const urlParams = parameters?.filter((p) => p.in === "path") || [];
|
|
48
53
|
const queryParams = parameters?.filter((p) => p.in === "query") || [];
|
|
49
54
|
const headerParams = parameters?.filter((p) => p.in === "header") || [];
|
|
55
|
+
const cookieParams = parameters?.filter((p) => p.in === "cookie") || [];
|
|
50
56
|
const isFormData = requestBody && "content" in requestBody && requestBody.content?.["multipart/form-data"];
|
|
51
57
|
const formDataSchema = isFormData
|
|
52
58
|
? (0, utils_1.resolveSchema)(requestBody.content["multipart/form-data"].schema, spec)
|
|
@@ -62,9 +68,20 @@ function generateAxiosMethod(operation, spec) {
|
|
|
62
68
|
const hasData = (parameters && parameters.length > 0) || operation.requestBody;
|
|
63
69
|
const namedType = (0, utils_1.pascalCase)(operationId);
|
|
64
70
|
// Get response type from 2xx response
|
|
65
|
-
const responseType =
|
|
66
|
-
|
|
67
|
-
|
|
71
|
+
const responseType = (() => {
|
|
72
|
+
if (!responseDetails)
|
|
73
|
+
return "unknown";
|
|
74
|
+
const [code, response] = responseDetails;
|
|
75
|
+
// If response has content, use the generated type
|
|
76
|
+
if ("content" in response && response.content) {
|
|
77
|
+
return `T.${namedType}Response${code}`;
|
|
78
|
+
}
|
|
79
|
+
// 204 (No Content) and 205 (Reset Content) should return void
|
|
80
|
+
if (code === "204" || code === "205") {
|
|
81
|
+
return "void";
|
|
82
|
+
}
|
|
83
|
+
return "unknown";
|
|
84
|
+
})();
|
|
68
85
|
const urlWithParams = urlParams.length > 0 ? `\`${path.replace(/{(\w+)}/g, "${encodeURIComponent(data.$1)}")}\`` : `"${path}"`;
|
|
69
86
|
// Handle destructuring based on whether we have primitive request body
|
|
70
87
|
const destructuringLine = hasData
|
|
@@ -106,13 +123,18 @@ function generateAxiosMethod(operation, spec) {
|
|
|
106
123
|
headerParams.length > 0
|
|
107
124
|
? `axiosConfig.headers = { ...axiosConfig.headers, ${headerParams.map((p) => `["${p.name}"]: data["${p.name}"]`).join(", ")} };`
|
|
108
125
|
: "",
|
|
109
|
-
|
|
110
|
-
?
|
|
126
|
+
cookieParams.length > 0
|
|
127
|
+
? `axiosConfig.headers = { ...axiosConfig.headers, Cookie: [${cookieParams.map((p) => `data["${p.name}"] != null ? \`${p.name}=\${data["${p.name}"]}\` : null`).join(", ")}].filter(Boolean).join("; ") };`
|
|
111
128
|
: "",
|
|
129
|
+
// Note: Don't set Content-Type for FormData - Axios will set it automatically with the correct boundary
|
|
112
130
|
requestBody
|
|
113
|
-
?
|
|
114
|
-
|
|
115
|
-
|
|
131
|
+
? responseType === "void"
|
|
132
|
+
? `await apiClient.${method}<${responseType}>(url, ${formDataSchema?.properties || requestBodySchema?.properties ? "bodyData" : "data"}, axiosConfig);`
|
|
133
|
+
: `const res = await apiClient.${method}<${responseType}>(url, ${formDataSchema?.properties || requestBodySchema?.properties ? "bodyData" : "data"}, axiosConfig);`
|
|
134
|
+
: responseType === "void"
|
|
135
|
+
? `await apiClient.${method}<${responseType}>(url, axiosConfig);`
|
|
136
|
+
: `const res = await apiClient.${method}<${responseType}>(url, axiosConfig);`,
|
|
137
|
+
responseType !== "void" ? "return res.data;" : "",
|
|
116
138
|
]
|
|
117
139
|
.filter(Boolean)
|
|
118
140
|
.join("\n ");
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.generateReactQuery = generateReactQuery;
|
|
4
4
|
const utils_1 = require("../utils");
|
|
5
5
|
function generateQueryOptions(operation, spec) {
|
|
6
|
-
const { operationId, parameters, requestBody } = operation;
|
|
6
|
+
const { operationId, parameters, requestBody, deprecated } = operation;
|
|
7
7
|
const hasData = (parameters && parameters.length > 0) || operation.requestBody;
|
|
8
8
|
// Helper to get required fields from a schema
|
|
9
9
|
const getRequiredFields = (schema, context) => {
|
|
@@ -56,8 +56,9 @@ function generateQueryOptions(operation, spec) {
|
|
|
56
56
|
? "!!data"
|
|
57
57
|
: `hasDefinedProps(${paramsVariable}, ${requiredParams.join(", ")})`
|
|
58
58
|
: "true";
|
|
59
|
+
const deprecatedComment = deprecated ? "/** @deprecated */\n" : "";
|
|
59
60
|
return `
|
|
60
|
-
export const ${namedQueryOptions} = (
|
|
61
|
+
${deprecatedComment}export const ${namedQueryOptions} = (
|
|
61
62
|
${hasData ? `props: Partial<Parameters<typeof apiClient.${namedQuery}>[0]>` : `props?: Partial<Parameters<typeof apiClient.${namedQuery}>[0]>`}
|
|
62
63
|
) => {
|
|
63
64
|
${destructuringLine}
|
|
@@ -72,10 +73,8 @@ function generateReactQuery(spec) {
|
|
|
72
73
|
const operations = (0, utils_1.collectOperations)(spec);
|
|
73
74
|
return `import { queryOptions, skipToken } from '@tanstack/react-query';
|
|
74
75
|
import * as apiClient from './${(0, utils_1.specTitle)(spec)}.client';
|
|
75
|
-
// TEMPORARY: allows for backward compatibility imports
|
|
76
|
-
export * from './${(0, utils_1.specTitle)(spec)}.client';
|
|
77
76
|
|
|
78
|
-
const hasDefinedProps = <T extends { [P in K]?:
|
|
77
|
+
const hasDefinedProps = <T extends { [P in K]?: unknown }, K extends PropertyKey>(
|
|
79
78
|
obj: T,
|
|
80
79
|
...keys: K[]
|
|
81
80
|
): obj is T & { [P in K]-?: Exclude<T[P], undefined> } => {
|
|
@@ -87,10 +87,13 @@ function generateTypeDefinitions(spec) {
|
|
|
87
87
|
[]);
|
|
88
88
|
const headerParams = (parameters?.filter((p) => "in" in p && p.in === "header") ||
|
|
89
89
|
[]);
|
|
90
|
-
|
|
90
|
+
const cookieParams = (parameters?.filter((p) => "in" in p && p.in === "cookie") ||
|
|
91
|
+
[]);
|
|
92
|
+
// Add path, query, header, and cookie parameters
|
|
91
93
|
urlParams.forEach((p) => dataProps.push(formatParamProperty(p, true))); // Path params always required
|
|
92
94
|
queryParams.forEach((p) => dataProps.push(formatParamProperty(p)));
|
|
93
95
|
headerParams.forEach((p) => dataProps.push(formatParamProperty(p)));
|
|
96
|
+
cookieParams.forEach((p) => dataProps.push(formatParamProperty(p)));
|
|
94
97
|
// Add request body type if it exists
|
|
95
98
|
const hasData = (parameters && parameters.length > 0) || requestBody;
|
|
96
99
|
let dataType = "undefined";
|
package/dist/utils.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { OpenAPIV3 } from "openapi-types";
|
|
|
2
2
|
/**
|
|
3
3
|
* Supported content types in order of preference
|
|
4
4
|
*/
|
|
5
|
-
export declare const CONTENT_TYPES: readonly ["application/ld+json", "application/json", "multipart/form-data", "application/octet-stream", "application/json;charset=UTF-8"];
|
|
5
|
+
export declare const CONTENT_TYPES: readonly ["application/ld+json", "application/json", "text/plain", "multipart/form-data", "application/octet-stream", "application/json;charset=UTF-8"];
|
|
6
6
|
/**
|
|
7
7
|
* Resolves a schema reference to its actual schema object.
|
|
8
8
|
* If the schema is already a concrete schema (not a $ref), returns it as-is.
|
|
@@ -23,6 +23,7 @@ export interface OperationInfo {
|
|
|
23
23
|
operationId: string;
|
|
24
24
|
summary?: string;
|
|
25
25
|
description?: string;
|
|
26
|
+
deprecated?: boolean;
|
|
26
27
|
parameters: OpenAPIV3.ParameterObject[];
|
|
27
28
|
requestBody?: OpenAPIV3.RequestBodyObject;
|
|
28
29
|
responses: OpenAPIV3.ResponsesObject;
|
package/dist/utils.js
CHANGED
|
@@ -16,6 +16,7 @@ exports.getTypeFromSchema = getTypeFromSchema;
|
|
|
16
16
|
exports.CONTENT_TYPES = [
|
|
17
17
|
"application/ld+json",
|
|
18
18
|
"application/json",
|
|
19
|
+
"text/plain",
|
|
19
20
|
"multipart/form-data",
|
|
20
21
|
"application/octet-stream",
|
|
21
22
|
"application/json;charset=UTF-8",
|
|
@@ -83,6 +84,7 @@ function collectOperations(spec) {
|
|
|
83
84
|
operationId: sanitizeTypeName(operation.operationId || path.replace(/\W+/g, "_")),
|
|
84
85
|
summary: operation.summary,
|
|
85
86
|
description: operation.description,
|
|
87
|
+
deprecated: operation.deprecated,
|
|
86
88
|
parameters: resolveParameters([...(pathItem.parameters || []), ...(operation.parameters || [])]),
|
|
87
89
|
requestBody: resolveRequestBody(operation.requestBody),
|
|
88
90
|
responses: operation.responses,
|
|
@@ -176,7 +178,7 @@ function getTypeFromSchema(schema) {
|
|
|
176
178
|
if ("allOf" in schema && schema.allOf) {
|
|
177
179
|
const types = schema.allOf.map((s) => getTypeFromSchema(s)).filter(Boolean);
|
|
178
180
|
if (types.length === 0)
|
|
179
|
-
return "
|
|
181
|
+
return "unknown";
|
|
180
182
|
const result = types.length === 1 ? types[0] : `(${types.join(" & ")})`;
|
|
181
183
|
return `${result}${nullable}`;
|
|
182
184
|
}
|
|
@@ -184,7 +186,7 @@ function getTypeFromSchema(schema) {
|
|
|
184
186
|
if ("oneOf" in schema && schema.oneOf) {
|
|
185
187
|
const types = schema.oneOf.map((s) => getTypeFromSchema(s)).filter(Boolean);
|
|
186
188
|
if (types.length === 0)
|
|
187
|
-
return "
|
|
189
|
+
return "unknown";
|
|
188
190
|
const result = types.length === 1 ? types[0] : `(${types.join(" | ")})`;
|
|
189
191
|
return `${result}${nullable}`;
|
|
190
192
|
}
|
|
@@ -192,7 +194,7 @@ function getTypeFromSchema(schema) {
|
|
|
192
194
|
if ("anyOf" in schema && schema.anyOf) {
|
|
193
195
|
const types = schema.anyOf.map((s) => getTypeFromSchema(s)).filter(Boolean);
|
|
194
196
|
if (types.length === 0)
|
|
195
|
-
return "
|
|
197
|
+
return "unknown";
|
|
196
198
|
const result = types.length === 1 ? types[0] : `(${types.join(" | ")})`;
|
|
197
199
|
return `${result}${nullable}`;
|
|
198
200
|
}
|
|
@@ -245,16 +247,16 @@ function getTypeFromSchema(schema) {
|
|
|
245
247
|
// Handle objects with additionalProperties
|
|
246
248
|
if (schema.additionalProperties) {
|
|
247
249
|
const valueType = typeof schema.additionalProperties === "boolean"
|
|
248
|
-
? "
|
|
250
|
+
? "unknown"
|
|
249
251
|
: getTypeFromSchema(schema.additionalProperties);
|
|
250
252
|
return `Record<string, ${valueType}>${nullable}`;
|
|
251
253
|
}
|
|
252
254
|
// Default object type when no properties specified
|
|
253
|
-
return `Record<string,
|
|
255
|
+
return `Record<string, unknown>${nullable}`;
|
|
254
256
|
default:
|
|
255
|
-
return `
|
|
257
|
+
return `unknown${nullable}`;
|
|
256
258
|
}
|
|
257
259
|
}
|
|
258
260
|
// Fallback for schemas without a type
|
|
259
|
-
return "
|
|
261
|
+
return "unknown";
|
|
260
262
|
}
|
package/package.json
CHANGED
|
@@ -10,9 +10,11 @@ import {
|
|
|
10
10
|
} from "../utils";
|
|
11
11
|
|
|
12
12
|
function generateAxiosMethod(operation: OperationInfo, spec: OpenAPIV3.Document): string {
|
|
13
|
-
const { method, path, operationId, summary, description, parameters, requestBody, responses } =
|
|
13
|
+
const { method, path, operationId, summary, description, deprecated, parameters, requestBody, responses } =
|
|
14
|
+
operation;
|
|
14
15
|
// Generate JSDoc
|
|
15
16
|
const jsDocLines = ["/**"];
|
|
17
|
+
if (deprecated) jsDocLines.push(" * @deprecated");
|
|
16
18
|
if (summary) jsDocLines.push(` * ${summary}`);
|
|
17
19
|
if (description) jsDocLines.push(` * ${description}`);
|
|
18
20
|
|
|
@@ -26,7 +28,9 @@ function generateAxiosMethod(operation: OperationInfo, spec: OpenAPIV3.Document)
|
|
|
26
28
|
? "query."
|
|
27
29
|
: param.in === "header"
|
|
28
30
|
? "headers."
|
|
29
|
-
: ""
|
|
31
|
+
: param.in === "cookie"
|
|
32
|
+
? "cookies."
|
|
33
|
+
: "";
|
|
30
34
|
jsDocLines.push(` * @param ${prefix}${param.name}${desc}`);
|
|
31
35
|
});
|
|
32
36
|
|
|
@@ -34,8 +38,10 @@ function generateAxiosMethod(operation: OperationInfo, spec: OpenAPIV3.Document)
|
|
|
34
38
|
jsDocLines.push(` * @param data - ${requestBody.description}`);
|
|
35
39
|
}
|
|
36
40
|
|
|
37
|
-
// Add return type description
|
|
38
|
-
const responseDetails =
|
|
41
|
+
// Add return type description - prefer 2xx responses, fall back to "default"
|
|
42
|
+
const responseDetails =
|
|
43
|
+
Object.entries(responses).find(([code]) => code.startsWith("2")) ||
|
|
44
|
+
Object.entries(responses).find(([code]) => code === "default");
|
|
39
45
|
if (responseDetails) {
|
|
40
46
|
const [code, response] = responseDetails;
|
|
41
47
|
const responseObj = response as OpenAPIV3.ResponseObject;
|
|
@@ -58,6 +64,7 @@ function generateAxiosMethod(operation: OperationInfo, spec: OpenAPIV3.Document)
|
|
|
58
64
|
const urlParams = parameters?.filter((p) => p.in === "path") || [];
|
|
59
65
|
const queryParams = parameters?.filter((p) => p.in === "query") || [];
|
|
60
66
|
const headerParams = parameters?.filter((p) => p.in === "header") || [];
|
|
67
|
+
const cookieParams = parameters?.filter((p) => p.in === "cookie") || [];
|
|
61
68
|
|
|
62
69
|
const isFormData = requestBody && "content" in requestBody && requestBody.content?.["multipart/form-data"];
|
|
63
70
|
|
|
@@ -82,11 +89,19 @@ function generateAxiosMethod(operation: OperationInfo, spec: OpenAPIV3.Document)
|
|
|
82
89
|
const namedType = pascalCase(operationId);
|
|
83
90
|
|
|
84
91
|
// Get response type from 2xx response
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
92
|
+
const responseType = (() => {
|
|
93
|
+
if (!responseDetails) return "unknown";
|
|
94
|
+
const [code, response] = responseDetails;
|
|
95
|
+
// If response has content, use the generated type
|
|
96
|
+
if ("content" in response && response.content) {
|
|
97
|
+
return `T.${namedType}Response${code}`;
|
|
98
|
+
}
|
|
99
|
+
// 204 (No Content) and 205 (Reset Content) should return void
|
|
100
|
+
if (code === "204" || code === "205") {
|
|
101
|
+
return "void";
|
|
102
|
+
}
|
|
103
|
+
return "unknown";
|
|
104
|
+
})();
|
|
90
105
|
|
|
91
106
|
const urlWithParams =
|
|
92
107
|
urlParams.length > 0 ? `\`${path.replace(/{(\w+)}/g, "${encodeURIComponent(data.$1)}")}\`` : `"${path}"`;
|
|
@@ -134,13 +149,18 @@ function generateAxiosMethod(operation: OperationInfo, spec: OpenAPIV3.Document)
|
|
|
134
149
|
headerParams.length > 0
|
|
135
150
|
? `axiosConfig.headers = { ...axiosConfig.headers, ${headerParams.map((p) => `["${p.name}"]: data["${p.name}"]`).join(", ")} };`
|
|
136
151
|
: "",
|
|
137
|
-
|
|
138
|
-
?
|
|
152
|
+
cookieParams.length > 0
|
|
153
|
+
? `axiosConfig.headers = { ...axiosConfig.headers, Cookie: [${cookieParams.map((p) => `data["${p.name}"] != null ? \`${p.name}=\${data["${p.name}"]}\` : null`).join(", ")}].filter(Boolean).join("; ") };`
|
|
139
154
|
: "",
|
|
155
|
+
// Note: Don't set Content-Type for FormData - Axios will set it automatically with the correct boundary
|
|
140
156
|
requestBody
|
|
141
|
-
?
|
|
142
|
-
|
|
143
|
-
|
|
157
|
+
? responseType === "void"
|
|
158
|
+
? `await apiClient.${method}<${responseType}>(url, ${formDataSchema?.properties || requestBodySchema?.properties ? "bodyData" : "data"}, axiosConfig);`
|
|
159
|
+
: `const res = await apiClient.${method}<${responseType}>(url, ${formDataSchema?.properties || requestBodySchema?.properties ? "bodyData" : "data"}, axiosConfig);`
|
|
160
|
+
: responseType === "void"
|
|
161
|
+
? `await apiClient.${method}<${responseType}>(url, axiosConfig);`
|
|
162
|
+
: `const res = await apiClient.${method}<${responseType}>(url, axiosConfig);`,
|
|
163
|
+
responseType !== "void" ? "return res.data;" : "",
|
|
144
164
|
]
|
|
145
165
|
.filter(Boolean)
|
|
146
166
|
.join("\n ");
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
} from "../utils";
|
|
10
10
|
|
|
11
11
|
function generateQueryOptions(operation: OperationInfo, spec: OpenAPIV3.Document): string {
|
|
12
|
-
const { operationId, parameters, requestBody } = operation;
|
|
12
|
+
const { operationId, parameters, requestBody, deprecated } = operation;
|
|
13
13
|
|
|
14
14
|
const hasData = (parameters && parameters.length > 0) || operation.requestBody;
|
|
15
15
|
|
|
@@ -78,8 +78,10 @@ function generateQueryOptions(operation: OperationInfo, spec: OpenAPIV3.Document
|
|
|
78
78
|
: `hasDefinedProps(${paramsVariable}, ${requiredParams.join(", ")})`
|
|
79
79
|
: "true";
|
|
80
80
|
|
|
81
|
+
const deprecatedComment = deprecated ? "/** @deprecated */\n" : "";
|
|
82
|
+
|
|
81
83
|
return `
|
|
82
|
-
export const ${namedQueryOptions} = (
|
|
84
|
+
${deprecatedComment}export const ${namedQueryOptions} = (
|
|
83
85
|
${hasData ? `props: Partial<Parameters<typeof apiClient.${namedQuery}>[0]>` : `props?: Partial<Parameters<typeof apiClient.${namedQuery}>[0]>`}
|
|
84
86
|
) => {
|
|
85
87
|
${destructuringLine}
|
|
@@ -96,10 +98,8 @@ export function generateReactQuery(spec: OpenAPIV3.Document): string {
|
|
|
96
98
|
|
|
97
99
|
return `import { queryOptions, skipToken } from '@tanstack/react-query';
|
|
98
100
|
import * as apiClient from './${specTitle(spec)}.client';
|
|
99
|
-
// TEMPORARY: allows for backward compatibility imports
|
|
100
|
-
export * from './${specTitle(spec)}.client';
|
|
101
101
|
|
|
102
|
-
const hasDefinedProps = <T extends { [P in K]?:
|
|
102
|
+
const hasDefinedProps = <T extends { [P in K]?: unknown }, K extends PropertyKey>(
|
|
103
103
|
obj: T,
|
|
104
104
|
...keys: K[]
|
|
105
105
|
): obj is T & { [P in K]-?: Exclude<T[P], undefined> } => {
|
|
@@ -109,11 +109,14 @@ export function generateTypeDefinitions(spec: OpenAPIV3.Document): string {
|
|
|
109
109
|
[]) as OpenAPIV3.ParameterObject[];
|
|
110
110
|
const headerParams = (parameters?.filter((p) => "in" in p && p.in === "header") ||
|
|
111
111
|
[]) as OpenAPIV3.ParameterObject[];
|
|
112
|
+
const cookieParams = (parameters?.filter((p) => "in" in p && p.in === "cookie") ||
|
|
113
|
+
[]) as OpenAPIV3.ParameterObject[];
|
|
112
114
|
|
|
113
|
-
// Add path, query, and
|
|
115
|
+
// Add path, query, header, and cookie parameters
|
|
114
116
|
urlParams.forEach((p) => dataProps.push(formatParamProperty(p, true))); // Path params always required
|
|
115
117
|
queryParams.forEach((p) => dataProps.push(formatParamProperty(p)));
|
|
116
118
|
headerParams.forEach((p) => dataProps.push(formatParamProperty(p)));
|
|
119
|
+
cookieParams.forEach((p) => dataProps.push(formatParamProperty(p)));
|
|
117
120
|
|
|
118
121
|
// Add request body type if it exists
|
|
119
122
|
const hasData = (parameters && parameters.length > 0) || requestBody;
|
package/src/utils.ts
CHANGED
|
@@ -6,6 +6,7 @@ import type { OpenAPIV3 } from "openapi-types";
|
|
|
6
6
|
export const CONTENT_TYPES = [
|
|
7
7
|
"application/ld+json",
|
|
8
8
|
"application/json",
|
|
9
|
+
"text/plain",
|
|
9
10
|
"multipart/form-data",
|
|
10
11
|
"application/octet-stream",
|
|
11
12
|
"application/json;charset=UTF-8",
|
|
@@ -51,6 +52,7 @@ export interface OperationInfo {
|
|
|
51
52
|
operationId: string;
|
|
52
53
|
summary?: string;
|
|
53
54
|
description?: string;
|
|
55
|
+
deprecated?: boolean;
|
|
54
56
|
parameters: OpenAPIV3.ParameterObject[];
|
|
55
57
|
requestBody?: OpenAPIV3.RequestBodyObject;
|
|
56
58
|
responses: OpenAPIV3.ResponsesObject;
|
|
@@ -100,6 +102,7 @@ export function collectOperations(spec: OpenAPIV3.Document): OperationInfo[] {
|
|
|
100
102
|
operationId: sanitizeTypeName(operation.operationId || path.replace(/\W+/g, "_")),
|
|
101
103
|
summary: operation.summary,
|
|
102
104
|
description: operation.description,
|
|
105
|
+
deprecated: operation.deprecated,
|
|
103
106
|
parameters: resolveParameters([...(pathItem.parameters || []), ...(operation.parameters || [])]),
|
|
104
107
|
requestBody: resolveRequestBody(operation.requestBody),
|
|
105
108
|
responses: operation.responses,
|
|
@@ -202,7 +205,7 @@ export function getTypeFromSchema(
|
|
|
202
205
|
// Handle allOf (intersection types)
|
|
203
206
|
if ("allOf" in schema && schema.allOf) {
|
|
204
207
|
const types = schema.allOf.map((s) => getTypeFromSchema(s)).filter(Boolean) as string[];
|
|
205
|
-
if (types.length === 0) return "
|
|
208
|
+
if (types.length === 0) return "unknown";
|
|
206
209
|
const result = types.length === 1 ? types[0] : `(${types.join(" & ")})`;
|
|
207
210
|
return `${result}${nullable}`;
|
|
208
211
|
}
|
|
@@ -210,7 +213,7 @@ export function getTypeFromSchema(
|
|
|
210
213
|
// Handle oneOf (union types - exactly one)
|
|
211
214
|
if ("oneOf" in schema && schema.oneOf) {
|
|
212
215
|
const types = schema.oneOf.map((s) => getTypeFromSchema(s)).filter(Boolean) as string[];
|
|
213
|
-
if (types.length === 0) return "
|
|
216
|
+
if (types.length === 0) return "unknown";
|
|
214
217
|
const result = types.length === 1 ? types[0] : `(${types.join(" | ")})`;
|
|
215
218
|
return `${result}${nullable}`;
|
|
216
219
|
}
|
|
@@ -218,7 +221,7 @@ export function getTypeFromSchema(
|
|
|
218
221
|
// Handle anyOf (union types - one or more)
|
|
219
222
|
if ("anyOf" in schema && schema.anyOf) {
|
|
220
223
|
const types = schema.anyOf.map((s) => getTypeFromSchema(s)).filter(Boolean) as string[];
|
|
221
|
-
if (types.length === 0) return "
|
|
224
|
+
if (types.length === 0) return "unknown";
|
|
222
225
|
const result = types.length === 1 ? types[0] : `(${types.join(" | ")})`;
|
|
223
226
|
return `${result}${nullable}`;
|
|
224
227
|
}
|
|
@@ -282,19 +285,19 @@ export function getTypeFromSchema(
|
|
|
282
285
|
if (schema.additionalProperties) {
|
|
283
286
|
const valueType =
|
|
284
287
|
typeof schema.additionalProperties === "boolean"
|
|
285
|
-
? "
|
|
288
|
+
? "unknown"
|
|
286
289
|
: getTypeFromSchema(schema.additionalProperties);
|
|
287
290
|
return `Record<string, ${valueType}>${nullable}`;
|
|
288
291
|
}
|
|
289
292
|
|
|
290
293
|
// Default object type when no properties specified
|
|
291
|
-
return `Record<string,
|
|
294
|
+
return `Record<string, unknown>${nullable}`;
|
|
292
295
|
|
|
293
296
|
default:
|
|
294
|
-
return `
|
|
297
|
+
return `unknown${nullable}`;
|
|
295
298
|
}
|
|
296
299
|
}
|
|
297
300
|
|
|
298
301
|
// Fallback for schemas without a type
|
|
299
|
-
return "
|
|
302
|
+
return "unknown";
|
|
300
303
|
}
|