@acrool/rtk-query-codegen-openapi 1.0.6-alpha.0 → 1.1.0-alpha.3

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.
@@ -13,6 +13,7 @@ export function generateRtkQueryFile(endpointInfos: Array<{
13
13
  isVoidArg: boolean;
14
14
  summary: string;
15
15
  contentType: string;
16
+ hasRequestBody: boolean;
16
17
  }>, options: GenerationOptions) {
17
18
 
18
19
  const { groupKey } = options;
@@ -25,15 +26,40 @@ export function generateRtkQueryFile(endpointInfos: Array<{
25
26
  const methodType = info.isQuery ? 'query' : 'mutation';
26
27
  const argType = info.isVoidArg ? 'void' : `${httpClientTypeName}<${info.argTypeName}>`;
27
28
 
29
+ // 處理 path parameters - 替換 {id} 為 ${queryArg.variables.id}
30
+ let urlPath = info.path;
31
+ if (info.pathParams && info.pathParams.length > 0) {
32
+ info.pathParams.forEach((param: any) => {
33
+ urlPath = urlPath.replace(`{${param.name}}`, `\${queryArg.variables.${param.name}}`);
34
+ });
35
+ // 使用模板字符串
36
+ urlPath = '`' + urlPath + '`';
37
+ } else {
38
+ // 使用普通字符串
39
+ urlPath = `"${urlPath}"`;
40
+ }
41
+
42
+ // 處理 query parameters
43
+ let paramsSection = '';
44
+ if (info.queryParams && info.queryParams.length > 0) {
45
+ const paramsLines = info.queryParams.map((param: any) =>
46
+ ` ${param.name}: queryArg.variables.${param.name},`
47
+ ).join('\n');
48
+ paramsSection = `
49
+ params: {
50
+ ${paramsLines}
51
+ },`;
52
+ }
53
+
28
54
  return ` ${info.operationName}: build.${methodType}<
29
55
  ${info.responseTypeName},
30
56
  ${argType}
31
57
  >({
32
58
  query: (queryArg) => ({
33
- url: "${info.path}",
59
+ url: ${urlPath},
34
60
  method: "${info.verb.toUpperCase()}",
35
- contentType: "${info.contentType}",${info.isVoidArg ? '' : `
36
- body: queryArg.variables.body,`}${info.isVoidArg ? '' : `
61
+ contentType: "${info.contentType}",${paramsSection}${info.hasRequestBody ? `
62
+ body: queryArg.variables.body,` : ''}${info.isVoidArg ? '' : `
37
63
  fetchOptions: queryArg?.fetchOptions,`}
38
64
  }),
39
65
  }),`;
@@ -79,22 +105,22 @@ ${endpoints}
79
105
 
80
106
  export const {
81
107
  ${endpointInfos.map(info => {
82
- const capitalizedOperationName = info.operationName.charAt(0).toUpperCase() + info.operationName.slice(1);
83
- if (info.isQuery) {
84
- // For queries, generate both regular and lazy hooks if useLazyQueries is enabled
85
- const regularHook = `use${capitalizedOperationName}Query`;
86
- if (options.useLazyQueries) {
87
- const lazyHook = `useLazy${capitalizedOperationName}Query`;
88
- return ` ${regularHook},\n ${lazyHook},`;
108
+ const capitalizedOperationName = info.operationName.charAt(0).toUpperCase() + info.operationName.slice(1);
109
+ if (info.isQuery) {
110
+ // For queries, generate both regular and lazy hooks if useLazyQueries is enabled
111
+ const regularHook = `use${capitalizedOperationName}Query`;
112
+ if (options.useLazyQueries) {
113
+ const lazyHook = `useLazy${capitalizedOperationName}Query`;
114
+ return ` ${regularHook},\n ${lazyHook},`;
115
+ } else {
116
+ return ` ${regularHook},`;
117
+ }
89
118
  } else {
90
- return ` ${regularHook},`;
119
+ // For mutations, only generate regular hook
120
+ const mutationHook = `use${capitalizedOperationName}Mutation`;
121
+ return ` ${mutationHook},`;
91
122
  }
92
- } else {
93
- // For mutations, only generate regular hook
94
- const mutationHook = `use${capitalizedOperationName}Mutation`;
95
- return ` ${mutationHook},`;
96
- }
97
- }).join('\n')}
123
+ }).join('\n')}
98
124
  } = injectedRtkApi;
99
125
 
100
126
  export default injectedRtkApi;
@@ -19,6 +19,7 @@ export interface EndpointInfo {
19
19
  isVoidArg: boolean;
20
20
  summary: string;
21
21
  contentType: string;
22
+ hasRequestBody: boolean;
22
23
  }
23
24
 
24
25
  /**
@@ -65,7 +66,7 @@ export class EndpointInfoExtractor {
65
66
  const summary = operation.summary || `${verb.toUpperCase()} ${path}`;
66
67
 
67
68
  // 解析參數
68
- const { queryParams, pathParams, isVoidArg } = this.extractParameters(operationDefinition);
69
+ const { queryParams, pathParams, isVoidArg, hasRequestBody } = this.extractParameters(operationDefinition);
69
70
 
70
71
  // 提取 content type
71
72
  const contentType = this.extractContentType(operation);
@@ -82,7 +83,8 @@ export class EndpointInfoExtractor {
82
83
  pathParams,
83
84
  isVoidArg,
84
85
  summary,
85
- contentType
86
+ contentType,
87
+ hasRequestBody
86
88
  };
87
89
  }
88
90
 
@@ -97,20 +99,24 @@ export class EndpointInfoExtractor {
97
99
  const operationParameters = this.resolveArray(operation.parameters);
98
100
  const pathItemParameters = this.resolveArray(pathItem.parameters)
99
101
  .filter((pp) => !operationParameters.some((op) => op.name === pp.name && op.in === pp.in));
100
-
102
+
101
103
  const allParameters = supportDeepObjects([...pathItemParameters, ...operationParameters])
102
104
  .filter((param) => param.in !== 'header');
103
105
 
104
106
  const queryParams = allParameters.filter(param => param.in === 'query');
105
107
  const pathParams = allParameters.filter(param => param.in === 'path');
106
108
 
109
+ // 檢查是否有 request body
110
+ const hasRequestBody = !!operation.requestBody;
111
+
107
112
  // 檢查是否為 void 類型參數
108
113
  const isVoidArg = queryParams.length === 0 && pathParams.length === 0 && !operation.requestBody;
109
114
 
110
115
  return {
111
116
  queryParams,
112
117
  pathParams,
113
- isVoidArg
118
+ isVoidArg,
119
+ hasRequestBody
114
120
  };
115
121
  }
116
122
 
@@ -24,8 +24,17 @@ export class OpenApiParserService {
24
24
  */
25
25
  initialize(): void {
26
26
  if (this.apiGen.spec.components?.schemas) {
27
+ // 原因:oazapfts 會優先使用 schema.title 作為類型名稱,但應該使用 schema key
28
+ // 這只在記憶體中修改,不影響原始 OpenAPI 文件
29
+ Object.keys(this.apiGen.spec.components.schemas).forEach(schemaName => {
30
+ const schema = this.apiGen.spec.components!.schemas![schemaName];
31
+ if (schema && typeof schema === 'object' && 'title' in schema) {
32
+ delete schema.title;
33
+ }
34
+ });
35
+
27
36
  this.apiGen.preprocessComponents(this.apiGen.spec.components.schemas);
28
-
37
+
29
38
  // 手動為每個 schema 生成 type alias
30
39
  Object.keys(this.apiGen.spec.components.schemas).forEach(schemaName => {
31
40
  try {