@toktokhan-dev/cli-plugin-gen-api-react-query 0.0.18 → 0.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/index.d.ts CHANGED
@@ -38,11 +38,10 @@ interface GenerateSwaggerApiConfig {
38
38
  swaggerSchemaUrl: string;
39
39
  /** 생성될 파일들이 위치할 경로입니다. */
40
40
  output: string;
41
- /** 생성되는 코드의 React Query 포함 여부 입니다.
42
- * 해당 옵션이 false 일경우 infiniteQuery 를 포함한 모든 Query 가 생성되지 않습니다. */
41
+ /** 생성되는 코드의 useQuery, useInfiniteQuery 포함 여부 입니다. */
43
42
  includeReactQuery: boolean;
44
- /** 생성되는 코드의 InfiniteQuery 포함 여부 입니다. */
45
- includeReactInfiniteQuery: boolean;
43
+ /** 생성되는 코드의 useSuspenseQuery, useSuspenseInfiniteQuery 포함 여부 입니다. */
44
+ includeReactSuspenseQuery: boolean;
46
45
  /** Api 의 axios 혹은 fetch 요청 instance 주소입니다. */
47
46
  instancePath: string;
48
47
  /** http client 타입입니다. */
package/dist/index.js CHANGED
@@ -23,11 +23,12 @@ const GENERATE_SWAGGER_DATA = {
23
23
  TYPE_FILE: ['react-query-type.ts', 'data-contracts.ts', 'util-types.ts'],
24
24
  UTIL_FILE: ['param-serializer-by.ts'],
25
25
  QUERY_HOOK_INDICATOR: '@indicator-for-query-hook',
26
+ USE_SUSPENSE_QUERY_HOOK_INDICATOR: '@indicator-for-use-suspense-query-hook',
26
27
  AXIOS_DEFAULT_INSTANCE_PATH: '@/configs/axios/instance',
27
28
  FETCH_DEFAULT_INSTANCE_PATH: '@/configs/fetch/fetch-extend',
28
29
  };
29
30
 
30
- const { EXTRA_TEMPLATE_FOLTER, CUSTOM_AXIOS_TEMPLATE_FOLDER, CUSTOM_FETCH_TEMPLATE_FOLDER, QUERY_HOOK_INDICATOR: QUERY_HOOK_INDICATOR$1, } = GENERATE_SWAGGER_DATA;
31
+ const { EXTRA_TEMPLATE_FOLTER, CUSTOM_AXIOS_TEMPLATE_FOLDER, CUSTOM_FETCH_TEMPLATE_FOLDER, QUERY_HOOK_INDICATOR: QUERY_HOOK_INDICATOR$1, USE_SUSPENSE_QUERY_HOOK_INDICATOR: USE_SUSPENSE_QUERY_HOOK_INDICATOR$1, } = GENERATE_SWAGGER_DATA;
31
32
  const parseSwagger = (config) => generateApi({
32
33
  templates: config.httpClientType === 'axios' ?
33
34
  CUSTOM_AXIOS_TEMPLATE_FOLDER
@@ -62,15 +63,19 @@ const parseSwagger = (config) => generateApi({
62
63
  onPrepareConfig: (defaultConfig) => {
63
64
  return {
64
65
  ...defaultConfig,
65
- myConfig: { QUERY_HOOK_INDICATOR: QUERY_HOOK_INDICATOR$1, ...config },
66
+ myConfig: {
67
+ QUERY_HOOK_INDICATOR: QUERY_HOOK_INDICATOR$1,
68
+ USE_SUSPENSE_QUERY_HOOK_INDICATOR: USE_SUSPENSE_QUERY_HOOK_INDICATOR$1,
69
+ ...config,
70
+ },
66
71
  };
67
72
  },
68
73
  },
69
74
  });
70
75
 
71
- const { TYPE_FILE, UTIL_FILE, QUERY_HOOK_INDICATOR } = GENERATE_SWAGGER_DATA;
76
+ const { TYPE_FILE, UTIL_FILE, QUERY_HOOK_INDICATOR, USE_SUSPENSE_QUERY_HOOK_INDICATOR, } = GENERATE_SWAGGER_DATA;
72
77
  const writeSwaggerApiFile = (params) => {
73
- const { input, output, spinner } = params;
78
+ const { input, output, spinner, config } = params;
74
79
  input.files.forEach(async ({ fileName, fileContent: content, fileExtension }) => {
75
80
  const name = fileName + fileExtension;
76
81
  try {
@@ -97,9 +102,14 @@ const writeSwaggerApiFile = (params) => {
97
102
  return;
98
103
  }
99
104
  if (isApiFile) {
100
- const { apiContents, hookContents } = spilitHookContents(filename, content);
101
- genreatePretty(path.resolve(targetFolder, `${filename}.api.ts`), apiContents);
102
- genreatePretty(path.resolve(targetFolder, `${filename}.query.ts`), hookContents);
105
+ const { apiContents, hookParts } = splitHookContents(filename, content);
106
+ generatePretty(path.resolve(targetFolder, `${filename}.api.ts`), apiContents);
107
+ if (config.includeReactQuery) {
108
+ generatePretty(path.resolve(targetFolder, `${filename}.query.ts`), hookParts[0]);
109
+ }
110
+ if (config.includeReactSuspenseQuery) {
111
+ generatePretty(path.resolve(targetFolder, `${filename}.suspenseQuery.ts`), hookParts[1]);
112
+ }
103
113
  return;
104
114
  }
105
115
  generate(path.resolve(targetFolder, name), content);
@@ -109,7 +119,7 @@ const writeSwaggerApiFile = (params) => {
109
119
  }
110
120
  });
111
121
  };
112
- async function genreatePretty(path, contents) {
122
+ async function generatePretty(path, contents) {
113
123
  const organized = await prettierString(contents, {
114
124
  parser: 'babel-ts',
115
125
  plugins: ['prettier-plugin-organize-imports'],
@@ -123,8 +133,9 @@ async function genreatePretty(path, contents) {
123
133
  function generate(path, contents) {
124
134
  fs.writeFileSync(path, contents);
125
135
  }
126
- function spilitHookContents(filename, content) {
136
+ function splitHookContents(filename, content) {
127
137
  const [_apiContent, _hookContent] = content.split(QUERY_HOOK_INDICATOR);
138
+ const _hookParts = _hookContent.split(USE_SUSPENSE_QUERY_HOOK_INDICATOR);
128
139
  const lastImport = getLastImportLine(content);
129
140
  const lines = content.split('\n');
130
141
  const importArea = [
@@ -133,7 +144,7 @@ function spilitHookContents(filename, content) {
133
144
  ].join('\n');
134
145
  return {
135
146
  apiContents: _apiContent,
136
- hookContents: importArea + _hookContent,
147
+ hookParts: _hookParts.map((d) => importArea + d),
137
148
  };
138
149
  }
139
150
  function getLastImportLine(content) {
@@ -155,7 +166,7 @@ const genApi = defineCommand({
155
166
  swaggerSchemaUrl: '',
156
167
  output: 'src/generated/apis',
157
168
  includeReactQuery: true,
158
- includeReactInfiniteQuery: true,
169
+ includeReactSuspenseQuery: false,
159
170
  httpClientType: 'axios',
160
171
  instancePath: GENERATE_SWAGGER_DATA.AXIOS_DEFAULT_INSTANCE_PATH,
161
172
  paginationSets: [
@@ -191,7 +202,12 @@ const genApi = defineCommand({
191
202
  }
192
203
  withLoading('Write Swagger API', //
193
204
  covered.output, (spinner) => {
194
- writeSwaggerApiFile({ input: parsed, output: covered.output, spinner });
205
+ writeSwaggerApiFile({
206
+ input: parsed,
207
+ output: covered.output,
208
+ spinner,
209
+ config,
210
+ });
195
211
  });
196
212
  },
197
213
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@toktokhan-dev/cli-plugin-gen-api-react-query",
3
- "version": "0.0.18",
3
+ "version": "0.1.0",
4
4
  "description": "A CLI plugin for generating API hooks with React Query built by TOKTOKHAN.DEV",
5
5
  "author": "TOKTOKHAN.DEV <fe-system@toktokhan.dev>",
6
6
  "license": "ISC",
@@ -38,8 +38,8 @@
38
38
  "lodash": "^4.17.21",
39
39
  "prettier-plugin-organize-imports": "^3.2.4",
40
40
  "swagger-typescript-api": "^13.0.3",
41
- "@toktokhan-dev/cli": "0.0.11",
42
- "@toktokhan-dev/node": "0.0.10"
41
+ "@toktokhan-dev/node": "0.0.10",
42
+ "@toktokhan-dev/cli": "0.0.11"
43
43
  },
44
44
  "devDependencies": {
45
45
  "@types/lodash": "^4.17.0",
@@ -6,36 +6,36 @@ const { RESERVED_REQ_PARAMS_ARG_NAMES } = config.constants;
6
6
  const routes = route.routes;
7
7
  const dataContracts = _.map(modelTypes, "name");
8
8
 
9
-
10
9
  const projectRootPath = process.env.PWD;
11
- const myTemeplatePath = `../my`
12
- const reactQueryTemplatePath = `${myTemeplatePath}/react-query-hook.eta`
13
- const reactQuerKeyTemplatePath = `${myTemeplatePath}/react-query-key.eta`
10
+ const myTemeplatePath = `../my`;
11
+ const reactQueryTemplatePath = `${myTemeplatePath}/react-query-hook.eta`;
12
+ const reactSuspenseQueryTemplatePath = `${myTemeplatePath}/react-query-suspense-hook.eta`;
13
+ const reactQuerKeyTemplatePath = `${myTemeplatePath}/react-query-key.eta`;
14
14
 
15
15
  const apiClassName = classNameCase(route.moduleName) + 'Api';
16
- const paginationSets = myConfig?.paginationSets
17
- const instancePath = myConfig?.instancePath
18
-
19
- const apiInstanceName =route.moduleName + "Api";
20
- const queryKeyName = "QUERY_KEY_" + _.upperCase(apiClassName).replace(/ /g, '_');
16
+ const paginationSets = myConfig?.paginationSets;
17
+ const instancePath = myConfig?.instancePath;
21
18
 
19
+ const includeReactQuery = myConfig?.includeReactQuery;
20
+ const includeReactSuspenseQuery = myConfig?.includeReactSuspenseQuery;
22
21
 
22
+ const apiInstanceName = route.moduleName + "Api";
23
+ const queryKeyName = "QUERY_KEY_" + _.upperCase(apiClassName).replace(/ /g, '_');
23
24
 
24
25
  const hasPaginationKeyword = (queryString, keywords = paginationKeywords ) => {
25
- if(!myConfig?.includeReactInfiniteQuery) return false;
26
+ if(!includeReactQuery && !includeReactSuspenseQuery ) return false;
26
27
  const keywordUnion = keywords.map(str => `.*${str}.*`).join("|");
27
28
  const rgxSting = keywords.map(str => `(${keywordUnion})`).join("");
28
29
  const rgx = new RegExp(rgxSting);
29
30
  return rgx.test(queryString);
30
- }
31
-
31
+ };
32
32
 
33
33
  const upperSnakeCase = (str) => _.upperCase(str).replace(/ /g, '_');
34
34
 
35
- const removeModuleName = (str) => str.replace(route.moduleName,'');
35
+ const removeModuleName = (str) => str.replace(route.moduleName,'');
36
36
 
37
37
  const getConfigByRoute = (route) => {
38
- const { specificArgNameResolver } = route
38
+ const { specificArgNameResolver } = route;
39
39
  const { parameters, path, method, payload, query, formData, security, requestParams } = route.request;
40
40
  const pathParams = _.values(parameters);
41
41
  const pathParamsNames = _.map(pathParams, "name");
@@ -45,7 +45,7 @@ const getConfigByRoute = (route) => {
45
45
  name: specificArgNameResolver.resolve(RESERVED_REQ_PARAMS_ARG_NAMES),
46
46
  optional: true,
47
47
  type: "RequestParams",
48
- }
48
+ };
49
49
 
50
50
  const argToTmpl = ({ name, optional, type, defaultValue }) => `${name}${!defaultValue && optional ? '?' : ''}: ${type}`;
51
51
 
@@ -71,30 +71,29 @@ const getConfigByRoute = (route) => {
71
71
  // Sort by optionality
72
72
  .sortBy(rawWrapperArgs, [o => o.optional])
73
73
  .map(argToTmpl)
74
- .join('; ')
75
-
74
+ .join('; ');
76
75
 
77
76
  const functionName = route.routeName.usage;
78
- const hookVariant = _.upperCase(method) === "GET" ? "Query" : "Mutation"
77
+ const hookVariant = _.upperCase(method) === "GET" ? "Query" : "Mutation";
79
78
  const key = upperSnakeCase(functionName);
80
79
  const methodKey = upperSnakeCase(removeModuleName(functionName));
81
- const pagination = paginationSets.find(d => !!query?.type && hasPaginationKeyword(query?.type.split("\n").join(""), d.keywords));
80
+ const pagination = paginationSets.find(d => !!query?.type && hasPaginationKeyword(query?.type.split("\n").join(""), d.keywords));
82
81
 
83
82
  const isQuery = hookVariant === "Query";
84
83
  const isMutation = hookVariant === "Mutation";
85
84
  const hasPagination = !!pagination;
86
85
 
87
- const isOptionalVariables = _
88
- // Find optional value
86
+ const isOptionalVariables = _
89
87
  .filter(rawWrapperArgs, o => o.optional).length === rawWrapperArgs.length;
90
88
 
91
- const conditionalVriablesText = isOptionalVariables? "variables?" : "variables";
89
+ const conditionalVriablesText = isOptionalVariables ? "variables?" : "variables";
92
90
  const repalceTarget = "${" + conditionalVriablesText + ".";
93
91
 
94
-
95
92
  return {
96
- conditions:{
93
+ conditions: {
97
94
  hasPagination,
95
+ includeReactQuery,
96
+ includeReactSuspenseQuery,
98
97
  isQuery,
99
98
  isMutation,
100
99
  isOptionalVariables,
@@ -116,31 +115,32 @@ const getConfigByRoute = (route) => {
116
115
  removeModuleName,
117
116
  argToTmpl,
118
117
  }
119
- }
120
- }
118
+ };
119
+ };
121
120
 
122
121
  const dataForReactHookTemplate = {
123
- getConfigByRoute,
124
- queryKeyName,
125
- apiClassName,
126
- apiInstanceName,
127
- };
128
-
122
+ getConfigByRoute,
123
+ queryKeyName,
124
+ apiClassName,
125
+ apiInstanceName,
126
+ };
129
127
  %>
130
128
 
131
- <% if (config.httpClientType === config.constants.HTTP_CLIENT.AXIOS) { %> import { AxiosRequestConfig, AxiosResponse } from "axios"; <% } %>
129
+ <% if (config.httpClientType === config.constants.HTTP_CLIENT.AXIOS) { %>
130
+ import { AxiosRequestConfig, AxiosResponse } from "axios";
131
+ <% } %>
132
132
 
133
133
  import { AxiosError } from 'axios';
134
- import { useQuery, useMutation, useInfiniteQuery, InfiniteData } from '@tanstack/react-query';
135
- import { QueryHookParams, InfiniteQueryHookParams, MutationHookParams, Parameter, RequestFnReturn } from "../@types/react-query-type";
136
- import { paramsSerializerBy } "../@utils/param-serializer-by"
134
+ import { useQuery, useMutation, useInfiniteQuery, useSuspenseQuery, useSuspenseInfiniteQuery, InfiniteData } from '@tanstack/react-query';
135
+ import { QueryHookParams, InfiniteQueryHookParams, MutationHookParams, Parameter, RequestFnReturn, SuspenseInfiniteQueryHookParams, SuspenseQueryHookParams } from "../@types/react-query-type";
136
+ import { paramsSerializerBy } from "../@utils/param-serializer-by";
137
137
 
138
- import instance from "<%~ instancePath %>";
139
- import { HttpClient, RequestParams, ContentType, HttpResponse } from "../@<%~ config.fileNames.httpClient %>";
138
+ import instance from "<%= instancePath %>";
139
+ import { HttpClient, RequestParams, ContentType, HttpResponse } from "../@<%= config.fileNames.httpClient %>";
140
140
  import { DeepOmitReadOnly } from '../@types/util-types';
141
141
 
142
142
  <% if (dataContracts.length) { %>
143
- import { <%~ dataContracts.join(", ") %> } from "../@types/<%~ config.fileNames.dataContracts %>"
143
+ import { <%= dataContracts.join(", ") %> } from "../@types/<%= config.fileNames.dataContracts %>";
144
144
  <% } %>
145
145
 
146
146
  /**
@@ -149,8 +149,6 @@ import { DeepOmitReadOnly } from '../@types/util-types';
149
149
  * 스크립트가 실행될때, 파일을 항상 새로 쓰기 때문에 파일 수정시 작성내용이 제거 될 수 있습니다.
150
150
  */
151
151
 
152
-
153
-
154
152
  export class <%= apiClassName %><SecurityDataType = unknown><% if (!config.singleHttpClient) { %> extends HttpClient<SecurityDataType> <% } %> {
155
153
  <% if(config.singleHttpClient) { %>
156
154
  http: HttpClient<SecurityDataType>;
@@ -160,33 +158,52 @@ export class <%= apiClassName %><SecurityDataType = unknown><% if (!config.singl
160
158
  }
161
159
  <% } %>
162
160
 
163
- <% routes.forEach((route) => { %>
164
- <%~ includeFile('./procedure-call.eta', { ...it, route }) %>
165
- <% }) %>
161
+ <% routes.forEach((route) => { %>
162
+ <%~ includeFile('./procedure-call.eta', { ...it, route }) %>
163
+ <% }) %>
166
164
  }
167
165
 
166
+ <% if(myConfig.includeReactQuery || myConfig.includeReactSuspenseQuery) { %>
167
+ //<%= myConfig.QUERY_HOOK_INDICATOR %>
168
168
 
169
+ <% if(myConfig.includeReactQuery) { %>
170
+ /**
171
+ * !DO NOT EDIT THIS FILE
172
+ *
173
+ * 스크립트가 실행될때, 파일을 항상 새로 쓰기 때문에 파일 수정시 작성내용이 제거 될 수 있습니다.
174
+ */
169
175
 
170
- <% if(myConfig.includeReactQuery) { %>
171
- //<%~ myConfig.QUERY_HOOK_INDICATOR %>
176
+ /**
177
+ * tok-cli.config.ts 에서 설정된 instance 경로의 axios instace 가 적용된, api 의 instance 입니다.
178
+ */
179
+ export const <%= apiInstanceName %> = new <%= apiClassName %>({ instance:instance });
172
180
 
173
- /**
174
- * !DO NOT EDIT THIS FILE
175
- *
176
- * 스크립트가 실행될때, 파일을 항상 새로 쓰기 때문에 파일 수정시 작성내용이 제거 될 수 있습니다.
177
- */
181
+ <%~ includeFile(reactQuerKeyTemplatePath, { ...it, route , dataFromApiTemplate:dataForReactHookTemplate}) %>
182
+
183
+ <% routes.forEach((route) => { %>
184
+ <%~ includeFile(reactQueryTemplatePath, { ...it, route , dataFromApiTemplate:dataForReactHookTemplate}) %>
185
+ <% }) %>
186
+ <% } %>
178
187
 
188
+ <% if(myConfig.includeReactSuspenseQuery) { %>
189
+ //<%= myConfig.USE_SUSPENSE_QUERY_HOOK_INDICATOR %>
179
190
 
180
- /**
181
- * tok-cli.config.ts 에서 설정된 instance 경로의 axios instace 가 적용된, api 의 instance 입니다.
182
- */
183
- export const <%= apiInstanceName %> = new <%= apiClassName %>({ instance:instance })
191
+ /**
192
+ * !DO NOT EDIT THIS FILE
193
+ *
194
+ * 스크립트가 실행될때, 파일을 항상 새로 쓰기 때문에 파일 수정시 작성내용이 제거 될 수 있습니다.
195
+ */
184
196
 
185
- <%~ includeFile(reactQuerKeyTemplatePath, { ...it, route , dataFromApiTemplate:dataForReactHookTemplate}) %>
186
-
187
- <% routes.forEach((route) => { %>
188
- <%~ includeFile(reactQueryTemplatePath, { ...it, route , dataFromApiTemplate:dataForReactHookTemplate}) %>
197
+ /**
198
+ * tok-cli.config.ts 에서 설정된 instance 경로의 axios instace 가 적용된, api 의 instance 입니다.
199
+ */
200
+ export const <%= apiInstanceName %> = new <%= apiClassName %>({ instance:instance });
201
+
202
+ <%~ includeFile(reactQuerKeyTemplatePath, { ...it, route , dataFromApiTemplate:dataForReactHookTemplate}) %>
203
+
204
+ <% routes.forEach((route) => { %>
205
+ <%~ includeFile(reactSuspenseQueryTemplatePath, { ...it, route , dataFromApiTemplate:dataForReactHookTemplate}) %>
189
206
  <% }) %>
207
+ <% } %>
190
208
  <% } %>
191
-
192
209
 
@@ -9,12 +9,16 @@ const dataContracts = _.map(modelTypes, "name");
9
9
  const projectRootPath = process.env.PWD;
10
10
  const myTemeplatePath = `../my`
11
11
  const reactQueryTemplatePath = `${myTemeplatePath}/react-query-hook.eta`
12
- const reactQuerKeyTemplatePath = `${myTemeplatePath}/react-query-key.eta`
12
+ const reactSuspenseQueryTemplatePath = `${myTemeplatePath}/react-query-suspense-hook.eta`;
13
+ const reactQueryKeyTemplatePath = `${myTemeplatePath}/react-query-key.eta`
13
14
 
14
15
  const apiClassName = classNameCase(route.moduleName) + 'Api';
15
16
  const paginationSets = myConfig?.paginationSets;
16
17
  const instancePath = myConfig?.instancePath || "@/configs/fetch/fetch-extend";
17
18
 
19
+ const includeReactQuery = myConfig?.includeReactQuery;
20
+ const includeReactSuspenseQuery = myConfig?.includeReactSuspenseQuery;
21
+
18
22
  const apiInstanceName = route.moduleName + "Api";
19
23
  const queryKeyName = "QUERY_KEY_" + _.upperCase(apiClassName).replace(/ /g, '_');
20
24
 
@@ -90,6 +94,8 @@ const getConfigByRoute = (route) => {
90
94
  return {
91
95
  conditions: {
92
96
  hasPagination,
97
+ includeReactQuery,
98
+ includeReactSuspenseQuery,
93
99
  isQuery,
94
100
  isMutation,
95
101
  isOptionalVariables,
@@ -122,8 +128,8 @@ const dataForReactHookTemplate = {
122
128
  };
123
129
  %>
124
130
 
125
- import { useQuery, useMutation, useInfiniteQuery, InfiniteData } from '@tanstack/react-query';
126
- import { QueryHookParams, InfiniteQueryHookParams, MutationHookParams, Parameter, RequestFnReturn } from "../@types/react-query-type";
131
+ import { useQuery, useMutation, useInfiniteQuery, useSuspenseQuery, useSuspenseInfiniteQuery, InfiniteData } from '@tanstack/react-query';
132
+ import { QueryHookParams, InfiniteQueryHookParams, MutationHookParams, Parameter, RequestFnReturn, SuspenseInfiniteQueryHookParams, SuspenseQueryHookParams } from "../@types/react-query-type";
127
133
  import { paramsSerializerBy } from "../@utils/param-serializer-by";
128
134
  import fetchExtended from "<%= instancePath %>";
129
135
 
@@ -141,13 +147,11 @@ import { <%~ dataContracts.join(", ") %> } from "../@types/<%~ config.fileNames.
141
147
  * 스크립트가 실행될때, 파일을 항상 새로 쓰기 때문에 파일 수정시 작성내용이 제거 될 수 있습니다.
142
148
  */
143
149
 
144
-
145
-
146
150
  export class <%= apiClassName %><SecurityDataType = unknown><% if (!config.singleHttpClient) { %> extends HttpClient<SecurityDataType> <% } %> {
147
- <% if (config.singleHttpClient) { %>
151
+ <% if(config.singleHttpClient) { %>
148
152
  http: HttpClient<SecurityDataType>;
149
153
 
150
- constructor(http: HttpClient<SecurityDataType>) {
154
+ constructor (http: HttpClient<SecurityDataType>) {
151
155
  this.http = http;
152
156
  }
153
157
  <% } %>
@@ -157,25 +161,47 @@ export class <%= apiClassName %><SecurityDataType = unknown><% if (!config.singl
157
161
  <% }) %>
158
162
  }
159
163
 
164
+ <% if(myConfig.includeReactQuery || myConfig.includeReactSuspenseQuery) { %>
165
+ //<%= myConfig.QUERY_HOOK_INDICATOR %>
160
166
 
161
- <% if (myConfig.includeReactQuery) { %>
162
- //<%~ myConfig.QUERY_HOOK_INDICATOR %>
167
+ <% if(myConfig.includeReactQuery) { %>
168
+ /**
169
+ * !DO NOT EDIT THIS FILE
170
+ *
171
+ * 스크립트가 실행될때, 파일을 항상 새로 쓰기 때문에 파일 수정시 작성내용이 제거 될 수 있습니다.
172
+ */
163
173
 
174
+ /**
175
+ * tok-cli.config.ts 에서 설정된 instance 경로의 axios instace 가 적용된, api 의 instance 입니다.
176
+ */
177
+ export const <%= apiInstanceName %> = new <%= apiClassName %>({ customFetch: fetchExtended });
164
178
 
165
- /**
166
- * !DO NOT EDIT THIS FILE
167
- *
168
- * 스크립트가 실행될때, 파일을 항상 새로 쓰기 때문에 파일 수정시 작성내용이 제거 될 수 있습니다.
169
- */
179
+ <%~ includeFile(reactQueryKeyTemplatePath, { ...it, route , dataFromApiTemplate:dataForReactHookTemplate}) %>
170
180
 
181
+ <% routes.forEach((route) => { %>
182
+ <%~ includeFile(reactQueryTemplatePath, { ...it, route , dataFromApiTemplate:dataForReactHookTemplate}) %>
183
+ <% }) %>
184
+ <% } %>
171
185
 
172
- /**
173
- * tok-cli.config.ts 에서 설정된 instance 경로의 fetch instance 가 적용된, api 의 instance 입니다.
174
- */
175
- export const <%= apiInstanceName %> = new <%= apiClassName %>({ customFetch: fetchExtended });
176
- <%~ includeFile(reactQuerKeyTemplatePath, { ...it, route, dataFromApiTemplate: dataForReactHookTemplate }) %>
186
+ <% if(myConfig.includeReactSuspenseQuery) { %>
187
+ //<%= myConfig.USE_SUSPENSE_QUERY_HOOK_INDICATOR %>
177
188
 
178
- <% routes.forEach((route) => { %>
179
- <%~ includeFile(reactQueryTemplatePath, { ...it, route, dataFromApiTemplate: dataForReactHookTemplate }) %>
180
- <% }) %>
189
+ /**
190
+ * !DO NOT EDIT THIS FILE
191
+ *
192
+ * 스크립트가 실행될때, 파일을 항상 새로 쓰기 때문에 파일 수정시 작성내용이 제거 될 수 있습니다.
193
+ */
194
+
195
+ /**
196
+ * tok-cli.config.ts 에서 설정된 instance 경로의 axios instace 가 적용된, api 의 instance 입니다.
197
+ */
198
+ export const <%= apiInstanceName %> = new <%= apiClassName %>({ customFetch: fetchExtended });
199
+
200
+ <%~ includeFile(reactQueryKeyTemplatePath, { ...it, route , dataFromApiTemplate:dataForReactHookTemplate}) %>
201
+
202
+ <% routes.forEach((route) => { %>
203
+ <%~ includeFile(reactSuspenseQueryTemplatePath, { ...it, route , dataFromApiTemplate:dataForReactHookTemplate}) %>
204
+ <% }) %>
205
+ <% } %>
181
206
  <% } %>
207
+
@@ -42,9 +42,10 @@ export interface ApiConfig<SecurityDataType = unknown> {
42
42
  customFetch?: typeof fetch;
43
43
  }
44
44
 
45
- export interface HttpResponse<D extends unknown, E extends unknown = unknown> extends Response {
46
- data: D;
47
- error: E;
45
+ export interface HttpResponse<D, E = unknown>
46
+ extends Response {
47
+ data: D
48
+ error: E
48
49
  }
49
50
 
50
51
  type CancelToken = Symbol | string | number;
@@ -4,10 +4,11 @@
4
4
  const { errorType } = route.response;
5
5
  const { getConfigByRoute,paginationTargetKeywords } = dataFromApiTemplate;
6
6
 
7
-
8
7
  const {
9
8
  conditions:{
10
9
  hasPagination,
10
+ includeReactQuery,
11
+ includeReactSuspenseQuery,
11
12
  isQuery,
12
13
  isMutation,
13
14
  isOptionalVariables,
@@ -45,7 +46,7 @@
45
46
  const hookKeyName = `${lowerhookVariant}Key`;
46
47
 
47
48
  const isAxiosInstance = myConfig.httpClientType === 'axios'
48
-
49
+ const fetchErrorType = `{ error: ${errorType} }`
49
50
 
50
51
  const initialPageParam = () => {
51
52
  if(typeof pagination.initialPageParam === "string") return pagination.initialPageParam;
@@ -61,111 +62,114 @@
61
62
  if(typeof pagination.getNextPageParam === "string") return pagination.getNextPageParam;
62
63
  if(typeof pagination.getNextPageParam === "function") return pagination.getNextPageParam({ apiInstanceName, functionName, pagination})
63
64
  }
64
-
65
-
66
65
  %>
67
66
 
68
- /**
69
- <%~ routeDocs.description %>
67
+ <% if (isQuery) { %>
68
+ <% if(includeReactQuery) { %>
69
+ /**
70
+ <%~ routeDocs.description %>
70
71
 
71
- * <% /* Here you can add some other JSDoc tags */ %>
72
+ * <% /* Here you can add some other JSDoc tags */ %>
72
73
 
73
- <%~ routeDocs.lines %>
74
- */
74
+ <%~ routeDocs.lines %>
75
+ */
75
76
 
76
- <% if (isQuery) { %>
77
- export const use<%~ classNameCase(functionName) %>Query = <
78
- TData = RequestFnReturn<typeof <%= apiInstanceName %>.<%~ functionName %>>,
79
- >(
80
- <%~ conditionalParamsText %>: QueryHookParams<typeof <%= apiInstanceName %>.<%~ functionName %>,
81
- <% if (isAxiosInstance) { %>
82
- AxiosError<<%~ errorType %>>
83
- <% } else { %>
84
- <%~ errorType %>
85
- <% } %>
86
- , TData>,
87
- ) => {
88
- const <%~ hookKeyName %> = <%~ queryKeyName %>.<%~ methodKey %>(<%~ `${conditionalParamsText}.variables` %>);
89
- return useQuery({
90
- <%~ hookKeyName %>,
91
- queryFn: () => <%= apiInstanceName %>.<%~ functionName %>(<%~ `${conditionalParamsText}.variables` %>),
92
- ...params?.options,
93
- });
94
- };
77
+ export const use<%~ classNameCase(functionName) %>Query = <
78
+ TData = RequestFnReturn<typeof <%= apiInstanceName %>.<%~ functionName %>>,
79
+ >(
80
+ <%~ conditionalParamsText %>: QueryHookParams<typeof <%= apiInstanceName %>.<%~ functionName %>,
81
+ <% if (isAxiosInstance) { %>
82
+ AxiosError<<%~ errorType %>>
83
+ <% } else { %>
84
+ <%~ fetchErrorType %>
85
+ <% } %>
86
+ , TData>,
87
+ ) => {
88
+ const <%~ hookKeyName %> = <%~ queryKeyName %>.<%~ methodKey %>(<%~ `${conditionalParamsText}.variables` %>);
89
+ return useQuery({
90
+ <%~ hookKeyName %>,
91
+ queryFn: () => <%= apiInstanceName %>.<%~ functionName %>(<%~ `${conditionalParamsText}.variables` %>),
92
+ ...params?.options,
93
+ });
94
+ }
95
+ <% } %>
95
96
  <% } else { %>
97
+ /**
98
+ <%~ routeDocs.description %>
99
+
100
+ * <% /* Here you can add some other JSDoc tags */ %>
101
+
102
+ <%~ routeDocs.lines %>
103
+ */
104
+
96
105
  export const use<%~ classNameCase(functionName) %>Mutation = (
97
- <%~ conditionalParamsText %>: MutationHookParams<typeof <%= apiInstanceName %>.<%~ functionName %>,
106
+ <%~ conditionalParamsText %>: MutationHookParams<typeof <%= apiInstanceName %>.<%~ functionName %>,
98
107
  <% if (isAxiosInstance) { %>
99
- AxiosError<<%~ errorType %>>
108
+ AxiosError<<%~ errorType %>>
100
109
  <% } else { %>
101
- <%~ errorType %>
110
+ <%~ fetchErrorType %>
102
111
  <% } %>
103
112
  >,
104
- ) => {
105
- const <%~ hookKeyName %> = <%~ queryKeyName %>.<%~ methodKey %>();
106
- return useMutation({
107
- <%~ hookKeyName %>,
108
- mutationFn: <%= apiInstanceName %>.<%~ functionName %>,
109
- ...params?.options,
110
- });
111
- };
113
+ ) => {
114
+ const <%~ hookKeyName %> = <%~ queryKeyName %>.<%~ methodKey %>();
115
+ return useMutation({
116
+ <%~ hookKeyName %>,
117
+ mutationFn: <%= apiInstanceName %>.<%~ functionName %>,
118
+ ...params?.options,
119
+ });
120
+ };
112
121
  <% } %>
113
122
 
114
-
115
123
  <% if (isQuery && hasPagination) { %>
116
-
117
- /**
118
- <%~ routeDocs.description %>
119
-
120
- * <% /* Here you can add some other JSDoc tags */ %>
121
-
122
- <%~ routeDocs.lines %>
123
-
124
- */
125
- export const use<%~ classNameCase(functionName) %>InfiniteQuery = <
126
- TData = InfiniteData<
127
- RequestFnReturn<typeof <%= apiInstanceName %>.<%~ functionName %>>,
128
- Parameter<typeof <%= apiInstanceName %>.<%~ functionName %>>
129
- >,
130
- >(
131
- <%~ conditionalParamsText %>: InfiniteQueryHookParams<typeof <%= apiInstanceName %>.<%~ functionName %>,
132
- <% if (isAxiosInstance) { %>
133
- AxiosError<<%~ errorType %>>
134
- <% } else { %>
135
- <%~ errorType %>
136
- <% } %>
137
- , TData>,
138
- ) => {
139
- const <%~ hookKeyName %> = <%~ queryKeyName %>.<%~ methodKey %>_INFINITE(<%~ conditionalQueryKeyParams %>);
140
-
141
- return useInfiniteQuery({
142
- <%~ hookKeyName %>,
143
- initialPageParam: <% if (initialPageParam()) { %>
144
- <%~ initialPageParam() %>
145
- <% } else { %>
146
- null
147
- <% } %>,
148
- queryFn: <% if (getNextPage()) { %>
149
- <%~ getNextPage() %>
124
+ <% if (includeReactQuery) { %>
125
+ /**
126
+ <%~ routeDocs.description %>
127
+ * <% /* Here you can add some other JSDoc tags */ %>
128
+ <%~ routeDocs.lines %>
129
+ */
130
+ export const use<%~ classNameCase(functionName) %>InfiniteQuery = <
131
+ TData = InfiniteData<
132
+ RequestFnReturn<typeof <%= apiInstanceName %>.<%~ functionName %>>,
133
+ Parameter<typeof <%= apiInstanceName %>.<%~ functionName %>>
134
+ >,
135
+ >(
136
+ <%~ conditionalParamsText %>: InfiniteQueryHookParams<typeof <%= apiInstanceName %>.<%~ functionName %>,
137
+ <% if (isAxiosInstance) { %>
138
+ AxiosError<<%~ errorType %>>
150
139
  <% } else { %>
151
- ({ pageParam }) => {
152
- return <%= apiInstanceName %>.<%~ functionName %>({
153
- ...params?.variables,
154
- query: { ...params?.variables?.query, <%~ pagination.nextKey %>: pageParam, }
155
- });
156
- }
157
- <% } %>,
158
- getNextPageParam:
159
- <% if (getNextPageParam()) { %>
160
- <%~ getNextPageParam() %>
140
+ <%~ errorType %>
141
+ <% } %>
142
+ , TData>,
143
+ ) => {
144
+ const <%~ hookKeyName %> = <%~ queryKeyName %>.<%~ methodKey %>_INFINITE(<%~ conditionalQueryKeyParams %>);
145
+ return useInfiniteQuery({
146
+ <%~ hookKeyName %>,
147
+ initialPageParam: <% if (initialPageParam()) { %>
148
+ <%~ initialPageParam() %>
149
+ <% } else { %>
150
+ null
151
+ <% } %>,
152
+ queryFn: <% if (getNextPage()) { %>
153
+ <%~ getNextPage() %>
154
+ <% } else { %>
155
+ ({ pageParam }) => {
156
+ return <%= apiInstanceName %>.<%~ functionName %>({
157
+ ...params?.variables,
158
+ query: { ...params?.variables?.query, <%~ pagination.nextKey %>: pageParam, }
159
+ });
160
+ }
161
+ <% } %>,
162
+ getNextPageParam:
163
+ <% if (getNextPageParam()) { %>
164
+ <%~ getNextPageParam() %>
161
165
  <% } else { %>
162
166
  (lastPage) => {
163
167
  const <%~ pagination.nextKey %> = lastPage.cursor ?? null;
164
168
  return <%~ pagination.nextKey %>;
165
169
  }
166
170
  <% } %>,
167
- ...params?.options,
168
- });
169
- };
170
-
171
+ ...params?.options,
172
+ });
173
+ };
174
+ <% } %>
171
175
  <% } %>
@@ -5,7 +5,7 @@ const { getConfigByRoute, queryKeyName } = dataFromApiTemplate;
5
5
  %>
6
6
 
7
7
  /**
8
- * query key 에 undfined 를 포함시키지 않기 위한 함수입니다.
8
+ * query key 에 undefined 를 포함시키지 않기 위한 함수입니다.
9
9
  */
10
10
  const isDefined = (v: unknown) => typeof v !== "undefined"
11
11
 
@@ -0,0 +1,175 @@
1
+
2
+ <%
3
+ const { utils, route, config, myConfig, dataFromApiTemplate } = it;
4
+ const { query } = route.request;
5
+ const { errorType } = route.response;
6
+ const { getConfigByRoute,paginationTargetKeywords } = dataFromApiTemplate;
7
+
8
+ const {
9
+ conditions:{
10
+ hasPagination,
11
+ includeReactQuery,
12
+ includeReactSuspenseQuery,
13
+ isQuery,
14
+ isMutation,
15
+ isOptionalVariables,
16
+ },
17
+ data: {
18
+ rawWrapperArgs,
19
+ wrapperArgs,
20
+ queryKeyName,
21
+ functionName,
22
+ apiInstanceName,
23
+ apiClassName,
24
+ hookVariant,
25
+ key,
26
+ methodKey,
27
+ pagination
28
+ },
29
+ utils: {
30
+ upperSnakeCase,
31
+ removeModuleName,
32
+ argToTmpl,
33
+ }
34
+ } = getConfigByRoute(route);
35
+
36
+ const { _, classNameCase } = utils;
37
+
38
+ const conditionalParamsText = isOptionalVariables ? "params?" : "params"
39
+ const conditionCallWithVariabels = isQuery ? `(${conditionalParamsText}.variables)` : "";
40
+ const conditionParamQueryKey = isQuery ? `,${conditionalParamsText}.variables` : "";
41
+ const conditionWrapFunc = isQuery ? "() =>" : "";
42
+ const conditionalQueryKeyParams = isQuery ? `${conditionalParamsText}.variables` : "";
43
+ const conditionalFn = isQuery ? "queryFn" : "mutationFn";
44
+
45
+ const routeDocs = includeFile("@base/route-docs", { config, route, utils });
46
+ const lowerhookVariant = _.lowerCase(hookVariant)
47
+ const hookKeyName = `${lowerhookVariant}Key`;
48
+
49
+ const isAxiosInstance = myConfig.httpClientType === 'axios'
50
+ const fetchErrorType = `{ error: ${errorType} }`
51
+
52
+ const initialPageParam = () => {
53
+ if(typeof pagination.initialPageParam === "string") return pagination.initialPageParam;
54
+ if(typeof pagination.initialPageParam === "function") return pagination.initialPageParam({ apiInstanceName, functionName, pagination})
55
+ }
56
+
57
+ const getNextPage = () => {
58
+ if(typeof pagination.getNextPage === "string") return pagination.getNextPage;
59
+ if(typeof pagination.getNextPage === "function") return pagination.getNextPage({ apiInstanceName, functionName, pagination})
60
+ }
61
+
62
+ const getNextPageParam = () => {
63
+ if(typeof pagination.getNextPageParam === "string") return pagination.getNextPageParam;
64
+ if(typeof pagination.getNextPageParam === "function") return pagination.getNextPageParam({ apiInstanceName, functionName, pagination})
65
+ }
66
+ %>
67
+
68
+ <% if (isQuery) { %>
69
+ <% if (includeReactSuspenseQuery) { %>
70
+ /**
71
+ <%~ routeDocs.description %>
72
+
73
+ * <% /* Here you can add some other JSDoc tags */ %>
74
+
75
+ <%~ routeDocs.lines %>
76
+ */
77
+
78
+ export const use<%~ classNameCase(functionName) %>SuspenseQuery = <
79
+ TData = RequestFnReturn<typeof <%= apiInstanceName %>.<%~ functionName %>>,
80
+ >(
81
+ <%~ conditionalParamsText %>: SuspenseQueryHookParams<typeof <%= apiInstanceName %>.<%~ functionName %>,
82
+ <% if (isAxiosInstance) { %>
83
+ AxiosError<<%~ errorType %>>
84
+ <% } else { %>
85
+ <%~ fetchErrorType %>
86
+ <% } %>
87
+ , TData>,
88
+ ) => {
89
+ const <%~ hookKeyName %> = <%~ queryKeyName %>.<%~ methodKey %>(<%~ `${conditionalParamsText}.variables` %>);
90
+ return useSuspenseQuery({
91
+ <%~ hookKeyName %>,
92
+ queryFn: () => <%= apiInstanceName %>.<%~ functionName %>(<%~ `${conditionalParamsText}.variables` %>),
93
+ ...params?.options,
94
+ });
95
+ };
96
+
97
+
98
+ /**
99
+ * @name <%~ _.camelCase(functionName) %>QueryOptions
100
+ * @description 이 옵션은 Suspense 기반의 병렬 데이터 쿼리를 위한 설정입니다.
101
+ * `useSuspenseQueries`를 사용하여 여러 쿼리를 병렬로 처리할 때 활용하세요.
102
+ */
103
+
104
+ export const <%~ _.camelCase(functionName) %>SuspenseQueryOptions = <
105
+ TData = RequestFnReturn<typeof <%= apiInstanceName %>.<%~ functionName %>>,
106
+ >(
107
+ <%~ conditionalParamsText %>: SuspenseQueryHookParams<typeof <%= apiInstanceName %>.<%~ functionName %>,
108
+ <% if (isAxiosInstance) { %>
109
+ unknown
110
+ <% } else { %>
111
+ <%~ fetchErrorType %>
112
+ <% } %>
113
+ , TData>,
114
+ ) => {
115
+ const queryKey = <%~ queryKeyName %>.<%~ methodKey %>(<%~ `${conditionalParamsText}.variables` %>);
116
+ return {
117
+ queryKey,
118
+ queryFn: () => <%= apiInstanceName %>.<%~ functionName %>(<%~ `${conditionalParamsText}.variables` %>),
119
+ ...params?.options,
120
+ };
121
+ };
122
+ <% } %>
123
+
124
+ <% if (isQuery && hasPagination) { %>
125
+ /**
126
+ <%~ routeDocs.description %>
127
+ * <% /* Here you can add some other JSDoc tags */ %>
128
+ <%~ routeDocs.lines %>
129
+ */
130
+ export const use<%~ classNameCase(functionName) %>InfiniteSuspenseQuery = <
131
+ TData = InfiniteData<
132
+ RequestFnReturn<typeof <%= apiInstanceName %>.<%~ functionName %>>,
133
+ Parameter<typeof <%= apiInstanceName %>.<%~ functionName %>>
134
+ >,
135
+ >(
136
+ <%~ conditionalParamsText %>: SuspenseInfiniteQueryHookParams<typeof <%= apiInstanceName %>.<%~ functionName %>,
137
+ <% if (isAxiosInstance) { %>
138
+ AxiosError<<%~ errorType %>>
139
+ <% } else { %>
140
+ <%~ errorType %>
141
+ <% } %>
142
+ , TData>,
143
+ ) => {
144
+ const <%~ hookKeyName %> = <%~ queryKeyName %>.<%~ methodKey %>_INFINITE(<%~ conditionalQueryKeyParams %>);
145
+ return useSuspenseInfiniteQuery({
146
+ <%~ hookKeyName %>,
147
+ initialPageParam: <% if (initialPageParam()) { %>
148
+ <%~ initialPageParam() %>
149
+ <% } else { %>
150
+ null
151
+ <% } %>,
152
+ queryFn: <% if (getNextPage()) { %>
153
+ <%~ getNextPage() %>
154
+ <% } else { %>
155
+ ({ pageParam }) => {
156
+ return <%= apiInstanceName %>.<%~ functionName %>({
157
+ ...params?.variables,
158
+ query: { ...params?.variables?.query, <%~ pagination.nextKey %>: pageParam, }
159
+ });
160
+ }
161
+ <% } %>,
162
+ getNextPageParam:
163
+ <% if (getNextPageParam()) { %>
164
+ <%~ getNextPageParam() %>
165
+ <% } else { %>
166
+ (lastPage) => {
167
+ const <%~ pagination.nextKey %> = lastPage.cursor ?? null;
168
+ return <%~ pagination.nextKey %>;
169
+ }
170
+ <% } %>,
171
+ ...params?.options,
172
+ });
173
+ };
174
+ <% } %>
175
+ <% } %>
@@ -1,173 +1,100 @@
1
1
  <%
2
- const { utils, route, config, myConfig, dataFromApiTemplate } = it;
3
- const { query } = route.request;
4
- const { errorType } = route.response;
5
- const { getConfigByRoute,paginationTargetKeywords } = dataFromApiTemplate;
6
-
7
-
8
- const {
9
- conditions:{
10
- hasPagination,
11
- isQuery,
12
- isMutation,
13
- isOptionalVariables,
14
- },
15
- data: {
16
- rawWrapperArgs,
17
- wrapperArgs,
18
- queryKeyName,
19
- functionName,
20
- apiInstanceName,
21
- apiClassName,
22
- hookVariant,
23
- key,
24
- methodKey,
25
- pagination
26
- },
27
- utils: {
28
- upperSnakeCase,
29
- removeModuleName,
30
- argToTmpl,
31
- }
32
- } = getConfigByRoute(route);
33
-
34
- const { _, classNameCase } = utils;
35
-
36
- const conditionalParamsText = isOptionalVariables ? "params?" : "params"
37
- const conditionCallWithVariabels = isQuery ? `(${conditionalParamsText}.variables)` : "";
38
- const conditionParamQueryKey = isQuery ? `,${conditionalParamsText}.variables` : "";
39
- const conditionWrapFunc = isQuery ? "() =>" : "";
40
- const conditionalQueryKeyParams = isQuery ? `${conditionalParamsText}.variables` : "";
41
- const conditionalFn = isQuery ? "queryFn" : "mutationFn";
42
-
43
- const routeDocs = includeFile("@base/route-docs", { config, route, utils });
44
- const lowerhookVariant = _.lowerCase(hookVariant)
45
- const hookKeyName = `${lowerhookVariant}Key`;
46
-
47
- const isAxiosInstance = myConfig.httpClientType === 'axios'
48
- const fetchErrorType = `{ error: ${errorType} }`
49
-
50
-
51
-
52
- const initialPageParam = () => {
53
- if(typeof pagination.initialPageParam === "string") return pagination.initialPageParam;
54
- if(typeof pagination.initialPageParam === "function") return pagination.initialPageParam({ apiInstanceName, functionName, pagination})
55
- }
56
-
57
- const getNextPage = () => {
58
- if(typeof pagination.getNextPage === "string") return pagination.getNextPage;
59
- if(typeof pagination.getNextPage === "function") return pagination.getNextPage({ apiInstanceName, functionName, pagination})
60
- }
61
-
62
- const getNextPageParam = () => {
63
- if(typeof pagination.getNextPageParam === "string") return pagination.getNextPageParam;
64
- if(typeof pagination.getNextPageParam === "function") return pagination.getNextPageParam({ apiInstanceName, functionName, pagination})
65
- }
66
-
67
-
68
- %>
69
-
70
- /**
71
- <%~ routeDocs.description %>
72
-
73
- * <% /* Here you can add some other JSDoc tags */ %>
74
-
75
- <%~ routeDocs.lines %>
76
- */
77
-
78
- <% if (isQuery) { %>
79
- export const use<%~ classNameCase(functionName) %>Query = <
80
- TData = RequestFnReturn<typeof <%= apiInstanceName %>.<%~ functionName %>>,
81
- >(
82
- <%~ conditionalParamsText %>: QueryHookParams<typeof <%= apiInstanceName %>.<%~ functionName %>,
83
- <% if (isAxiosInstance) { %>
84
- AxiosError<<%~ errorType %>>
85
- <% } else { %>
86
- <%~ fetchErrorType %>
87
- <% } %>
88
- , TData>,
89
- ) => {
90
- const <%~ hookKeyName %> = <%~ queryKeyName %>.<%~ methodKey %>(<%~ `${conditionalParamsText}.variables` %>);
91
- return useQuery({
92
- <%~ hookKeyName %>,
93
- queryFn: () => <%= apiInstanceName %>.<%~ functionName %>(<%~ `${conditionalParamsText}.variables` %>),
94
- ...params?.options,
95
- });
96
- };
97
- <% } else { %>
98
- export const use<%~ classNameCase(functionName) %>Mutation = (
99
- <%~ conditionalParamsText %>: MutationHookParams<typeof <%= apiInstanceName %>.<%~ functionName %>,
100
- <% if (isAxiosInstance) { %>
101
- AxiosError<<%~ errorType %>>
102
- <% } else { %>
103
- <%~ fetchErrorType %>
104
- <% } %>
105
- >,
106
- ) => {
107
- const <%~ hookKeyName %> = <%~ queryKeyName %>.<%~ methodKey %>();
108
- return useMutation({
109
- <%~ hookKeyName %>,
110
- mutationFn: <%= apiInstanceName %>.<%~ functionName %>,
111
- ...params?.options,
112
- });
113
- };
114
- <% } %>
115
-
116
-
117
- <% if (isQuery && hasPagination) { %>
118
-
119
- /**
120
- <%~ routeDocs.description %>
121
-
122
- * <% /* Here you can add some other JSDoc tags */ %>
123
-
124
- <%~ routeDocs.lines %>
125
-
2
+ const { myConfig } = it;
3
+ const errorType = myConfig.httpClientType === 'axios' ? 'AxiosError<any>' : 'any';
4
+ %>
5
+ import { AxiosError } from 'axios';
6
+
7
+ import {
8
+ UseInfiniteQueryOptions,
9
+ UseMutationOptions,
10
+ UseQueryOptions,
11
+ UseSuspenseQueryOptions,
12
+ UseSuspenseInfiniteQueryOptions,
13
+ } from '@tanstack/react-query';
14
+
15
+
16
+ /**
17
+ * !DO NOT EDIT THIS FILE
18
+ *
19
+ * 스크립트가 실행될때, 파일을 항상 새로 쓰기 때문에 파일 수정시 작성내용이 제거 될 수 있습니다.
126
20
  */
127
- export const use<%~ classNameCase(functionName) %>InfiniteQuery = <
128
- TData = InfiniteData<
129
- RequestFnReturn<typeof <%= apiInstanceName %>.<%~ functionName %>>,
130
- Parameter<typeof <%= apiInstanceName %>.<%~ functionName %>>
131
- >,
132
- >(
133
- <%~ conditionalParamsText %>: InfiniteQueryHookParams<typeof <%= apiInstanceName %>.<%~ functionName %>,
134
- <% if (isAxiosInstance) { %>
135
- AxiosError<<%~ errorType %>>
136
- <% } else { %>
137
- <%~ errorType %>
138
- <% } %>
139
- , TData>,
140
- ) => {
141
- const <%~ hookKeyName %> = <%~ queryKeyName %>.<%~ methodKey %>_INFINITE(<%~ conditionalQueryKeyParams %>);
142
21
 
143
- return useInfiniteQuery({
144
- <%~ hookKeyName %>,
145
- initialPageParam: <% if (initialPageParam()) { %>
146
- <%~ initialPageParam() %>
147
- <% } else { %>
148
- null
149
- <% } %>,
150
- queryFn: <% if (getNextPage()) { %>
151
- <%~ getNextPage() %>
152
- <% } else { %>
153
- ({ pageParam }) => {
154
- return <%= apiInstanceName %>.<%~ functionName %>({
155
- ...params?.variables,
156
- query: { ...params?.variables?.query, <%~ pagination.nextKey %>: pageParam, }
157
- });
158
- }
159
- <% } %>,
160
- getNextPageParam:
161
- <% if (getNextPageParam()) { %>
162
- <%~ getNextPageParam() %>
163
- <% } else { %>
164
- (lastPage) => {
165
- const <%~ pagination.nextKey %> = lastPage.cursor ?? null;
166
- return <%~ pagination.nextKey %>;
167
- }
168
- <% } %>,
169
- ...params?.options,
170
- });
22
+
23
+
24
+ export type QueryHookParams<
25
+ T extends CustomRequestFn,
26
+ Error = <%~ errorType %>,
27
+ TData = RequestFnReturn<T>,
28
+ OriginData = RequestFnReturn<T>,
29
+ Variables = Parameter<T>,
30
+ > = {
31
+ options?: Omit<
32
+ UseQueryOptions<OriginData, Error, TData>,
33
+ 'queryKey' | 'queryFn'
34
+ >;
35
+ } & OptionalVariables<Variables>;
36
+
37
+ export type InfiniteQueryHookParams<
38
+ T extends CustomRequestFn,
39
+ Error = <%~ errorType %>,
40
+ TData = RequestFnReturn<T>,
41
+ OriginData = RequestFnReturn<T>,
42
+ Variables = Parameter<T>,
43
+ > = {
44
+ options?: Partial<
45
+ Omit<
46
+ UseInfiniteQueryOptions<OriginData, Error, TData, OriginData, any, any>,
47
+ 'queryKey' | 'queryFn'
48
+ >
49
+ >;
50
+ } & OptionalVariables<Variables>;
51
+
52
+ export type MutationHookParams<
53
+ T extends CustomRequestFn,
54
+ Error = <%~ errorType %>,
55
+ Data = RequestFnReturn<T>,
56
+ Variables = Parameter<T>,
57
+ > = {
58
+ options?: Omit<
59
+ UseMutationOptions<Data, Error, Variables>,
60
+ 'mutationFn' | 'mutationKey'
61
+ >;
171
62
  };
172
63
 
173
- <% } %>
64
+ export type SuspenseQueryHookParams<
65
+ T extends CustomRequestFn,
66
+ Error = <%~ errorType %>,
67
+ TData = RequestFnReturn<T>,
68
+ OriginData = RequestFnReturn<T>,
69
+ Variables = Parameter<T>,
70
+ > = {
71
+ options?: Omit<
72
+ UseSuspenseQueryOptions<OriginData, Error, TData>,
73
+ 'queryKey' | 'queryFn'
74
+ >;
75
+ } & OptionalVariables<Variables>;
76
+
77
+ export type SuspenseInfiniteQueryHookParams<
78
+ T extends CustomRequestFn,
79
+ Error = <%~ errorType %>,
80
+ TData = RequestFnReturn<T>,
81
+ OriginData = RequestFnReturn<T>,
82
+ Variables = Parameter<T>,
83
+ > = {
84
+ options?: Partial<
85
+ Omit<
86
+ UseSuspenseInfiniteQueryOptions<OriginData, Error, TData, OriginData, any, any>,
87
+ 'queryKey' | 'queryFn'
88
+ >
89
+ >;
90
+ } & OptionalVariables<Variables>;
91
+
92
+ export type OptionalVariables<T> = undefined extends T
93
+ ? { variables?: T }
94
+ : { variables: T };
95
+
96
+ export type Parameter<T> = T extends (param: infer U) => any ? U : never;
97
+
98
+ export type CustomRequestFn = (variables?: any) => Promise<any>;
99
+
100
+ export type RequestFnReturn<T extends CustomRequestFn> = Awaited<ReturnType<T>>;