@7nohe/openapi-react-query-codegen 1.6.0 → 1.6.2

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
@@ -7,6 +7,7 @@
7
7
  ## Features
8
8
 
9
9
  - Generates custom react hooks that use React Query's `useQuery`, `useSuspenseQuery`, `useMutation` and `useInfiniteQuery` hooks
10
+ - Generates custom functions that use React Query's `ensureQueryData` and `prefetchQuery` functions
10
11
  - Generates query keys and functions for query caching
11
12
  - Generates pure TypeScript clients generated by [@hey-api/openapi-ts](https://github.com/hey-api/openapi-ts)
12
13
 
@@ -42,24 +43,25 @@ Usage: openapi-rq [options]
42
43
  Generate React Query code based on OpenAPI
43
44
 
44
45
  Options:
45
- -V, --version output the version number
46
- -i, --input <value> OpenAPI specification, can be a path, url or string content (required)
47
- -o, --output <value> Output directory (default: "openapi")
48
- -c, --client <value> HTTP client to generate (choices: "angular", "axios", "fetch", "node", "xhr", default: "fetch")
49
- --request <value> Path to custom request file
50
- --format <value> Process output folder with formatter? (choices: "biome", "prettier")
51
- --lint <value> Process output folder with linter? (choices: "biome", "eslint")
52
- --operationId Use operation ID to generate operation names?
53
- --serviceResponse <value> Define shape of returned value from service calls (choices: "body", "response", default: "body")
54
- --base <value> Manually set base in OpenAPI config instead of inferring from server value
55
- --enums <value> Generate JavaScript objects from enum definitions? ['javascript', 'typescript', 'typescript+namespace']
56
- --enums <value> Generate JavaScript objects from enum definitions? (choices: "javascript", "typescript")
57
- --useDateType Use Date type instead of string for date types for models, this will not convert the data to a Date object
58
- --debug Run in debug mode?
59
- --noSchemas Disable generating JSON schemas
60
- --schemaType <value> Type of JSON schema [Default: 'json'] (choices: "form", "json")
61
- --pageParam <value> Name of the query parameter used for pagination (default: "page")
62
- --nextPageParam <value> Name of the response parameter used for next page (default: "nextPage")
46
+ -V, --version output the version number
47
+ -i, --input <value> OpenAPI specification, can be a path, url or string content (required)
48
+ -o, --output <value> Output directory (default: "openapi")
49
+ -c, --client <value> HTTP client to generate (choices: "angular", "axios", "fetch", "node", "xhr", default: "fetch")
50
+ --request <value> Path to custom request file
51
+ --format <value> Process output folder with formatter? (choices: "biome", "prettier")
52
+ --lint <value> Process output folder with linter? (choices: "biome", "eslint")
53
+ --operationId Use operation ID to generate operation names?
54
+ --serviceResponse <value> Define shape of returned value from service calls (choices: "body", "response", default: "body")
55
+ --base <value> Manually set base in OpenAPI config instead of inferring from server value
56
+ --enums <value> Generate JavaScript objects from enum definitions? ['javascript', 'typescript', 'typescript+namespace']
57
+ --enums <value> Generate JavaScript objects from enum definitions? (choices: "javascript", "typescript")
58
+ --useDateType Use Date type instead of string for date types for models, this will not convert the data to a Date object
59
+ --debug Run in debug mode?
60
+ --noSchemas Disable generating JSON schemas
61
+ --schemaType <value> Type of JSON schema [Default: 'json'] (choices: "form", "json")
62
+ --pageParam <value> Name of the query parameter used for pagination (default: "page")
63
+ --nextPageParam <value> Name of the response parameter used for next page (default: "nextPage")
64
+ --initialPageParam <value> Initial value for the pagination parameter (default: "1")
63
65
  -h, --help display help for command
64
66
  ```
65
67
 
@@ -78,9 +80,10 @@ $ openapi-rq -i ./petstore.yaml
78
80
  - queries
79
81
  - index.ts <- main file that exports common types, variables, and queries. Does not export suspense or prefetch hooks
80
82
  - common.ts <- common types
83
+ - ensureQueryData.ts <- generated ensureQueryData functions
81
84
  - queries.ts <- generated query hooks
82
85
  - suspenses.ts <- generated suspense hooks
83
- - prefetch.ts <- generated prefetch hooks learn more about prefetching in in link below
86
+ - prefetch.ts <- generated prefetch functions learn more about prefetching in in link below
84
87
  - requests <- output code generated by @hey-api/openapi-ts
85
88
  ```
86
89
 
@@ -241,6 +244,8 @@ export default App;
241
244
 
242
245
  This feature will generate a function in infiniteQueries.ts when the name specified by the `pageParam` option exists in the query parameters and the name specified by the `nextPageParam` option exists in the response.
243
246
 
247
+ The `initialPageParam` option can be specified to set the intial page to load, defaults to 1. The `nextPageParam` supports dot notation for nested values (i.e. `meta.next`).
248
+
244
249
  Example Schema:
245
250
 
246
251
  ```yml
package/dist/cli.mjs CHANGED
@@ -36,6 +36,7 @@ async function setupProgram() {
36
36
  .addOption(new Option("--schemaType <value>", "Type of JSON schema [Default: 'json']").choices(["form", "json"]))
37
37
  .option("--pageParam <value>", "Name of the query parameter used for pagination", "page")
38
38
  .option("--nextPageParam <value>", "Name of the response parameter used for next page", "nextPage")
39
+ .option("--initialPageParam <value>", "Initial page value to query", "1")
39
40
  .parse();
40
41
  const options = program.opts();
41
42
  await generate(options, version);
@@ -10,4 +10,5 @@ export const OpenApiRqFiles = {
10
10
  suspense: "suspense",
11
11
  index: "index",
12
12
  prefetch: "prefetch",
13
+ ensureQueryData: "ensureQueryData",
13
14
  };
@@ -1,7 +1,7 @@
1
- import { createPrefetch } from "./createPrefetch.mjs";
1
+ import { createPrefetchOrEnsure } from "./createPrefetchOrEnsure.mjs";
2
2
  import { createUseMutation } from "./createUseMutation.mjs";
3
3
  import { createUseQuery } from "./createUseQuery.mjs";
4
- export const createExports = (service, pageParam, nextPageParam) => {
4
+ export const createExports = (service, pageParam, nextPageParam, initialPageParam) => {
5
5
  const { klasses } = service;
6
6
  const methods = klasses.flatMap((k) => k.methods);
7
7
  const allGet = methods.filter((m) => m.httpMethodName.toUpperCase().includes("GET"));
@@ -9,8 +9,9 @@ export const createExports = (service, pageParam, nextPageParam) => {
9
9
  const allPut = methods.filter((m) => m.httpMethodName.toUpperCase().includes("PUT"));
10
10
  const allPatch = methods.filter((m) => m.httpMethodName.toUpperCase().includes("PATCH"));
11
11
  const allDelete = methods.filter((m) => m.httpMethodName.toUpperCase().includes("DELETE"));
12
- const allGetQueries = allGet.map((m) => createUseQuery(m, pageParam, nextPageParam));
13
- const allPrefetchQueries = allGet.map((m) => createPrefetch(m));
12
+ const allGetQueries = allGet.map((m) => createUseQuery(m, pageParam, nextPageParam, initialPageParam));
13
+ const allPrefetchQueries = allGet.map((m) => createPrefetchOrEnsure({ ...m, functionType: "prefetch" }));
14
+ const allEnsureQueries = allGet.map((m) => createPrefetchOrEnsure({ ...m, functionType: "ensure" }));
14
15
  const allPostMutations = allPost.map((m) => createUseMutation(m));
15
16
  const allPutMutations = allPut.map((m) => createUseMutation(m));
16
17
  const allPatchMutations = allPatch.map((m) => createUseMutation(m));
@@ -44,9 +45,8 @@ export const createExports = (service, pageParam, nextPageParam) => {
44
45
  suspenseQueryHook,
45
46
  ]);
46
47
  const suspenseExports = [...suspenseQueries];
47
- const allPrefetches = allPrefetchQueries.flatMap(({ prefetchHook }) => [
48
- prefetchHook,
49
- ]);
48
+ const allPrefetches = allPrefetchQueries.flatMap(({ hook }) => [hook]);
49
+ const allEnsures = allEnsureQueries.flatMap(({ hook }) => [hook]);
50
50
  const allPrefetchExports = [...allPrefetches];
51
51
  return {
52
52
  /**
@@ -69,5 +69,9 @@ export const createExports = (service, pageParam, nextPageParam) => {
69
69
  * Prefetch exports are the hooks that are used in the prefetch components
70
70
  */
71
71
  allPrefetchExports,
72
+ /**
73
+ * Ensure exports are the hooks that are used in the loader components
74
+ */
75
+ allEnsures,
72
76
  };
73
77
  };
@@ -3,12 +3,15 @@ import { BuildCommonTypeName, extractPropertiesFromObjectParam, getNameFromMetho
3
3
  import { createQueryKeyFromMethod, getQueryKeyFnName, getRequestParamFromMethod, hookNameFromMethod, } from "./createUseQuery.mjs";
4
4
  import { addJSDocToNode } from "./util.mjs";
5
5
  /**
6
- * Creates a prefetch function for a query
6
+ * Creates a prefetch/ensure function for a query
7
7
  */
8
- function createPrefetchHook({ requestParams, method, className, }) {
8
+ function createPrefetchOrEnsureHook({ requestParams, method, className, functionType, }) {
9
9
  const methodName = getNameFromMethod(method);
10
10
  const queryName = hookNameFromMethod({ method, className });
11
- const customHookName = `prefetch${queryName.charAt(0).toUpperCase() + queryName.slice(1)}`;
11
+ let customHookName = `prefetch${queryName.charAt(0).toUpperCase() + queryName.slice(1)}`;
12
+ if (functionType === "ensure") {
13
+ customHookName = `ensure${queryName.charAt(0).toUpperCase() + queryName.slice(1)}Data`;
14
+ }
12
15
  const queryKey = createQueryKeyFromMethod({ method, className });
13
16
  // const
14
17
  const hookExport = ts.factory.createVariableStatement(
@@ -17,7 +20,7 @@ function createPrefetchHook({ requestParams, method, className, }) {
17
20
  ts.factory.createVariableDeclaration(ts.factory.createIdentifier(customHookName), undefined, undefined, ts.factory.createArrowFunction(undefined, undefined, [
18
21
  ts.factory.createParameterDeclaration(undefined, undefined, "queryClient", undefined, ts.factory.createTypeReferenceNode(ts.factory.createIdentifier("QueryClient"))),
19
22
  ...requestParams,
20
- ], undefined, ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.factory.createCallExpression(ts.factory.createIdentifier("queryClient.prefetchQuery"), undefined, [
23
+ ], undefined, ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.factory.createCallExpression(ts.factory.createIdentifier(`queryClient.${functionType === "prefetch" ? "prefetchQuery" : "ensureQueryData"}`), undefined, [
21
24
  ts.factory.createObjectLiteralExpression([
22
25
  ts.factory.createPropertyAssignment(ts.factory.createIdentifier("queryKey"), ts.factory.createCallExpression(BuildCommonTypeName(getQueryKeyFnName(queryKey)), undefined, method.getParameters().length
23
26
  ? [
@@ -38,16 +41,17 @@ function createPrefetchHook({ requestParams, method, className, }) {
38
41
  ], ts.NodeFlags.Const));
39
42
  return hookExport;
40
43
  }
41
- export const createPrefetch = ({ className, method, jsDoc, }) => {
44
+ export const createPrefetchOrEnsure = ({ className, method, jsDoc, functionType, }) => {
42
45
  const requestParam = getRequestParamFromMethod(method);
43
46
  const requestParams = requestParam ? [requestParam] : [];
44
- const prefetchHook = createPrefetchHook({
47
+ const prefetchOrEnsureHook = createPrefetchOrEnsureHook({
45
48
  requestParams,
46
49
  method,
47
50
  className,
51
+ functionType,
48
52
  });
49
- const hookWithJsDoc = addJSDocToNode(prefetchHook, jsDoc);
53
+ const hookWithJsDoc = addJSDocToNode(prefetchOrEnsureHook, jsDoc);
50
54
  return {
51
- prefetchHook: hookWithJsDoc,
55
+ hook: hookWithJsDoc,
52
56
  };
53
57
  };
@@ -5,7 +5,7 @@ import { OpenApiRqFiles } from "./constants.mjs";
5
5
  import { createExports } from "./createExports.mjs";
6
6
  import { createImports } from "./createImports.mjs";
7
7
  import { getServices } from "./service.mjs";
8
- const createSourceFile = async (outputPath, serviceEndName, pageParam, nextPageParam) => {
8
+ const createSourceFile = async (outputPath, serviceEndName, pageParam, nextPageParam, initialPageParam) => {
9
9
  const project = new Project({
10
10
  // Optionally specify compiler options, tsconfig.json, in-memory file system, and more here.
11
11
  // If you initialize with a tsconfig.json, then it will automatically populate the project
@@ -20,7 +20,7 @@ const createSourceFile = async (outputPath, serviceEndName, pageParam, nextPageP
20
20
  serviceEndName,
21
21
  project,
22
22
  });
23
- const exports = createExports(service, pageParam, nextPageParam);
23
+ const exports = createExports(service, pageParam, nextPageParam, initialPageParam);
24
24
  const commonSource = ts.factory.createSourceFile([...imports, ...exports.allCommon], ts.factory.createToken(ts.SyntaxKind.EndOfFileToken), ts.NodeFlags.None);
25
25
  const commonImport = ts.factory.createImportDeclaration(undefined, ts.factory.createImportClause(false, ts.factory.createIdentifier("* as Common"), undefined), ts.factory.createStringLiteral(`./${OpenApiRqFiles.common}`), undefined);
26
26
  const commonExport = ts.factory.createExportDeclaration(undefined, false, undefined, ts.factory.createStringLiteral(`./${OpenApiRqFiles.common}`), undefined);
@@ -30,6 +30,7 @@ const createSourceFile = async (outputPath, serviceEndName, pageParam, nextPageP
30
30
  const suspenseSource = ts.factory.createSourceFile([commonImport, ...imports, ...exports.suspenseExports], ts.factory.createToken(ts.SyntaxKind.EndOfFileToken), ts.NodeFlags.None);
31
31
  const indexSource = ts.factory.createSourceFile([commonExport, queriesExport], ts.factory.createToken(ts.SyntaxKind.EndOfFileToken), ts.NodeFlags.None);
32
32
  const prefetchSource = ts.factory.createSourceFile([commonImport, ...imports, ...exports.allPrefetchExports], ts.factory.createToken(ts.SyntaxKind.EndOfFileToken), ts.NodeFlags.None);
33
+ const ensureSource = ts.factory.createSourceFile([commonImport, ...imports, ...exports.allEnsures], ts.factory.createToken(ts.SyntaxKind.EndOfFileToken), ts.NodeFlags.None);
33
34
  return {
34
35
  commonSource,
35
36
  infiniteQueriesSource,
@@ -37,20 +38,22 @@ const createSourceFile = async (outputPath, serviceEndName, pageParam, nextPageP
37
38
  suspenseSource,
38
39
  indexSource,
39
40
  prefetchSource,
41
+ ensureSource,
40
42
  };
41
43
  };
42
- export const createSource = async ({ outputPath, version, serviceEndName, pageParam, nextPageParam, }) => {
44
+ export const createSource = async ({ outputPath, version, serviceEndName, pageParam, nextPageParam, initialPageParam, }) => {
43
45
  const queriesFile = ts.createSourceFile(`${OpenApiRqFiles.queries}.ts`, "", ts.ScriptTarget.Latest, false, ts.ScriptKind.TS);
44
46
  const infiniteQueriesFile = ts.createSourceFile(`${OpenApiRqFiles.infiniteQueries}.ts`, "", ts.ScriptTarget.Latest, false, ts.ScriptKind.TS);
45
47
  const commonFile = ts.createSourceFile(`${OpenApiRqFiles.common}.ts`, "", ts.ScriptTarget.Latest, false, ts.ScriptKind.TS);
46
48
  const suspenseFile = ts.createSourceFile(`${OpenApiRqFiles.suspense}.ts`, "", ts.ScriptTarget.Latest, false, ts.ScriptKind.TS);
47
49
  const indexFile = ts.createSourceFile(`${OpenApiRqFiles.index}.ts`, "", ts.ScriptTarget.Latest, false, ts.ScriptKind.TS);
48
50
  const prefetchFile = ts.createSourceFile(`${OpenApiRqFiles.prefetch}.ts`, "", ts.ScriptTarget.Latest, false, ts.ScriptKind.TS);
51
+ const ensureQueryDataFile = ts.createSourceFile(`${OpenApiRqFiles.ensureQueryData}.ts`, "", ts.ScriptTarget.Latest, false, ts.ScriptKind.TS);
49
52
  const printer = ts.createPrinter({
50
53
  newLine: ts.NewLineKind.LineFeed,
51
54
  removeComments: false,
52
55
  });
53
- const { commonSource, mainSource, infiniteQueriesSource, suspenseSource, indexSource, prefetchSource, } = await createSourceFile(outputPath, serviceEndName, pageParam, nextPageParam);
56
+ const { commonSource, mainSource, infiniteQueriesSource, suspenseSource, indexSource, prefetchSource, ensureSource, } = await createSourceFile(outputPath, serviceEndName, pageParam, nextPageParam, initialPageParam);
54
57
  const comment = `// generated with @7nohe/openapi-react-query-codegen@${version} \n\n`;
55
58
  const commonResult = comment +
56
59
  printer.printNode(ts.EmitHint.Unspecified, commonSource, commonFile);
@@ -64,6 +67,8 @@ export const createSource = async ({ outputPath, version, serviceEndName, pagePa
64
67
  printer.printNode(ts.EmitHint.Unspecified, indexSource, indexFile);
65
68
  const prefetchResult = comment +
66
69
  printer.printNode(ts.EmitHint.Unspecified, prefetchSource, prefetchFile);
70
+ const enqureResult = comment +
71
+ printer.printNode(ts.EmitHint.Unspecified, ensureSource, ensureQueryDataFile);
67
72
  return [
68
73
  {
69
74
  name: `${OpenApiRqFiles.index}.ts`,
@@ -89,5 +94,9 @@ export const createSource = async ({ outputPath, version, serviceEndName, pagePa
89
94
  name: `${OpenApiRqFiles.prefetch}.ts`,
90
95
  content: prefetchResult,
91
96
  },
97
+ {
98
+ name: `${OpenApiRqFiles.ensureQueryData}.ts`,
99
+ content: enqureResult,
100
+ },
92
101
  ];
93
102
  };
@@ -85,12 +85,36 @@ export function createQueryKeyFromMethod({ method, className, }) {
85
85
  const queryKey = `${customHookName}Key`;
86
86
  return queryKey;
87
87
  }
88
+ /**
89
+ * Extracts the type of the next page parameter from the given properties.
90
+ *
91
+ * @param properties The properties to search through.
92
+ * @param nextPageParam The name of the next page parameter.
93
+ * @returns The type of the next page parameter, if found.
94
+ */
95
+ function findNextPageParamType(properties, nextPageParam) {
96
+ if (!properties)
97
+ return undefined;
98
+ for (const property of properties) {
99
+ if (property.getName() === nextPageParam) {
100
+ return property?.getDeclarations()?.at(0)?.getType()?.getText();
101
+ }
102
+ const type = property.getDeclarations().at(0)?.getType();
103
+ const nestedProperties = type?.getProperties();
104
+ if (!type?.isObject() || type.isArray())
105
+ continue;
106
+ const result = findNextPageParamType(nestedProperties, nextPageParam);
107
+ if (result)
108
+ return result;
109
+ }
110
+ return undefined;
111
+ }
88
112
  /**
89
113
  * Creates a custom hook for a query
90
114
  * @param queryString The type of query to use from react-query
91
115
  * @param suffix The suffix to append to the hook name
92
116
  */
93
- export function createQueryHook({ queryString, suffix, responseDataType, requestParams, method, className, pageParam, nextPageParam, }) {
117
+ export function createQueryHook({ queryString, suffix, responseDataType, requestParams, method, className, pageParam, nextPageParam, initialPageParam, }) {
94
118
  const methodName = getNameFromMethod(method);
95
119
  const customHookName = hookNameFromMethod({ method, className });
96
120
  const queryKey = createQueryKeyFromMethod({ method, className });
@@ -101,6 +125,11 @@ export function createQueryHook({ queryString, suffix, responseDataType, request
101
125
  const isInfiniteQuery = queryString === "useInfiniteQuery";
102
126
  const responseDataTypeRef = responseDataType.default;
103
127
  const responseDataTypeIdentifier = responseDataTypeRef.typeName;
128
+ const arg = method.getReturnType().getTypeArguments().at(0);
129
+ const nextPageParamTypePropetires = arg?.getProperties();
130
+ const nextPageParamType = arg?.isObject() && nextPageParam
131
+ ? findNextPageParamType(nextPageParamTypePropetires, nextPageParam.split(".").at(-1) ?? "")
132
+ : undefined;
104
133
  const hookExport = ts.factory.createVariableStatement([ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], ts.factory.createVariableDeclarationList([
105
134
  ts.factory.createVariableDeclaration(ts.factory.createIdentifier(`${customHookName}${suffix}`), undefined, undefined, ts.factory.createArrowFunction(undefined, ts.factory.createNodeArray([
106
135
  isInfiniteQuery
@@ -151,18 +180,22 @@ export function createQueryHook({ queryString, suffix, responseDataType, request
151
180
  ts.factory.createObjectLiteralExpression(method
152
181
  .getParameters()
153
182
  .flatMap((param) => extractPropertiesFromObjectParam(param).map((p) => p.name === pageParam
154
- ? ts.factory.createPropertyAssignment(ts.factory.createIdentifier(p.name), ts.factory.createAsExpression(ts.factory.createIdentifier("pageParam"), ts.factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword)))
183
+ ? ts.factory.createPropertyAssignment(ts.factory.createIdentifier(p.name), ts.factory.createAsExpression(ts.factory.createIdentifier("pageParam"), ts.factory.createKeywordTypeNode(p.type?.getText() === "number"
184
+ ? ts.SyntaxKind
185
+ .NumberKeyword
186
+ : ts.SyntaxKind
187
+ .StringKeyword)))
155
188
  : ts.factory.createShorthandPropertyAssignment(ts.factory.createIdentifier(p.name))))),
156
189
  ]
157
190
  : undefined), ts.factory.createTypeReferenceNode(TData)))),
158
- ...createInfiniteQueryParams(pageParam, nextPageParam),
191
+ ...createInfiniteQueryParams(pageParam, nextPageParam, initialPageParam, nextPageParamType),
159
192
  ts.factory.createSpreadAssignment(ts.factory.createIdentifier("options")),
160
193
  ]),
161
194
  ]))),
162
195
  ], ts.NodeFlags.Const));
163
196
  return hookExport;
164
197
  }
165
- export const createUseQuery = ({ className, method, jsDoc }, pageParam, nextPageParam) => {
198
+ export const createUseQuery = ({ className, method, jsDoc }, pageParam, nextPageParam, initialPageParam) => {
166
199
  const methodName = getNameFromMethod(method);
167
200
  const queryKey = createQueryKeyFromMethod({ method, className });
168
201
  const { apiResponse: defaultApiResponse, responseDataType } = createApiResponseType({
@@ -206,6 +239,7 @@ export const createUseQuery = ({ className, method, jsDoc }, pageParam, nextPage
206
239
  className,
207
240
  pageParam,
208
241
  nextPageParam,
242
+ initialPageParam,
209
243
  })
210
244
  : undefined;
211
245
  const hookWithJsDoc = addJSDocToNode(queryHook, jsDoc);
@@ -257,16 +291,22 @@ function queryKeyFn(queryKey, method) {
257
291
  : ts.factory.createArrayLiteralExpression([])))),
258
292
  ], false);
259
293
  }
260
- function createInfiniteQueryParams(pageParam, nextPageParam) {
294
+ function createInfiniteQueryParams(pageParam, nextPageParam, initialPageParam = "1", type) {
261
295
  if (pageParam === undefined || nextPageParam === undefined) {
262
296
  return [];
263
297
  }
264
298
  return [
265
- ts.factory.createPropertyAssignment(ts.factory.createIdentifier("initialPageParam"), ts.factory.createNumericLiteral(1)),
299
+ ts.factory.createPropertyAssignment(ts.factory.createIdentifier("initialPageParam"), ts.factory.createStringLiteral(initialPageParam)),
266
300
  ts.factory.createPropertyAssignment(ts.factory.createIdentifier("getNextPageParam"),
267
301
  // (response) => (response as { nextPage: number }).nextPage,
268
302
  ts.factory.createArrowFunction(undefined, undefined, [
269
303
  ts.factory.createParameterDeclaration(undefined, undefined, ts.factory.createIdentifier("response"), undefined, undefined),
270
- ], undefined, EqualsOrGreaterThanToken, ts.factory.createPropertyAccessExpression(ts.factory.createParenthesizedExpression(ts.factory.createAsExpression(ts.factory.createIdentifier("response"), ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(`{ ${nextPageParam}: number }`)))), ts.factory.createIdentifier(nextPageParam)))),
304
+ ], undefined, EqualsOrGreaterThanToken, ts.factory.createPropertyAccessExpression(ts.factory.createParenthesizedExpression(ts.factory.createAsExpression(ts.factory.createIdentifier("response"), nextPageParam.split(".").reduceRight((acc, segment) => {
305
+ return ts.factory.createTypeLiteralNode([
306
+ ts.factory.createPropertySignature(undefined, ts.factory.createIdentifier(segment), undefined, acc),
307
+ ]);
308
+ }, ts.factory.createKeywordTypeNode(type === "number"
309
+ ? ts.SyntaxKind.NumberKeyword
310
+ : ts.SyntaxKind.StringKeyword)))), ts.factory.createIdentifier(nextPageParam)))),
271
311
  ];
272
312
  }
package/dist/generate.mjs CHANGED
@@ -27,6 +27,7 @@ export async function generate(options, version) {
27
27
  export: true,
28
28
  response: formattedOptions.serviceResponse,
29
29
  asClass: true,
30
+ operationId: formattedOptions.operationId ?? false,
30
31
  },
31
32
  types: {
32
33
  dates: formattedOptions.useDateType,
@@ -42,6 +43,7 @@ export async function generate(options, version) {
42
43
  serviceEndName: "Service", // we are hard coding this because changing the service end name was depreciated in @hey-api/openapi-ts
43
44
  pageParam: formattedOptions.pageParam,
44
45
  nextPageParam: formattedOptions.nextPageParam,
46
+ initialPageParam: formattedOptions.initialPageParam.toString(),
45
47
  });
46
48
  await print(source, formattedOptions);
47
49
  const queriesOutputPath = buildQueriesOutputPath(options.output);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@7nohe/openapi-react-query-codegen",
3
- "version": "1.6.0",
3
+ "version": "1.6.2",
4
4
  "description": "OpenAPI React Query Codegen",
5
5
  "keywords": [
6
6
  "codegen",
@@ -59,9 +59,9 @@
59
59
  "scripts": {
60
60
  "build": "rimraf dist && tsc -p tsconfig.json",
61
61
  "lint": "biome check .",
62
- "lint:fix": "biome check --apply .",
62
+ "lint:fix": "biome check --write .",
63
63
  "preview": "npm run build && npm -C examples/react-app run generate:api",
64
- "release": "npx git-ensure -a && npx bumpp --commit --tag --push",
64
+ "release": "npx git-ensure -a -b v1 && npx bumpp --commit --tag --push",
65
65
  "snapshot": "vitest --update",
66
66
  "test": "vitest --coverage.enabled true"
67
67
  }