elysia-openapi-codegen 0.1.5 → 0.1.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/index.js +43 -16
- package/package.json +19 -19
package/dist/index.js
CHANGED
|
@@ -77,7 +77,7 @@ function generateTypes(spec) {
|
|
|
77
77
|
if (!["get", "post", "put", "patch", "delete"].includes(method))
|
|
78
78
|
continue;
|
|
79
79
|
const op = operation;
|
|
80
|
-
const opId = op.operationId || `${method}${pathUrl.replace(/[^a-zA-Z0-9]/g, "")}
|
|
80
|
+
const opId = toSafeIdentifier(op.operationId || `${method}${pathUrl.replace(/[^a-zA-Z0-9]/g, "")}`);
|
|
81
81
|
const response = op.responses?.["200"];
|
|
82
82
|
if (response?.content?.["application/json"]?.schema) {
|
|
83
83
|
const responseType = resolveType(response.content["application/json"].schema);
|
|
@@ -112,7 +112,7 @@ function generateHooks(spec) {
|
|
|
112
112
|
if (!["get", "post", "put", "patch", "delete"].includes(method))
|
|
113
113
|
continue;
|
|
114
114
|
const op = operation;
|
|
115
|
-
const opId = op.operationId || `${method}${pathUrl.replace(/[^a-zA-Z0-9]/g, "")}
|
|
115
|
+
const opId = toSafeIdentifier(op.operationId || `${method}${pathUrl.replace(/[^a-zA-Z0-9]/g, "")}`);
|
|
116
116
|
const hasResponse = !!op.responses?.["200"]?.content?.["application/json"]?.schema;
|
|
117
117
|
const responseType = hasResponse ? `${capitalize(opId)}Response` : "any";
|
|
118
118
|
const params = op.parameters || [];
|
|
@@ -121,8 +121,18 @@ function generateHooks(spec) {
|
|
|
121
121
|
const hasBody = !!op.requestBody?.content?.["application/json"]?.schema;
|
|
122
122
|
const bodyType = hasBody ? `${capitalize(opId)}Body` : "void";
|
|
123
123
|
if (method === "get") {
|
|
124
|
-
const
|
|
125
|
-
const
|
|
124
|
+
const pathParamsList = params.filter((p) => p.in === "path");
|
|
125
|
+
const queryParamsList = params.filter((p) => p.in === "query");
|
|
126
|
+
let urlPath = pathUrl;
|
|
127
|
+
for (const p of pathParamsList) {
|
|
128
|
+
urlPath = urlPath.replace(`{${p.name}}`, `\${params.${p.name}}`);
|
|
129
|
+
}
|
|
130
|
+
const qsLines = queryParamsList.map((p) => ` if (params?.${p.name} !== undefined) _qs.set('${p.name}', String(params.${p.name}));`).join(`
|
|
131
|
+
`);
|
|
132
|
+
const fetchStatement = queryParamsList.length > 0 ? ` const _qs = new URLSearchParams();
|
|
133
|
+
${qsLines}
|
|
134
|
+
const _qstr = _qs.toString();
|
|
135
|
+
const res = await fetch(\`\${baseUrl}${urlPath}\${_qstr ? '?' + _qstr : ''}\`);` : ` const res = await fetch(\`\${baseUrl}${urlPath}\`);`;
|
|
126
136
|
hooks.push(`
|
|
127
137
|
export const use${capitalize(opId)} = (
|
|
128
138
|
params${hasParams ? "" : "?"}: ${paramsType},
|
|
@@ -131,7 +141,7 @@ export const use${capitalize(opId)} = (
|
|
|
131
141
|
return useQuery<${responseType}>({
|
|
132
142
|
queryKey: ['${opId}', params],
|
|
133
143
|
queryFn: async () => {
|
|
134
|
-
|
|
144
|
+
${fetchStatement}
|
|
135
145
|
if (!res.ok) throw new Error('API Error');
|
|
136
146
|
return res.json();
|
|
137
147
|
},
|
|
@@ -139,26 +149,40 @@ export const use${capitalize(opId)} = (
|
|
|
139
149
|
});
|
|
140
150
|
};`);
|
|
141
151
|
} else {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
152
|
+
const pathParamsList = params.filter((p) => p.in === "path");
|
|
153
|
+
const hasPathParams = pathParamsList.length > 0;
|
|
154
|
+
let urlPath = pathUrl;
|
|
155
|
+
for (const p of pathParamsList) {
|
|
156
|
+
urlPath = urlPath.replace(`{${p.name}}`, `\${${p.name}}`);
|
|
157
|
+
}
|
|
158
|
+
let inputType;
|
|
159
|
+
let mutationArg;
|
|
160
|
+
if (hasBody && hasPathParams) {
|
|
161
|
+
inputType = `${capitalize(opId)}Params & ${capitalize(opId)}Body`;
|
|
162
|
+
const pathParamNames = pathParamsList.map((p) => p.name).join(", ");
|
|
163
|
+
mutationArg = `{ ${pathParamNames}, ...body }`;
|
|
164
|
+
} else if (hasBody) {
|
|
145
165
|
inputType = bodyType;
|
|
146
|
-
|
|
147
|
-
} else if (
|
|
166
|
+
mutationArg = "body";
|
|
167
|
+
} else if (hasPathParams) {
|
|
148
168
|
inputType = paramsType;
|
|
149
|
-
|
|
169
|
+
const pathParamNames = pathParamsList.map((p) => p.name).join(", ");
|
|
170
|
+
mutationArg = `{ ${pathParamNames} }`;
|
|
171
|
+
} else {
|
|
172
|
+
inputType = "void";
|
|
173
|
+
mutationArg = "";
|
|
150
174
|
}
|
|
151
|
-
const
|
|
175
|
+
const fetchBodyLine = hasBody ? `
|
|
176
|
+
body: JSON.stringify(body),` : "";
|
|
152
177
|
hooks.push(`
|
|
153
178
|
export const use${capitalize(opId)} = (
|
|
154
179
|
options?: UseMutationOptions<${responseType}, Error, ${inputType}>
|
|
155
180
|
) => {
|
|
156
181
|
return useMutation<${responseType}, Error, ${inputType}>({
|
|
157
|
-
mutationFn: async (${
|
|
158
|
-
const res = await fetch(\`\${baseUrl}${
|
|
182
|
+
mutationFn: async (${mutationArg}) => {
|
|
183
|
+
const res = await fetch(\`\${baseUrl}${urlPath}\`, {
|
|
159
184
|
method: '${method.toUpperCase()}',
|
|
160
|
-
headers: { 'Content-Type': 'application/json' }
|
|
161
|
-
body: JSON.stringify(${hasInput ? inputArg : "{}"}),
|
|
185
|
+
headers: { 'Content-Type': 'application/json' },${fetchBodyLine}
|
|
162
186
|
});
|
|
163
187
|
if (!res.ok) throw new Error('API Error');
|
|
164
188
|
return res.json();
|
|
@@ -175,6 +199,9 @@ export const use${capitalize(opId)} = (
|
|
|
175
199
|
function capitalize(str) {
|
|
176
200
|
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
177
201
|
}
|
|
202
|
+
function toSafeIdentifier(id) {
|
|
203
|
+
return id.replace(/[^a-zA-Z0-9_-]/g, "").replace(/[-_]+(.?)/g, (_, c) => c ? c.toUpperCase() : "");
|
|
204
|
+
}
|
|
178
205
|
async function parseArgs() {
|
|
179
206
|
const args = process.argv.slice(2);
|
|
180
207
|
const config = {
|
package/package.json
CHANGED
|
@@ -1,25 +1,30 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "elysia-openapi-codegen",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "Generate React Query hooks and fully typed TypeScript interfaces from Elysia OpenAPI specs.",
|
|
5
|
-
"module": "index.ts",
|
|
6
|
-
"type": "module",
|
|
7
|
-
"bin": {
|
|
8
|
-
"elysia-codegen": "./dist/index.js"
|
|
9
|
-
},
|
|
10
|
-
"files": [
|
|
11
|
-
"dist",
|
|
12
|
-
"README.md"
|
|
13
|
-
],
|
|
3
|
+
"version": "0.1.6",
|
|
14
4
|
"author": "Khantamir mkhantamir77@gmail.com",
|
|
15
|
-
"license": "MIT",
|
|
16
5
|
"repository": {
|
|
17
6
|
"type": "git",
|
|
18
7
|
"url": "https://github.com/mkhantamir/elysia-openapi-codegen.git"
|
|
19
8
|
},
|
|
9
|
+
"main": "dist/index.js",
|
|
10
|
+
"module": "index.ts",
|
|
11
|
+
"devDependencies": {
|
|
12
|
+
"@types/bun": "latest"
|
|
13
|
+
},
|
|
14
|
+
"peerDependencies": {
|
|
15
|
+
"typescript": "^6.0.2"
|
|
16
|
+
},
|
|
17
|
+
"bin": {
|
|
18
|
+
"elysia-codegen": "./dist/index.js"
|
|
19
|
+
},
|
|
20
20
|
"bugs": {
|
|
21
21
|
"url": "https://github.com/mkhantamir/elysia-openapi-codegen/issues"
|
|
22
22
|
},
|
|
23
|
+
"description": "Generate React Query hooks and fully typed TypeScript interfaces from Elysia OpenAPI specs.",
|
|
24
|
+
"files": [
|
|
25
|
+
"dist",
|
|
26
|
+
"README.md"
|
|
27
|
+
],
|
|
23
28
|
"homepage": "https://github.com/mkhantamir/elysia-openapi-codegen#readme",
|
|
24
29
|
"keywords": [
|
|
25
30
|
"elysia",
|
|
@@ -29,14 +34,9 @@
|
|
|
29
34
|
"react-query",
|
|
30
35
|
"tanstack-query"
|
|
31
36
|
],
|
|
32
|
-
"
|
|
33
|
-
"@types/bun": "latest"
|
|
34
|
-
},
|
|
35
|
-
"peerDependencies": {
|
|
36
|
-
"typescript": "^6.0.2"
|
|
37
|
-
},
|
|
37
|
+
"license": "MIT",
|
|
38
38
|
"scripts": {
|
|
39
39
|
"build": "bun build index.ts --outfile dist/index.js --target node"
|
|
40
40
|
},
|
|
41
|
-
"
|
|
41
|
+
"type": "module"
|
|
42
42
|
}
|