@7nohe/openapi-react-query-codegen 1.2.1 → 1.3.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/README.md CHANGED
@@ -160,6 +160,80 @@ function App() {
160
160
  export default App;
161
161
  ```
162
162
 
163
+ ##### Using Mutation hooks
164
+
165
+ ```tsx
166
+ // App.tsx
167
+ import { usePetServiceAddPet } from "../openapi/queries";
168
+
169
+ function App() {
170
+ const { mutate } = usePetServiceAddPet();
171
+
172
+ const handleAddPet = () => {
173
+ mutate({ name: "Fluffy", status: "available" });
174
+ };
175
+
176
+ return (
177
+ <div className="App">
178
+ <h1>Add Pet</h1>
179
+ <button onClick={handleAddPet}>Add Pet</button>
180
+ </div>
181
+ );
182
+ }
183
+
184
+ export default App;
185
+ ```
186
+
187
+ ##### Invalidating queries after mutation
188
+
189
+ Invalidating queries after a mutation is important to ensure the cache is updated with the new data. This is done by calling the `queryClient.invalidateQueries` function with the query key used by the query hook.
190
+
191
+ Learn more about invalidating queries [here](https://tanstack.com/query/latest/docs/framework/react/guides/query-invalidation).
192
+
193
+ To ensure the query key is created the same way as the query hook, you can use the query key function exported by the generated query hooks.
194
+
195
+ ```tsx
196
+ import {
197
+ usePetServiceFindPetsByStatus,
198
+ usePetServiceAddPet,
199
+ UsePetServiceFindPetsByStatusKeyFn,
200
+ } from "../openapi/queries";
201
+
202
+ // App.tsx
203
+ function App() {
204
+ const [status, setStatus] = React.useState(["available"]);
205
+ const { data } = usePetServiceFindPetsByStatus({ status });
206
+ const { mutate } = usePetServiceAddPet({
207
+ onSuccess: () => {
208
+ queryClient.invalidateQueries({
209
+ // Call the query key function to get the query key
210
+ // This is important to ensure the query key is created the same way as the query hook
211
+ // This insures the cache is invalidated correctly and is typed correctly
212
+ queryKey: [UsePetServiceFindPetsByStatusKeyFn({
213
+ status
214
+ })],
215
+ });
216
+ },
217
+ });
218
+
219
+ return (
220
+ <div className="App">
221
+ <h1>Pet List</h1>
222
+ <ul>{data?.map((pet) => <li key={pet.id}>{pet.name}</li>)}</ul>
223
+ <button
224
+ onClick={() => {
225
+ mutate({ name: "Fluffy", status: "available" });
226
+ }}
227
+ >
228
+ Add Pet
229
+ </button>
230
+ </div>
231
+ );
232
+ }
233
+
234
+ export default App;
235
+ ```
236
+
163
237
  ##### Runtime Configuration
164
238
 
165
239
  You can modify the default values used by the generated service calls by modifying the OpenAPI configuration singleton object.
@@ -188,6 +262,39 @@ ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
188
262
 
189
263
  ```
190
264
 
265
+ ## Development
266
+
267
+ ### Install dependencies
268
+
269
+ ```bash
270
+ pnpm install
271
+ ```
272
+
273
+ ### Run tests
274
+ ```bash
275
+ pnpm test
276
+ ```
277
+
278
+ ### Run linter
279
+ ```bash
280
+ pnpm lint
281
+ ```
282
+
283
+ ### Run linter and fix
284
+ ```bash
285
+ pnpm lint:fix
286
+ ```
287
+
288
+ ### Update snapshots
289
+ ```bash
290
+ pnpm snapshot
291
+ ```
292
+
293
+ ### Build example and validate generated code
294
+ ```bash
295
+ npm run build && pnpm --filter @7nohe/react-app generate:api && pnpm --filter @7nohe/react-app test:generated
296
+ ```
297
+
191
298
  ## License
192
299
 
193
300
  MIT
package/dist/cli.mjs CHANGED
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
- import { generate } from "./generate.mjs";
3
- import { Command, Option } from "commander";
4
- import { readFile } from "fs/promises";
5
- import { dirname, join } from "path";
2
+ import { readFile } from "node:fs/promises";
3
+ import { dirname, join } from "node:path";
6
4
  import { fileURLToPath } from "node:url";
5
+ import { Command, Option } from "commander";
7
6
  import { defaultOutputPath } from "./constants.mjs";
7
+ import { generate } from "./generate.mjs";
8
8
  const program = new Command();
9
9
  async function setupProgram() {
10
10
  const __filename = fileURLToPath(import.meta.url);
package/dist/common.mjs CHANGED
@@ -1,10 +1,12 @@
1
- import { stat } from "fs/promises";
1
+ import { stat } from "node:fs/promises";
2
+ import path from "node:path";
2
3
  import ts from "typescript";
3
- import path from "path";
4
4
  import { queriesOutputPath, requestsOutputPath } from "./constants.mjs";
5
5
  export const TData = ts.factory.createIdentifier("TData");
6
6
  export const TError = ts.factory.createIdentifier("TError");
7
7
  export const TContext = ts.factory.createIdentifier("TContext");
8
+ export const EqualsOrGreaterThanToken = ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken);
9
+ export const QuestionToken = ts.factory.createToken(ts.SyntaxKind.QuestionToken);
8
10
  export const queryKeyGenericType = ts.factory.createTypeReferenceNode("TQueryKey");
9
11
  export const queryKeyConstraint = ts.factory.createTypeReferenceNode("Array", [
10
12
  ts.factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword),
@@ -49,10 +51,10 @@ export function BuildCommonTypeName(name) {
49
51
  */
50
52
  export function safeParseNumber(value) {
51
53
  const parsed = Number(value);
52
- if (!isNaN(parsed) && isFinite(parsed)) {
54
+ if (!Number.isNaN(parsed) && Number.isFinite(parsed)) {
53
55
  return parsed;
54
56
  }
55
- return NaN;
57
+ return Number.NaN;
56
58
  }
57
59
  export function extractPropertiesFromObjectParam(param) {
58
60
  const referenced = param.findReferences()[0];
@@ -117,7 +119,7 @@ export function formatOptions(options) {
117
119
  else if (value === "false" || value === false) {
118
120
  acc[typedKey] = false;
119
121
  }
120
- else if (!isNaN(parsedNumber)) {
122
+ else if (!Number.isNaN(parsedNumber)) {
121
123
  acc[typedKey] = parsedNumber;
122
124
  }
123
125
  else {
@@ -1,9 +1,9 @@
1
- import { createUseQuery } from "./createUseQuery.mjs";
2
- import { createUseMutation } from "./createUseMutation.mjs";
3
1
  import { createPrefetch } from "./createPrefetch.mjs";
2
+ import { createUseMutation } from "./createUseMutation.mjs";
3
+ import { createUseQuery } from "./createUseQuery.mjs";
4
4
  export const createExports = (service) => {
5
5
  const { klasses } = service;
6
- const methods = klasses.map((k) => k.methods).flat();
6
+ const methods = klasses.flatMap((k) => k.methods);
7
7
  const allGet = methods.filter((m) => m.httpMethodName.toUpperCase().includes("GET"));
8
8
  const allPost = methods.filter((m) => m.httpMethodName.toUpperCase().includes("POST"));
9
9
  const allPut = methods.filter((m) => m.httpMethodName.toUpperCase().includes("PUT"));
@@ -22,25 +22,28 @@ export const createExports = (service) => {
22
22
  ...allPatchMutations,
23
23
  ...allDeleteMutations,
24
24
  ];
25
- const commonInQueries = allQueries
26
- .map(({ apiResponse, returnType, key }) => [apiResponse, returnType, key])
27
- .flat();
28
- const commonInMutations = allMutations
29
- .map(({ mutationResult }) => [mutationResult])
30
- .flat();
25
+ const commonInQueries = allQueries.flatMap(({ apiResponse, returnType, key, queryKeyFn }) => [
26
+ apiResponse,
27
+ returnType,
28
+ key,
29
+ queryKeyFn,
30
+ ]);
31
+ const commonInMutations = allMutations.flatMap(({ mutationResult }) => [
32
+ mutationResult,
33
+ ]);
31
34
  const allCommon = [...commonInQueries, ...commonInMutations];
32
- const mainQueries = allQueries.map(({ queryHook }) => [queryHook]).flat();
33
- const mainMutations = allMutations
34
- .map(({ mutationHook }) => [mutationHook])
35
- .flat();
35
+ const mainQueries = allQueries.flatMap(({ queryHook }) => [queryHook]);
36
+ const mainMutations = allMutations.flatMap(({ mutationHook }) => [
37
+ mutationHook,
38
+ ]);
36
39
  const mainExports = [...mainQueries, ...mainMutations];
37
- const suspenseQueries = allQueries
38
- .map(({ suspenseQueryHook }) => [suspenseQueryHook])
39
- .flat();
40
+ const suspenseQueries = allQueries.flatMap(({ suspenseQueryHook }) => [
41
+ suspenseQueryHook,
42
+ ]);
40
43
  const suspenseExports = [...suspenseQueries];
41
- const allPrefetches = allPrefetchQueries
42
- .map(({ prefetchHook }) => [prefetchHook])
43
- .flat();
44
+ const allPrefetches = allPrefetchQueries.flatMap(({ prefetchHook }) => [
45
+ prefetchHook,
46
+ ]);
44
47
  const allPrefetchExports = [...allPrefetches];
45
48
  return {
46
49
  /**
@@ -1,5 +1,5 @@
1
+ import { posix } from "node:path";
1
2
  import ts from "typescript";
2
- import { posix } from "path";
3
3
  import { modalsFileName, serviceFileName } from "./constants.mjs";
4
4
  const { join } = posix;
5
5
  export const createImports = ({ serviceEndName, project, }) => {
@@ -19,6 +19,7 @@ export const createImports = ({ serviceEndName, project, }) => {
19
19
  const serviceNames = serviceExports.filter((name) => name.endsWith(serviceEndName));
20
20
  const imports = [
21
21
  ts.factory.createImportDeclaration(undefined, ts.factory.createImportClause(false, undefined, ts.factory.createNamedImports([
22
+ ts.factory.createImportSpecifier(true, undefined, ts.factory.createIdentifier("QueryClient")),
22
23
  ts.factory.createImportSpecifier(false, undefined, ts.factory.createIdentifier("useQuery")),
23
24
  ts.factory.createImportSpecifier(false, undefined, ts.factory.createIdentifier("useSuspenseQuery")),
24
25
  ts.factory.createImportSpecifier(false, undefined, ts.factory.createIdentifier("useMutation")),
@@ -25,8 +25,7 @@ function createPrefetchHook({ requestParams, method, className, }) {
25
25
  ? ts.factory.createArrayLiteralExpression([
26
26
  ts.factory.createObjectLiteralExpression(method
27
27
  .getParameters()
28
- .map((param) => extractPropertiesFromObjectParam(param).map((p) => ts.factory.createShorthandPropertyAssignment(ts.factory.createIdentifier(p.name))))
29
- .flat()),
28
+ .flatMap((param) => extractPropertiesFromObjectParam(param).map((p) => ts.factory.createShorthandPropertyAssignment(ts.factory.createIdentifier(p.name))))),
30
29
  ])
31
30
  : ts.factory.createArrayLiteralExpression([]),
32
31
  ], false)),
@@ -34,8 +33,7 @@ function createPrefetchHook({ requestParams, method, className, }) {
34
33
  ? [
35
34
  ts.factory.createObjectLiteralExpression(method
36
35
  .getParameters()
37
- .map((param) => extractPropertiesFromObjectParam(param).map((p) => ts.factory.createShorthandPropertyAssignment(ts.factory.createIdentifier(p.name))))
38
- .flat()),
36
+ .flatMap((param) => extractPropertiesFromObjectParam(param).map((p) => ts.factory.createShorthandPropertyAssignment(ts.factory.createIdentifier(p.name))))),
39
37
  ]
40
38
  : undefined))),
41
39
  ]),
@@ -1,9 +1,9 @@
1
- import ts from "typescript";
1
+ import { join } from "node:path";
2
2
  import { Project } from "ts-morph";
3
- import { join } from "path";
3
+ import ts from "typescript";
4
4
  import { OpenApiRqFiles } from "./constants.mjs";
5
- import { createImports } from "./createImports.mjs";
6
5
  import { createExports } from "./createExports.mjs";
6
+ import { createImports } from "./createImports.mjs";
7
7
  import { getServices } from "./service.mjs";
8
8
  const createSourceFile = async (outputPath, serviceEndName) => {
9
9
  const project = new Project({
@@ -20,15 +20,12 @@ export const createUseMutation = ({ className, method, jsDoc, }) => {
20
20
  const mutationResult = ts.factory.createTypeAliasDeclaration([ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], ts.factory.createIdentifier(`${className}${capitalizeFirstLetter(methodName)}MutationResult`), undefined, awaitedResponseDataType);
21
21
  const responseDataType = ts.factory.createTypeParameterDeclaration(undefined, TData, undefined, ts.factory.createTypeReferenceNode(BuildCommonTypeName(mutationResult.name)));
22
22
  const methodParameters = method.getParameters().length !== 0
23
- ? ts.factory.createTypeLiteralNode(method
24
- .getParameters()
25
- .map((param) => {
23
+ ? ts.factory.createTypeLiteralNode(method.getParameters().flatMap((param) => {
26
24
  const paramNodes = extractPropertiesFromObjectParam(param);
27
25
  return paramNodes.map((refParam) => ts.factory.createPropertySignature(undefined, ts.factory.createIdentifier(refParam.name), refParam.optional
28
26
  ? ts.factory.createToken(ts.SyntaxKind.QuestionToken)
29
27
  : undefined, ts.factory.createTypeReferenceNode(getShortType(refParam.type.getText(param)))));
30
- })
31
- .flat())
28
+ }))
32
29
  : ts.factory.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword);
33
30
  const exportHook = ts.factory.createVariableStatement([ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], ts.factory.createVariableDeclarationList([
34
31
  ts.factory.createVariableDeclaration(ts.factory.createIdentifier(`use${className}${capitalizeFirstLetter(methodName)}`), undefined, undefined, ts.factory.createArrowFunction(undefined, ts.factory.createNodeArray([
@@ -54,23 +51,17 @@ export const createUseMutation = ({ className, method, jsDoc, }) => {
54
51
  ts.factory.createObjectLiteralExpression([
55
52
  ts.factory.createPropertyAssignment(ts.factory.createIdentifier("mutationFn"), ts.factory.createArrowFunction(undefined, undefined, method.getParameters().length !== 0
56
53
  ? [
57
- ts.factory.createParameterDeclaration(undefined, undefined, ts.factory.createObjectBindingPattern(method
58
- .getParameters()
59
- .map((param) => {
54
+ ts.factory.createParameterDeclaration(undefined, undefined, ts.factory.createObjectBindingPattern(method.getParameters().flatMap((param) => {
60
55
  const paramNodes = extractPropertiesFromObjectParam(param);
61
56
  return paramNodes.map((refParam) => ts.factory.createBindingElement(undefined, undefined, ts.factory.createIdentifier(refParam.name), undefined));
62
- })
63
- .flat()), undefined, undefined, undefined),
57
+ })), undefined, undefined, undefined),
64
58
  ]
65
59
  : [], undefined, ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.factory.createAsExpression(ts.factory.createAsExpression(ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier(className), ts.factory.createIdentifier(methodName)), undefined, method.getParameters().length !== 0
66
60
  ? [
67
- ts.factory.createObjectLiteralExpression(method
68
- .getParameters()
69
- .map((params) => {
61
+ ts.factory.createObjectLiteralExpression(method.getParameters().flatMap((params) => {
70
62
  const paramNodes = extractPropertiesFromObjectParam(params);
71
63
  return paramNodes.map((refParam) => ts.factory.createShorthandPropertyAssignment(refParam.name));
72
- })
73
- .flat()),
64
+ })),
74
65
  ]
75
66
  : []), ts.factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword)), ts.factory.createTypeReferenceNode(ts.factory.createIdentifier("Promise"), [ts.factory.createTypeReferenceNode(TData)])))),
76
67
  ts.factory.createSpreadAssignment(ts.factory.createIdentifier("options")),
@@ -1,5 +1,5 @@
1
1
  import ts from "typescript";
2
- import { BuildCommonTypeName, capitalizeFirstLetter, extractPropertiesFromObjectParam, getNameFromMethod, getShortType, queryKeyConstraint, queryKeyGenericType, TData, TError, } from "./common.mjs";
2
+ import { BuildCommonTypeName, EqualsOrGreaterThanToken, QuestionToken, TData, TError, capitalizeFirstLetter, extractPropertiesFromObjectParam, getNameFromMethod, getShortType, queryKeyConstraint, queryKeyGenericType, } from "./common.mjs";
3
3
  import { addJSDocToNode } from "./util.mjs";
4
4
  export const createApiResponseType = ({ className, methodName, }) => {
5
5
  /** Awaited<ReturnType<typeof myClass.myMethod>> */
@@ -14,12 +14,15 @@ export const createApiResponseType = ({ className, methodName, }) => {
14
14
  const apiResponse = ts.factory.createTypeAliasDeclaration([ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], ts.factory.createIdentifier(`${capitalizeFirstLetter(className)}${capitalizeFirstLetter(methodName)}DefaultResponse`), undefined, awaitedResponseDataType);
15
15
  const responseDataType = ts.factory.createTypeParameterDeclaration(undefined, TData.text, undefined, ts.factory.createTypeReferenceNode(BuildCommonTypeName(apiResponse.name)));
16
16
  return {
17
- /** DefaultResponseDataType
17
+ /**
18
+ * DefaultResponseDataType
19
+ *
18
20
  * export type MyClassMethodDefaultResponse = Awaited<ReturnType<typeof myClass.myMethod>>
19
21
  */
20
22
  apiResponse,
21
23
  /**
22
- * will be the name of the type of the response type of the method
24
+ * This will be the name of the type of the response type of the method
25
+ *
23
26
  * MyClassMethodDefaultResponse
24
27
  */
25
28
  responseDataType,
@@ -29,17 +32,14 @@ export function getRequestParamFromMethod(method) {
29
32
  if (!method.getParameters().length) {
30
33
  return null;
31
34
  }
32
- const params = method
33
- .getParameters()
34
- .map((param) => {
35
+ const params = method.getParameters().flatMap((param) => {
35
36
  const paramNodes = extractPropertiesFromObjectParam(param);
36
37
  return paramNodes.map((refParam) => ({
37
38
  name: refParam.name,
38
39
  typeName: getShortType(refParam.type.getText()),
39
40
  optional: refParam.optional,
40
41
  }));
41
- })
42
- .flat();
42
+ });
43
43
  const areAllPropertiesOptional = params.every((param) => param.optional);
44
44
  return ts.factory.createParameterDeclaration(undefined, undefined, ts.factory.createObjectBindingPattern(params.map((refParam) => ts.factory.createBindingElement(undefined, undefined, ts.factory.createIdentifier(refParam.name), undefined))), undefined, ts.factory.createTypeLiteralNode(params.map((refParam) => {
45
45
  return ts.factory.createPropertySignature(undefined, ts.factory.createIdentifier(refParam.name), refParam.optional
@@ -54,6 +54,7 @@ export function getRequestParamFromMethod(method) {
54
54
  }
55
55
  /**
56
56
  * Return Type
57
+ *
57
58
  * export const classNameMethodNameQueryResult<TData = MyClassMethodDefaultResponse, TError = unknown> = UseQueryResult<TData, TError>;
58
59
  */
59
60
  export function createReturnTypeExport({ className, methodName, defaultApiResponse, }) {
@@ -109,28 +110,24 @@ export function createQueryHook({ queryString, suffix, responseDataType, request
109
110
  ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral("queryFn")),
110
111
  ]),
111
112
  ])),
112
- ], undefined, ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.factory.createCallExpression(ts.factory.createIdentifier(queryString), [
113
+ ], undefined, EqualsOrGreaterThanToken, ts.factory.createCallExpression(ts.factory.createIdentifier(queryString), [
113
114
  ts.factory.createTypeReferenceNode(TData),
114
115
  ts.factory.createTypeReferenceNode(TError),
115
116
  ], [
116
117
  ts.factory.createObjectLiteralExpression([
117
- ts.factory.createPropertyAssignment(ts.factory.createIdentifier("queryKey"), ts.factory.createArrayLiteralExpression([
118
- BuildCommonTypeName(queryKey),
119
- ts.factory.createSpreadElement(ts.factory.createParenthesizedExpression(ts.factory.createBinaryExpression(ts.factory.createIdentifier("queryKey"), ts.factory.createToken(ts.SyntaxKind.QuestionQuestionToken), method.getParameters().length
120
- ? ts.factory.createArrayLiteralExpression([
121
- ts.factory.createObjectLiteralExpression(method
122
- .getParameters()
123
- .map((param) => extractPropertiesFromObjectParam(param).map((p) => ts.factory.createShorthandPropertyAssignment(ts.factory.createIdentifier(p.name))))
124
- .flat()),
125
- ])
126
- : ts.factory.createArrayLiteralExpression([])))),
127
- ], false)),
128
- ts.factory.createPropertyAssignment(ts.factory.createIdentifier("queryFn"), ts.factory.createArrowFunction(undefined, undefined, [], undefined, ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.factory.createAsExpression(ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier(className), ts.factory.createIdentifier(methodName)), undefined, method.getParameters().length
118
+ ts.factory.createPropertyAssignment(ts.factory.createIdentifier("queryKey"), ts.factory.createCallExpression(BuildCommonTypeName(getQueryKeyFnName(queryKey)), undefined, method.getParameters().length
119
+ ? [
120
+ ts.factory.createObjectLiteralExpression(method
121
+ .getParameters()
122
+ .flatMap((param) => extractPropertiesFromObjectParam(param).map((p) => ts.factory.createShorthandPropertyAssignment(ts.factory.createIdentifier(p.name))))),
123
+ ts.factory.createIdentifier("queryKey"),
124
+ ]
125
+ : [])),
126
+ ts.factory.createPropertyAssignment(ts.factory.createIdentifier("queryFn"), ts.factory.createArrowFunction(undefined, undefined, [], undefined, EqualsOrGreaterThanToken, ts.factory.createAsExpression(ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier(className), ts.factory.createIdentifier(methodName)), undefined, method.getParameters().length
129
127
  ? [
130
128
  ts.factory.createObjectLiteralExpression(method
131
129
  .getParameters()
132
- .map((param) => extractPropertiesFromObjectParam(param).map((p) => ts.factory.createShorthandPropertyAssignment(ts.factory.createIdentifier(p.name))))
133
- .flat()),
130
+ .flatMap((param) => extractPropertiesFromObjectParam(param).map((p) => ts.factory.createShorthandPropertyAssignment(ts.factory.createIdentifier(p.name))))),
134
131
  ]
135
132
  : undefined), ts.factory.createTypeReferenceNode(TData)))),
136
133
  ts.factory.createSpreadAssignment(ts.factory.createIdentifier("options")),
@@ -176,11 +173,42 @@ export const createUseQuery = ({ className, method, jsDoc, }) => {
176
173
  methodName,
177
174
  queryKey,
178
175
  });
176
+ const queryKeyFn = createQueryKeyFnExport(queryKey, method);
179
177
  return {
180
178
  apiResponse: defaultApiResponse,
181
179
  returnType: returnTypeExport,
182
180
  key: queryKeyExport,
183
181
  queryHook: hookWithJsDoc,
184
182
  suspenseQueryHook: suspenseHookWithJsDoc,
183
+ queryKeyFn,
185
184
  };
186
185
  };
186
+ function getQueryKeyFnName(queryKey) {
187
+ return `${capitalizeFirstLetter(queryKey)}Fn`;
188
+ }
189
+ function createQueryKeyFnExport(queryKey, method) {
190
+ const params = getRequestParamFromMethod(method);
191
+ // override key is used to allow the user to override the the queryKey values
192
+ const overrideKey = ts.factory.createParameterDeclaration(undefined, undefined, ts.factory.createIdentifier("queryKey"), QuestionToken, ts.factory.createTypeReferenceNode("Array<unknown>", []));
193
+ return ts.factory.createVariableStatement([ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], ts.factory.createVariableDeclarationList([
194
+ ts.factory.createVariableDeclaration(ts.factory.createIdentifier(getQueryKeyFnName(queryKey)), undefined, undefined, ts.factory.createArrowFunction(undefined, undefined, params ? [params, overrideKey] : [], undefined, EqualsOrGreaterThanToken, queryKeyFn(queryKey, method))),
195
+ ], ts.NodeFlags.Const));
196
+ }
197
+ function queryKeyFn(queryKey, method) {
198
+ const params = getRequestParamFromMethod(method);
199
+ if (!params) {
200
+ return ts.factory.createArrayLiteralExpression([
201
+ ts.factory.createIdentifier(queryKey),
202
+ ]);
203
+ }
204
+ return ts.factory.createArrayLiteralExpression([
205
+ ts.factory.createIdentifier(queryKey),
206
+ ts.factory.createSpreadElement(ts.factory.createParenthesizedExpression(ts.factory.createBinaryExpression(ts.factory.createIdentifier("queryKey"), ts.factory.createToken(ts.SyntaxKind.QuestionQuestionToken), method.getParameters().length
207
+ ? ts.factory.createArrayLiteralExpression([
208
+ ts.factory.createObjectLiteralExpression(method
209
+ .getParameters()
210
+ .flatMap((param) => extractPropertiesFromObjectParam(param).map((p) => ts.factory.createShorthandPropertyAssignment(ts.factory.createIdentifier(p.name))))),
211
+ ])
212
+ : ts.factory.createArrayLiteralExpression([])))),
213
+ ], false);
214
+ }
package/dist/generate.mjs CHANGED
@@ -1,8 +1,8 @@
1
1
  import { createClient } from "@hey-api/openapi-ts";
2
- import { print } from "./print.mjs";
3
- import { createSource } from "./createSource.mjs";
4
2
  import { buildQueriesOutputPath, buildRequestsOutputPath, formatOptions, } from "./common.mjs";
3
+ import { createSource } from "./createSource.mjs";
5
4
  import { formatOutput } from "./format.mjs";
5
+ import { print } from "./print.mjs";
6
6
  export async function generate(options, version) {
7
7
  const openApiOutputPath = buildRequestsOutputPath(options.output);
8
8
  const formattedOptions = formatOptions(options);
@@ -11,7 +11,6 @@ export async function generate(options, version) {
11
11
  client: formattedOptions.client,
12
12
  debug: formattedOptions.debug,
13
13
  dryRun: false,
14
- enums: formattedOptions.enums,
15
14
  exportCore: true,
16
15
  format: formattedOptions.format,
17
16
  input: formattedOptions.input,
@@ -29,6 +28,7 @@ export async function generate(options, version) {
29
28
  types: {
30
29
  dates: formattedOptions.useDateType,
31
30
  export: true,
31
+ enums: formattedOptions.enums,
32
32
  },
33
33
  useOptions: true,
34
34
  };
package/dist/print.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { mkdir, writeFile } from "fs/promises";
2
- import path from "path";
1
+ import { mkdir, writeFile } from "node:fs/promises";
2
+ import path from "node:path";
3
3
  import { buildQueriesOutputPath, exists } from "./common.mjs";
4
4
  async function printGeneratedTS(result, options) {
5
5
  const dir = buildQueriesOutputPath(options.output);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@7nohe/openapi-react-query-codegen",
3
- "version": "1.2.1",
3
+ "version": "1.3.0",
4
4
  "description": "OpenAPI React Query Codegen",
5
5
  "bin": {
6
6
  "openapi-rq": "dist/cli.mjs"
@@ -30,19 +30,22 @@
30
30
  ],
31
31
  "author": "Daiki Urata (@7nohe)",
32
32
  "license": "MIT",
33
+ "dependencies": {
34
+ "@hey-api/openapi-ts": "0.43.0"
35
+ },
33
36
  "devDependencies": {
34
- "@hey-api/openapi-ts": "0.42.1",
37
+ "@biomejs/biome": "^1.7.2",
35
38
  "@types/node": "^20.10.6",
36
39
  "@vitest/coverage-v8": "^1.5.0",
37
40
  "commander": "^12.0.0",
38
41
  "glob": "^10.3.10",
42
+ "lefthook": "^1.6.10",
39
43
  "rimraf": "^5.0.5",
40
44
  "ts-morph": "^22.0.0",
41
45
  "typescript": "^5.3.3",
42
46
  "vitest": "^1.5.0"
43
47
  },
44
48
  "peerDependencies": {
45
- "@hey-api/openapi-ts": "0.42.1",
46
49
  "commander": "12.x",
47
50
  "glob": "10.x",
48
51
  "ts-morph": "22.x",
@@ -53,8 +56,11 @@
53
56
  },
54
57
  "scripts": {
55
58
  "build": "rimraf dist && tsc -p tsconfig.json",
59
+ "lint": "biome check .",
60
+ "lint:fix": "biome check --apply .",
56
61
  "preview": "npm run build && npm -C examples/react-app run generate:api",
57
62
  "release": "npx git-ensure -a && npx bumpp --commit --tag --push",
58
- "test": "vitest --coverage.enabled true"
63
+ "test": "vitest --coverage.enabled true",
64
+ "snapshot": "vitest --update"
59
65
  }
60
66
  }