@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/lib/bin/cli.mjs +40 -34
- package/lib/bin/cli.mjs.map +1 -1
- package/lib/index.js +56 -0
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +56 -0
- package/lib/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/generators/component-schema-generator.ts +40 -0
- package/src/generators/types-generator.ts +38 -0
package/package.json
CHANGED
|
@@ -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. 前綴
|