@bitstack/ng-query-codegen-openapi 0.0.30 → 0.0.31-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/src/types.ts CHANGED
@@ -3,22 +3,13 @@ import type { OpenAPIV3 } from 'openapi-types';
3
3
  import ts from 'typescript';
4
4
 
5
5
  // 重新匯出服務相關類型
6
- export type {
7
- GroupConfig,
8
- GroupInfo
9
- } from './services/group-service';
6
+ export type { GroupConfig, GroupInfo } from './services/group-service';
10
7
 
11
- export type {
12
- FileWriteResult
13
- } from './services/file-writer-service';
14
-
15
- export type {
16
- EndpointCacheKey
17
- } from './services/unified-code-generator';
8
+ export type { FileWriteResult } from './services/file-writer-service';
18
9
 
19
10
  export type {
20
11
  UnifiedGenerationOptions as EndpointGenerationOptions,
21
- UnifiedGenerationResult as EndpointGenerationResult
12
+ UnifiedGenerationResult as EndpointGenerationResult,
22
13
  } from './services/unified-code-generator';
23
14
 
24
15
  export type OperationDefinition = {
@@ -69,12 +60,12 @@ export interface CommonOptions {
69
60
  importName: string;
70
61
  };
71
62
  /**
72
- * HttpClient for WebApiConfiguration import
63
+ * HTTP client configuration for API calls
73
64
  * defaults to { file: "@core/httpClient/webapi/webapi-http-client.providers", importName: "WEBAPI_HTTP_CLIENT" }
74
65
  */
75
66
  httpClient?: {
76
67
  file: string;
77
- importName: string;
68
+ importReturnTypeName: string; // 用於指定別名導入,例如 IRestFulEndpointsQueryReturn
78
69
  };
79
70
  /**
80
71
  * defaults to "enhancedApi"
@@ -94,9 +85,9 @@ export interface CommonOptions {
94
85
  operationNameSuffix?: string;
95
86
  /**
96
87
  * defaults to `false`
97
- * `true` will generate hooks for queries and mutations, but no lazyQueries
88
+ * `true` will generate lazy query hooks (useLazy prefix) for query endpoints
98
89
  */
99
- hooks?: boolean | { queries: boolean; lazyQueries: boolean; mutations: boolean };
90
+ useLazyQueries?: boolean;
100
91
  /**
101
92
  * defaults to false
102
93
  * `true` will generate a union type for `undefined` properties like: `{ id?: string | undefined }` instead of `{ id?: string }`
@@ -173,11 +164,6 @@ export interface OutputFileOptions extends Partial<CommonOptions> {
173
164
  filterEndpoints?: EndpointMatcher;
174
165
  endpointOverrides?: EndpointOverrides[];
175
166
  queryMatch?: (method: string, path: string) => boolean;
176
- /**
177
- * defaults to false
178
- * If passed as true it will generate TS enums instead of union of strings
179
- */
180
- useEnumType?: boolean;
181
167
  sharedTypesFile?: string;
182
168
  /**
183
169
  * groupKey for service class naming, e.g., "room" -> "RoomService"
@@ -204,30 +190,23 @@ export type ConfigFile =
204
190
  | Id<
205
191
  Omit<CommonOptions, 'outputFile'> & {
206
192
  // outputFiles: { [outputFile: string]: Omit<OutputFileOptions, 'outputFile'> };
207
- outputFiles: OutputFilesConfig
193
+ outputFiles: OutputFilesConfig;
208
194
  }
209
195
  >;
210
196
 
211
197
  export type GenerateApiResult = {
212
198
  operationNames: string[];
199
+ tags: string[]; // 收集到的所有 tags
213
200
  files: {
214
201
  types: string;
215
- apiService: string;
216
- queryService: string;
202
+ queryService: string; // RTK Query generated file
217
203
  index: string;
204
+ enhanceEndpoints?: string; // RTK Query enhance endpoints file
218
205
  commonTypes?: string;
219
- cacheKeys?: string;
220
206
  componentSchema?: string;
221
- allEndpointCacheKeys?: Array<{
222
- operationName: string
223
- queryKeyName: string
224
- groupKey: string
225
- }>;
226
207
  };
227
208
  };
228
209
 
229
-
230
-
231
210
  export type QueryArgDefinition = {
232
211
  name: string;
233
212
  originalName: string;
@@ -236,13 +215,13 @@ export type QueryArgDefinition = {
236
215
  param?: OpenAPIV3.ParameterObject;
237
216
  } & (
238
217
  | {
239
- origin: 'param';
240
- param: OpenAPIV3.ParameterObject;
241
- }
218
+ origin: 'param';
219
+ param: OpenAPIV3.ParameterObject;
220
+ }
242
221
  | {
243
- origin: 'body';
244
- body: OpenAPIV3.RequestBodyObject;
245
- }
246
- );
222
+ origin: 'body';
223
+ body: OpenAPIV3.RequestBodyObject;
224
+ }
225
+ );
247
226
 
248
- export type QueryArgDefinitions = Record<string, QueryArgDefinition>;
227
+ export type QueryArgDefinitions = Record<string, QueryArgDefinition>;
@@ -1,112 +0,0 @@
1
- import type { GenerationOptions } from '../types';
2
-
3
- export function generateApiServiceFile(endpointInfos: Array<{
4
- operationName: string;
5
- argTypeName: string;
6
- responseTypeName: string;
7
- isQuery: boolean;
8
- verb: string;
9
- path: string;
10
- queryKeyName: string;
11
- queryParams: any[];
12
- pathParams: any[];
13
- isVoidArg: boolean;
14
- summary: string;
15
- }>, options: GenerationOptions) {
16
-
17
- const { apiConfiguration, httpClient, groupKey } = options;
18
-
19
- // 確定服務名稱,使用業務名稱
20
- const apiServiceClassName = groupKey ?
21
- `${groupKey.charAt(0).toUpperCase() + groupKey.slice(1)}ApiService` :
22
- 'ApiService';
23
-
24
- return `/* eslint-disable */
25
- // [Warning] Generated automatically - do not edit manually
26
-
27
- import { ${httpClient!.importName} } from '${httpClient!.file}';
28
- import { Injectable, inject } from '@angular/core';
29
- import { Observable } from 'rxjs';
30
- import { ${apiConfiguration!.importName} } from '${apiConfiguration!.file}';
31
- import { RequestOptions, IRestFulEndpointsQueryReturn } from '../common-types';
32
- import { withoutUndefined } from '../utils';
33
- import {${endpointInfos.map(info => ` ${info.argTypeName}, ${info.responseTypeName}`).join(',')} } from './types';
34
-
35
- @Injectable({
36
- providedIn: 'root',
37
- })
38
- export class ${apiServiceClassName} {
39
- private config = inject(${apiConfiguration!.importName});
40
- private http = inject(${httpClient!.importName});
41
-
42
- ${endpointInfos.map(info => {
43
- const isGet = info.verb.toUpperCase() === 'GET';
44
- const hasArgs = info.argTypeName !== 'VoidApiArg';
45
-
46
- // 生成 URL 模板字面量,直接替換路徑參數
47
- const generateUrlTemplate = (path: string) => {
48
- const hasPathParams = path.includes('{');
49
- if (hasPathParams && hasArgs) {
50
- // 將 {paramName} 替換為 ${args.variables.paramName}
51
- const urlTemplate = path.replace(/\{([^}]+)\}/g, '${args.variables.$1}');
52
- return `\`\${this.config.rootUrl}${urlTemplate}\``;
53
- } else {
54
- return `\`\${this.config.rootUrl}${path}\``;
55
- }
56
- };
57
-
58
- const hasQueryParams = info.queryParams.length > 0;
59
- const hasBody = !isGet && hasArgs && !info.isVoidArg;
60
-
61
- // 生成 HTTP 請求選項
62
- const generateRequestOptions = () => {
63
- const options = [
64
- '...args.fetchOptions',
65
- ];
66
-
67
- // 添加 Content-Type header,特別是對於有 body 的請求
68
- if (hasBody || !isGet) {
69
- options.push(`headers: { 'Content-Type': 'application/json', ...args.fetchOptions?.headers }`);
70
- }
71
-
72
- if (hasQueryParams && hasArgs) {
73
- options.push(generateQueryParams(info.queryParams));
74
- }
75
-
76
- if (hasBody) {
77
- options.push('body: args.variables.body');
78
- }
79
-
80
- return options.length > 0 ? `{ ${options.join(', ')} }` : '{}';
81
- };
82
-
83
- return `
84
- /**
85
- * ${info.summary}
86
- */
87
- ${info.operationName}(
88
- ${hasArgs ? `args: IRestFulEndpointsQueryReturn<${info.argTypeName}>, ` : ''}
89
- ): Observable<${info.responseTypeName}> {
90
- const url = ${generateUrlTemplate(info.path)};
91
- return this.http.request('${info.verb.toLowerCase()}', url, ${generateRequestOptions()});
92
- }`;
93
-
94
-
95
-
96
- }).join('')}
97
- }
98
- `;
99
- }
100
-
101
-
102
- /**
103
- * 產生 QueryParams 參數
104
- * @param queryParams
105
- */
106
- function generateQueryParams(queryParams: Record<string, string>[]) {
107
- const paramEntries = queryParams.map(param =>
108
- `${param.name}: args.variables.${param.name}`
109
- ).join(', ');
110
-
111
- return `params: withoutUndefined({ ${paramEntries} })`;
112
- }
@@ -1,43 +0,0 @@
1
- import { toCamelCase } from './utils-generator';
2
-
3
-
4
- export function generateCacheKeysFile(allEndpointInfos: Array<{
5
- operationName: string;
6
- queryKeyName: string;
7
- groupKey: string;
8
- }>) {
9
-
10
- // 按 group 分組
11
- const groupedKeys = allEndpointInfos.reduce((acc, info) => {
12
- if (!acc[info.groupKey]) {
13
- acc[info.groupKey] = [];
14
- }
15
- acc[info.groupKey].push({
16
- operationName: info.operationName,
17
- queryKeyName: info.queryKeyName
18
- });
19
- return acc;
20
- }, {} as Record<string, Array<{operationName: string, queryKeyName: string}>>);
21
-
22
- // 生成 enum 內容
23
- const enumEntries = Object.entries(groupedKeys).map(([groupKey, keys]) => {
24
- const groupComment = ` // ${groupKey.charAt(0).toUpperCase() + groupKey.slice(1)} related cache keys`;
25
- const keyEntries = keys.map(key =>
26
- ` ${key.queryKeyName} = '${toCamelCase(key.queryKeyName)}',`
27
- ).join('\n');
28
-
29
- return `${groupComment}\n${keyEntries}`;
30
- }).join('\n\n');
31
-
32
- return `// [Warning] Generated automatically - do not edit manually
33
-
34
- /**
35
- * Cache keys enum for all API queries
36
- */
37
- export enum ECacheKeys {
38
- ${enumEntries}
39
- }
40
-
41
- export default ECacheKeys;
42
- `;
43
- }
@@ -1,11 +0,0 @@
1
- import type { GenerationOptions } from '../types';
2
-
3
- export function generateIndexFile(groupKey: string, options: GenerationOptions) {
4
- const { groupKey: optionsGroupKey } = options;
5
-
6
-
7
- return `export * from './types';
8
- export * from './api.service';
9
- export * from './query.service';
10
- `;
11
- }
@@ -1,24 +0,0 @@
1
- import type { GenerationOptions } from '../types';
2
- import { generateApiServiceFile } from '../generators/api-service-generator';
3
-
4
- /**
5
- * API 服務程式碼生成器 - 專門負責生成 API Service 相關程式碼
6
- */
7
- export class ApiServiceGenerator {
8
- constructor(private options: GenerationOptions) {}
9
-
10
- /**
11
- * 生成 API Service 檔案內容
12
- */
13
- generateApiService(endpointInfos: Array<any>): string {
14
- const generatorOptions = {
15
- ...this.options,
16
- apiConfiguration: this.options.apiConfiguration || {
17
- file: '@/store/webapi',
18
- importName: 'WebApiConfiguration'
19
- }
20
- };
21
-
22
- return generateApiServiceFile(endpointInfos, generatorOptions);
23
- }
24
- }
@@ -1,24 +0,0 @@
1
- import type { GenerationOptions } from '../types';
2
- import { generateQueryServiceFile } from '../generators/query-service-generator';
3
-
4
- /**
5
- * Query 服務程式碼生成器 - 專門負責生成 Query Service 相關程式碼
6
- */
7
- export class QueryCodeGenerator {
8
- constructor(private options: GenerationOptions) {}
9
-
10
- /**
11
- * 生成 Query Service 檔案內容
12
- */
13
- generateQueryService(endpointInfos: Array<any>): string {
14
- const generatorOptions = {
15
- ...this.options,
16
- apiConfiguration: this.options.apiConfiguration || {
17
- file: '@/store/webapi',
18
- importName: 'WebApiConfiguration'
19
- }
20
- };
21
-
22
- return generateQueryServiceFile(endpointInfos, generatorOptions);
23
- }
24
- }