@acrool/rtk-query-codegen-openapi 1.4.0-alpha.0 → 1.4.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@acrool/rtk-query-codegen-openapi",
3
- "version": "1.4.0-alpha.0",
3
+ "version": "1.4.0-alpha.1",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "module": "lib/index.mjs",
@@ -21,6 +21,37 @@ function renameIdentifier(node: ts.Node, oldName: string, newName: string): ts.N
21
21
  ]).transformed[0];
22
22
  }
23
23
 
24
+ /**
25
+ * 判斷 TypeAliasDeclaration 是否為 string literal union(即 OpenAPI enum)
26
+ * 例如: type ETaskCategory = "feat" | "fix" | "refactor"
27
+ */
28
+ function isStringEnumType(node: ts.TypeAliasDeclaration): string[] | null {
29
+ if (!ts.isUnionTypeNode(node.type)) return null;
30
+
31
+ const members: string[] = [];
32
+ for (const member of node.type.types) {
33
+ if (ts.isLiteralTypeNode(member) && ts.isStringLiteral(member.literal)) {
34
+ members.push(member.literal.text);
35
+ } else {
36
+ return null; // 含有非 string literal 的成員,不是 enum
37
+ }
38
+ }
39
+ return members.length > 0 ? members : null;
40
+ }
41
+
42
+ /**
43
+ * 將 string union type 轉換為 enum 宣告字串
44
+ * 例如: export enum ETaskCategory { Feat = "feat", Fix = "fix", Refactor = "refactor" }
45
+ */
46
+ function generateEnumDeclaration(name: string, members: string[]): string {
47
+ const enumMembers = members.map(value => {
48
+ // enum key: 首字母大寫的 camelCase
49
+ const key = value.charAt(0).toUpperCase() + value.slice(1);
50
+ return ` ${key} = "${value}"`;
51
+ });
52
+ return `export enum ${name} {\n${enumMembers.join(',\n')}\n}`
53
+ }
54
+
24
55
  /**
25
56
  * 產生 component-schema.ts 內容
26
57
  * @param interfaces
@@ -53,6 +84,15 @@ export function generateComponentSchemaFile(
53
84
  return;
54
85
  }
55
86
 
87
+ // 偵測 string union type 並轉換為 enum
88
+ if (ts.isTypeAliasDeclaration(node)) {
89
+ const enumMembers = isStringEnumType(node);
90
+ if (enumMembers) {
91
+ renamedInterfaces.push(generateEnumDeclaration(pascalCaseName, enumMembers));
92
+ return;
93
+ }
94
+ }
95
+
56
96
  // 重新命名節點
57
97
  const renamedNode = renameIdentifier(node, originalName, pascalCaseName);
58
98
  const printed = printer.printNode(ts.EmitHint.Unspecified, renamedNode, resultFile);
@@ -72,6 +72,34 @@ export interface EndpointInfo {
72
72
  summary: string;
73
73
  }
74
74
 
75
+ /**
76
+ * 判斷 TypeAliasDeclaration 是否為 string literal union(即 OpenAPI enum)
77
+ */
78
+ function isStringEnumType(node: ts.TypeAliasDeclaration): string[] | null {
79
+ if (!ts.isUnionTypeNode(node.type)) return null;
80
+
81
+ const members: string[] = [];
82
+ for (const member of node.type.types) {
83
+ if (ts.isLiteralTypeNode(member) && ts.isStringLiteral(member.literal)) {
84
+ members.push(member.literal.text);
85
+ } else {
86
+ return null;
87
+ }
88
+ }
89
+ return members.length > 0 ? members : null;
90
+ }
91
+
92
+ /**
93
+ * 將 string union type 轉換為 enum 宣告字串
94
+ */
95
+ function generateEnumDeclaration(name: string, members: string[]): string {
96
+ const enumMembers = members.map(value => {
97
+ const key = value.charAt(0).toUpperCase() + value.slice(1);
98
+ return ` ${key} = "${value}"`;
99
+ });
100
+ return `export enum ${name} {\n${enumMembers.join(',\n')}\n}`;
101
+ }
102
+
75
103
  /**
76
104
  * Group-local schema 類型生成選項
77
105
  */
@@ -146,6 +174,16 @@ export function generateTypesFile(
146
174
 
147
175
  for (const [originalName, node] of Object.entries(localSchemaInterfaces)) {
148
176
  const pascalCaseName = toPascalCase(originalName);
177
+
178
+ // 偵測 string union type 並轉換為 enum
179
+ if (ts.isTypeAliasDeclaration(node)) {
180
+ const enumMembers = isStringEnumType(node);
181
+ if (enumMembers) {
182
+ localTypeDefs.push(generateEnumDeclaration(pascalCaseName, enumMembers));
183
+ continue;
184
+ }
185
+ }
186
+
149
187
  // 重新命名節點中的宣告名稱
150
188
  let transformedNode = renameIdentifier(node, originalName, pascalCaseName);
151
189
  // 將引用到 shared schema 的標識符加上 Schema. 前綴