react-query-lightbase-codegen 1.6.4 → 2.0.1
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/config/loadConfig.d.ts +2 -0
- package/dist/config/loadConfig.js +24 -0
- package/dist/generator/clientGenerator.d.ts +13 -0
- package/dist/generator/clientGenerator.js +199 -0
- package/dist/generator/instanceGenerator.d.ts +1 -0
- package/dist/generator/instanceGenerator.js +21 -0
- package/dist/generator/reactQueryGenerator.d.ts +2 -0
- package/dist/generator/reactQueryGenerator.js +82 -0
- package/dist/generator/schemaGenerator.d.ts +5 -0
- package/dist/generator/schemaGenerator.js +114 -0
- package/dist/index.d.ts +5 -3
- package/dist/index.js +106 -4
- package/dist/types/config.d.ts +11 -0
- package/dist/types/config.js +2 -0
- package/dist/types.d.ts +5 -0
- package/dist/types.js +2 -0
- package/dist/utils.d.ts +31 -20
- package/dist/utils.js +56 -179
- package/package.json +54 -82
- package/readme.md +94 -0
- package/src/config/loadConfig.ts +25 -0
- package/src/generator/clientGenerator.ts +236 -0
- package/src/generator/instanceGenerator.ts +20 -0
- package/src/generator/reactQueryGenerator.ts +94 -0
- package/src/generator/schemaGenerator.ts +138 -0
- package/src/index.ts +78 -3
- package/src/types/config.ts +12 -0
- package/src/types.ts +5 -0
- package/src/utils.ts +55 -213
- package/README.md +0 -77
- package/dist/convertSwaggerFile.d.ts +0 -5
- package/dist/convertSwaggerFile.js +0 -26
- package/dist/convertSwaggerFile.js.map +0 -1
- package/dist/generateHooks.d.ts +0 -18
- package/dist/generateHooks.js +0 -448
- package/dist/generateHooks.js.map +0 -1
- package/dist/generateImports.d.ts +0 -6
- package/dist/generateImports.js +0 -21
- package/dist/generateImports.js.map +0 -1
- package/dist/generateSchemas.d.ts +0 -7
- package/dist/generateSchemas.js +0 -100
- package/dist/generateSchemas.js.map +0 -1
- package/dist/importSpecs.d.ts +0 -10
- package/dist/importSpecs.js +0 -127
- package/dist/importSpecs.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/utils.js.map +0 -1
- package/src/convertSwaggerFile.ts +0 -25
- package/src/generateHooks.ts +0 -540
- package/src/generateImports.ts +0 -32
- package/src/generateSchemas.ts +0 -117
- package/src/importSpecs.ts +0 -168
package/dist/utils.d.ts
CHANGED
|
@@ -1,24 +1,35 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export declare
|
|
3
|
-
|
|
4
|
-
}) => string;
|
|
1
|
+
import type { OpenAPIV3 } from "openapi-types";
|
|
2
|
+
export declare function camelCase(str: string): string;
|
|
3
|
+
export declare function pascalCase(str: string): string;
|
|
5
4
|
/**
|
|
6
|
-
*
|
|
5
|
+
* Sanitizes a property name to ensure it's a valid JavaScript identifier.
|
|
6
|
+
* If the name is already a valid identifier (starts with letter/underscore/$ and contains only letters/numbers/underscore/$),
|
|
7
|
+
* returns it as-is. Otherwise wraps it in quotes to make it a valid property accessor.
|
|
8
|
+
*
|
|
9
|
+
* For example:
|
|
10
|
+
* - sanitizePropertyName("validName") => "validName"
|
|
11
|
+
* - sanitizePropertyName("invalid-name") => "'invalid-name'"
|
|
12
|
+
* - sanitizePropertyName("123invalid") => "'123invalid'"
|
|
13
|
+
*
|
|
14
|
+
* @param name The property name to sanitize
|
|
15
|
+
* @returns The sanitized property name, quoted if needed
|
|
7
16
|
*/
|
|
8
|
-
export declare
|
|
17
|
+
export declare function sanitizePropertyName(name: string): string;
|
|
9
18
|
/**
|
|
10
|
-
*
|
|
19
|
+
* Sanitizes a type name to ensure it's a valid TypeScript type identifier.
|
|
20
|
+
* Replaces any characters that aren't alphanumeric or underscore with an underscore.
|
|
21
|
+
*
|
|
22
|
+
* For example:
|
|
23
|
+
* - sanitizeTypeName("ValidType") => "ValidType"
|
|
24
|
+
* - sanitizeTypeName("invalid-type") => "invalid_type"
|
|
25
|
+
* - sanitizeTypeName("type.name") => "type_name"
|
|
26
|
+
* - sanitizeTypeName("type/name") => "type_name"
|
|
27
|
+
*
|
|
28
|
+
* This is used to convert operation IDs and response names from the OpenAPI spec
|
|
29
|
+
* into valid TypeScript type names.
|
|
30
|
+
*
|
|
31
|
+
* @param name The type name to sanitize
|
|
32
|
+
* @returns The sanitized type name with invalid characters replaced by underscores
|
|
11
33
|
*/
|
|
12
|
-
export declare
|
|
13
|
-
|
|
14
|
-
* Resolve the value of a schema object to a proper type definition.
|
|
15
|
-
*/
|
|
16
|
-
export declare const resolveValue: (schema: SchemaObject) => string;
|
|
17
|
-
/**
|
|
18
|
-
* Format a description to code documentation.
|
|
19
|
-
*/
|
|
20
|
-
export declare const formatDescription: (description?: string) => string;
|
|
21
|
-
/**
|
|
22
|
-
* Extract responses / request types from open-api specs
|
|
23
|
-
*/
|
|
24
|
-
export declare const getResReqTypes: (responsesOrRequests: Array<[string, ResponseObject | ReferenceObject | RequestBodyObject]>) => string;
|
|
34
|
+
export declare function sanitizeTypeName(name: string): string;
|
|
35
|
+
export declare function specTitle(spec: OpenAPIV3.Document): string;
|
package/dist/utils.js
CHANGED
|
@@ -1,179 +1,56 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
*
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
else {
|
|
58
|
-
throw new Error('This library only resolve $ref that are include into `#/components/*` for now');
|
|
59
|
-
}
|
|
60
|
-
};
|
|
61
|
-
/**
|
|
62
|
-
* Return the output type from an array
|
|
63
|
-
*/
|
|
64
|
-
const getArray = (item) => {
|
|
65
|
-
if (item.items) {
|
|
66
|
-
if (!isReference(item.items) && (item.items.oneOf || item.items.allOf || item.items.enum)) {
|
|
67
|
-
return `(${resolveValue(item.items)})[]`;
|
|
68
|
-
}
|
|
69
|
-
else {
|
|
70
|
-
return `${resolveValue(item.items)}[]`;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
console.log(chalk.red(`Skipped(${item.title}): All arrays must have an 'items' key define`));
|
|
74
|
-
return 'unknown[]';
|
|
75
|
-
};
|
|
76
|
-
/**
|
|
77
|
-
* Return the output type from an object
|
|
78
|
-
*/
|
|
79
|
-
const getObject = (item) => {
|
|
80
|
-
if (isReference(item)) {
|
|
81
|
-
return getRef(item.$ref);
|
|
82
|
-
}
|
|
83
|
-
if (item.allOf) {
|
|
84
|
-
return item.allOf.map(resolveValue).join(' & ');
|
|
85
|
-
}
|
|
86
|
-
if (item.oneOf) {
|
|
87
|
-
return item.oneOf.map(resolveValue).join(' | ');
|
|
88
|
-
}
|
|
89
|
-
if (item.anyOf) {
|
|
90
|
-
return item.anyOf.map(resolveValue).join(' | ');
|
|
91
|
-
}
|
|
92
|
-
if (!item.type && !item.properties && !item.additionalProperties) {
|
|
93
|
-
return '{}';
|
|
94
|
-
}
|
|
95
|
-
// Free form object (https://swagger.io/docs/specification/data-models/data-types/#free-form)
|
|
96
|
-
if (item.type === 'object' &&
|
|
97
|
-
!item.properties &&
|
|
98
|
-
(!item.additionalProperties || item.additionalProperties === true || isEmpty(item.additionalProperties))) {
|
|
99
|
-
return '{[key: string]: any}';
|
|
100
|
-
}
|
|
101
|
-
const IdentifierRegexp = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;
|
|
102
|
-
// Consolidation of item.properties & item.additionalProperties
|
|
103
|
-
let output = '{';
|
|
104
|
-
if (item.properties) {
|
|
105
|
-
output += Object.entries(item.properties)
|
|
106
|
-
.map(([key, prop]) => {
|
|
107
|
-
const doc = getDocs(prop);
|
|
108
|
-
const isRequired = (item.required || []).includes(key);
|
|
109
|
-
const processedKey = IdentifierRegexp.test(key) ? key : `"${key}"`;
|
|
110
|
-
return `${doc}\n${processedKey}${isRequired ? '' : '?'}: ${resolveValue(prop)}`;
|
|
111
|
-
})
|
|
112
|
-
.join('');
|
|
113
|
-
}
|
|
114
|
-
if (item.additionalProperties) {
|
|
115
|
-
if (item.properties) {
|
|
116
|
-
output += '\n';
|
|
117
|
-
}
|
|
118
|
-
output += `} & { [key: string]: ${item.additionalProperties === true ? 'any' : resolveValue(item.additionalProperties)}`;
|
|
119
|
-
}
|
|
120
|
-
if (item.properties || item.additionalProperties) {
|
|
121
|
-
if (output === '{\n') {
|
|
122
|
-
return '{}';
|
|
123
|
-
}
|
|
124
|
-
return output + '\n}';
|
|
125
|
-
}
|
|
126
|
-
return item.type === 'object' ? '{[key: string]: any}' : 'any';
|
|
127
|
-
};
|
|
128
|
-
/**
|
|
129
|
-
* Resolve the value of a schema object to a proper type definition.
|
|
130
|
-
*/
|
|
131
|
-
export const resolveValue = (schema) => {
|
|
132
|
-
if (isReference(schema)) {
|
|
133
|
-
const ref = getRef(schema.$ref);
|
|
134
|
-
imports?.push(ref);
|
|
135
|
-
return ref;
|
|
136
|
-
}
|
|
137
|
-
return getScalar(schema);
|
|
138
|
-
};
|
|
139
|
-
/**
|
|
140
|
-
* Format a description to code documentation.
|
|
141
|
-
*/
|
|
142
|
-
export const formatDescription = (description) => {
|
|
143
|
-
if (!description) {
|
|
144
|
-
return '';
|
|
145
|
-
}
|
|
146
|
-
return `\n/**\n${description
|
|
147
|
-
.split('\n')
|
|
148
|
-
.map((i) => `* ${i}`)
|
|
149
|
-
.join('\n')}\n */`;
|
|
150
|
-
};
|
|
151
|
-
/**
|
|
152
|
-
* Extract responses / request types from open-api specs
|
|
153
|
-
*/
|
|
154
|
-
export const getResReqTypes = (responsesOrRequests) => {
|
|
155
|
-
return uniq(responsesOrRequests.map(([_, res]) => {
|
|
156
|
-
if (!res) {
|
|
157
|
-
return;
|
|
158
|
-
}
|
|
159
|
-
if (isReference(res)) {
|
|
160
|
-
const ref = getRef(res.$ref);
|
|
161
|
-
imports.push(ref);
|
|
162
|
-
return ref;
|
|
163
|
-
}
|
|
164
|
-
if (res.content) {
|
|
165
|
-
for (const contentType of Object.keys(res.content)) {
|
|
166
|
-
if (contentType.startsWith('application/json') ||
|
|
167
|
-
contentType.startsWith('application/ld+json') ||
|
|
168
|
-
contentType.startsWith('application/octet-stream') ||
|
|
169
|
-
contentType.startsWith('multipart/form-data')) {
|
|
170
|
-
const schema = res.content[contentType].schema;
|
|
171
|
-
return resolveValue(schema);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
return;
|
|
175
|
-
}
|
|
176
|
-
return;
|
|
177
|
-
})).join(' | ');
|
|
178
|
-
};
|
|
179
|
-
//# sourceMappingURL=utils.js.map
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.camelCase = camelCase;
|
|
4
|
+
exports.pascalCase = pascalCase;
|
|
5
|
+
exports.sanitizePropertyName = sanitizePropertyName;
|
|
6
|
+
exports.sanitizeTypeName = sanitizeTypeName;
|
|
7
|
+
exports.specTitle = specTitle;
|
|
8
|
+
function camelCase(str) {
|
|
9
|
+
return str
|
|
10
|
+
.toLowerCase()
|
|
11
|
+
.replace(/[^a-zA-Z0-9]+(.)/g, (_, chr) => chr.toUpperCase())
|
|
12
|
+
.replace(/^[A-Z]/, (c) => c.toLowerCase());
|
|
13
|
+
}
|
|
14
|
+
function pascalCase(str) {
|
|
15
|
+
return str
|
|
16
|
+
.replace(/[^a-zA-Z0-9]+(.)/g, (_, chr) => chr.toUpperCase())
|
|
17
|
+
.replace(/^[a-z]/, (c) => c.toUpperCase());
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Sanitizes a property name to ensure it's a valid JavaScript identifier.
|
|
21
|
+
* If the name is already a valid identifier (starts with letter/underscore/$ and contains only letters/numbers/underscore/$),
|
|
22
|
+
* returns it as-is. Otherwise wraps it in quotes to make it a valid property accessor.
|
|
23
|
+
*
|
|
24
|
+
* For example:
|
|
25
|
+
* - sanitizePropertyName("validName") => "validName"
|
|
26
|
+
* - sanitizePropertyName("invalid-name") => "'invalid-name'"
|
|
27
|
+
* - sanitizePropertyName("123invalid") => "'123invalid'"
|
|
28
|
+
*
|
|
29
|
+
* @param name The property name to sanitize
|
|
30
|
+
* @returns The sanitized property name, quoted if needed
|
|
31
|
+
*/
|
|
32
|
+
function sanitizePropertyName(name) {
|
|
33
|
+
return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name) ? name : `'${name}'`;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Sanitizes a type name to ensure it's a valid TypeScript type identifier.
|
|
37
|
+
* Replaces any characters that aren't alphanumeric or underscore with an underscore.
|
|
38
|
+
*
|
|
39
|
+
* For example:
|
|
40
|
+
* - sanitizeTypeName("ValidType") => "ValidType"
|
|
41
|
+
* - sanitizeTypeName("invalid-type") => "invalid_type"
|
|
42
|
+
* - sanitizeTypeName("type.name") => "type_name"
|
|
43
|
+
* - sanitizeTypeName("type/name") => "type_name"
|
|
44
|
+
*
|
|
45
|
+
* This is used to convert operation IDs and response names from the OpenAPI spec
|
|
46
|
+
* into valid TypeScript type names.
|
|
47
|
+
*
|
|
48
|
+
* @param name The type name to sanitize
|
|
49
|
+
* @returns The sanitized type name with invalid characters replaced by underscores
|
|
50
|
+
*/
|
|
51
|
+
function sanitizeTypeName(name) {
|
|
52
|
+
return name.replace(/[^a-zA-Z0-9_]/g, "_").replace(/_+$/, "");
|
|
53
|
+
}
|
|
54
|
+
function specTitle(spec) {
|
|
55
|
+
return camelCase(spec.info.title.toLowerCase().replace(/\s+/g, "-"));
|
|
56
|
+
}
|
package/package.json
CHANGED
|
@@ -1,84 +1,56 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
"@babel/eslint-parser": "7.24.1",
|
|
57
|
-
"@commitlint/cli": "^19.2.1",
|
|
58
|
-
"@commitlint/config-conventional": "^19.1.0",
|
|
59
|
-
"@react-native-community/eslint-config": "3.2.0",
|
|
60
|
-
"@semantic-release/changelog": "^6.0.3",
|
|
61
|
-
"@semantic-release/git": "^10.0.1",
|
|
62
|
-
"@semantic-release/github": "^10.0.2",
|
|
63
|
-
"@semantic-release/npm": "^12.0.0",
|
|
64
|
-
"@tanstack/react-query": "5.51.23",
|
|
65
|
-
"@types/js-yaml": "4.0.9",
|
|
66
|
-
"@types/lodash": "4.17.0",
|
|
67
|
-
"@types/node": "20.11.30",
|
|
68
|
-
"@types/qs": "6.9.14",
|
|
69
|
-
"@types/query-string": "6.3.0",
|
|
70
|
-
"@types/yamljs": "0.2.34",
|
|
71
|
-
"axios": "1.7.3",
|
|
72
|
-
"eslint": "8.57.0",
|
|
73
|
-
"eslint-plugin-prettier": "5.1.3",
|
|
74
|
-
"husky": "^9.0.11",
|
|
75
|
-
"prettier": "3.3.3",
|
|
76
|
-
"react": "18.2.0",
|
|
77
|
-
"semantic-release": "^23.0.6",
|
|
78
|
-
"typescript": "5.4.3"
|
|
79
|
-
},
|
|
80
|
-
"peerDependencies": {
|
|
81
|
-
"@tanstack/react-query": ">= 5.20.0",
|
|
82
|
-
"axios": "*"
|
|
83
|
-
}
|
|
2
|
+
"name": "react-query-lightbase-codegen",
|
|
3
|
+
"version": "2.0.1",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"description": "Generate Axios API clients and React Query options from OpenAPI specifications",
|
|
6
|
+
"exports": "./dist/index.js",
|
|
7
|
+
"files": [
|
|
8
|
+
"src",
|
|
9
|
+
"dist"
|
|
10
|
+
],
|
|
11
|
+
"author": {
|
|
12
|
+
"name": "Oliver Winter",
|
|
13
|
+
"email": "owinter86@gmail.com"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"rest",
|
|
17
|
+
"client",
|
|
18
|
+
"swagger",
|
|
19
|
+
"open-api",
|
|
20
|
+
"fetch",
|
|
21
|
+
"data fetching",
|
|
22
|
+
"code-generation",
|
|
23
|
+
"react",
|
|
24
|
+
"react-query",
|
|
25
|
+
"axios",
|
|
26
|
+
"tanstack"
|
|
27
|
+
],
|
|
28
|
+
"repository": {
|
|
29
|
+
"type": "git",
|
|
30
|
+
"url": "https://github.com/lightbasenl/react-query-codegen"
|
|
31
|
+
},
|
|
32
|
+
"scripts": {
|
|
33
|
+
"build": "tsc -p tsconfig.json",
|
|
34
|
+
"example": "ts-node example/index.ts && biome check --fix --unsafe",
|
|
35
|
+
"check": "biome check --write .",
|
|
36
|
+
"updates": "npx npm-check-updates -i",
|
|
37
|
+
"release": "release-it"
|
|
38
|
+
},
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"axios": "^1.7.9",
|
|
41
|
+
"openapi-types": "^12.1.3",
|
|
42
|
+
"yaml": "^2.7.0"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@biomejs/biome": "1.9.4",
|
|
46
|
+
"@tanstack/react-query": "^5.66.9",
|
|
47
|
+
"@types/node": "^22.13.5",
|
|
48
|
+
"release-it": "^17.0.0",
|
|
49
|
+
"ts-node": "^10.9.2",
|
|
50
|
+
"typescript": "^5.7.3"
|
|
51
|
+
},
|
|
52
|
+
"peerDependencies": {
|
|
53
|
+
"@tanstack/react-query": ">= 5.50.0",
|
|
54
|
+
"axios": "^1.7.0"
|
|
55
|
+
}
|
|
84
56
|
}
|
package/readme.md
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# react-query-lightbase-codegen
|
|
2
|
+
|
|
3
|
+
Generate type-safe Axios API clients and React Query hooks from OpenAPI specifications.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🔄 Automatic code generation from OpenAPI/Swagger specs
|
|
8
|
+
- 📝 Type-safe API client functions
|
|
9
|
+
- 🎣 React Query integration with query options
|
|
10
|
+
- 📦 Support for multiple API specifications
|
|
11
|
+
- 📤 Handle multipart/form-data uploads
|
|
12
|
+
- 💪 Full TypeScript support
|
|
13
|
+
- 🔒 Type-safe request/response handling
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install react-query-lightbase-codegen
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Quick Start
|
|
22
|
+
|
|
23
|
+
### 1. Configure Generation
|
|
24
|
+
|
|
25
|
+
Create a script to generate your API code (e.g., `scripts/generate.ts`):
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
import { codegenerate } from 'react-query-lightbase-codegen';
|
|
29
|
+
await codegenerate({
|
|
30
|
+
specSource: './specs/api.yaml', // or array of specs
|
|
31
|
+
exportDir: './src/generated'
|
|
32
|
+
});
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### 2. Configure API Instance
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
import axios from "axios";
|
|
39
|
+
import { setApiClient } from "./src/generated/apiClient";
|
|
40
|
+
|
|
41
|
+
const api = axios.create({ baseURL: "https://api.example.com" });
|
|
42
|
+
// Set the API client instance to be used by the generated client functions
|
|
43
|
+
setApiClient(api);
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### 3. Use Generated Query Options
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
import { useQuery } from '@tanstack/react-query';
|
|
51
|
+
import { characteristicListQueryOptions } from './src/generated/pokiApi.queryOptions';
|
|
52
|
+
|
|
53
|
+
const { data, isLoading, error } = useQuery(characteristicListQueryOptions());
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
and more complex queries:
|
|
57
|
+
```typescript
|
|
58
|
+
import { useQuery } from '@tanstack/react-query';
|
|
59
|
+
import { characteristicListQueryOptions } from './src/generated/pokiApi.queryOptions';
|
|
60
|
+
|
|
61
|
+
const { data, isLoading, error } = useQuery({
|
|
62
|
+
...characteristicListQueryOptions(),
|
|
63
|
+
select: (data) => data.results.find(item => item.id === itemId),
|
|
64
|
+
});
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
easier query invalidation:
|
|
68
|
+
```typescript
|
|
69
|
+
queryClient.invalidateQueries(characteristicListQueryOptions());
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
## Generated Files
|
|
74
|
+
|
|
75
|
+
A single `apiClient.ts` file is generated to be used as a global Axios instance for all generated clients.
|
|
76
|
+
|
|
77
|
+
For each API specification, the following files are generated:
|
|
78
|
+
|
|
79
|
+
- `{api}.schema.ts` - TypeScript types for requests/responses
|
|
80
|
+
- `{api}.client.ts` - Type-safe API client functions
|
|
81
|
+
- `{api}.queryOptions.ts` - React Query integration
|
|
82
|
+
|
|
83
|
+
### Multiple API Specifications
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
await codegenerate({
|
|
87
|
+
specSource: [
|
|
88
|
+
'./specs/auth-api.yaml',
|
|
89
|
+
'./specs/user-api.json',
|
|
90
|
+
'https://api.example.com/openapi.yaml'
|
|
91
|
+
],
|
|
92
|
+
exportDir: './src/generated'
|
|
93
|
+
});
|
|
94
|
+
```
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import type { OpenAPIConfig } from "../types/config";
|
|
3
|
+
|
|
4
|
+
export async function loadConfig(configPath: string): Promise<OpenAPIConfig> {
|
|
5
|
+
try {
|
|
6
|
+
const configContent = await readFile(configPath, "utf-8");
|
|
7
|
+
const config = JSON.parse(configContent) as OpenAPIConfig;
|
|
8
|
+
|
|
9
|
+
// Validate required fields
|
|
10
|
+
if (!config.specSource) {
|
|
11
|
+
throw new Error("specSource is required in configuration");
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
if (!config.exportDir) {
|
|
15
|
+
throw new Error("exportDir is required in configuration");
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return config;
|
|
19
|
+
} catch (error) {
|
|
20
|
+
if (error instanceof Error) {
|
|
21
|
+
throw new Error(`Failed to load configuration: ${error.message}`);
|
|
22
|
+
}
|
|
23
|
+
throw new Error("Failed to load configuration: Unknown error");
|
|
24
|
+
}
|
|
25
|
+
}
|