@bitstack/ng-query-codegen-openapi 0.0.30 → 0.0.31-alpha.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/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 }`
@@ -151,11 +142,6 @@ export interface CommonOptions {
151
142
  * File path for importing IRestFulEndpointsQueryReturn type
152
143
  */
153
144
  endpointsQueryReturnTypeFile?: string;
154
- /**
155
- * defaults to 60 (seconds)
156
- * Number of seconds to wait before refetching data when component mounts or args change
157
- */
158
- refetchOnMountOrArgChange?: number;
159
145
  }
160
146
 
161
147
  export type TextMatcher = string | RegExp | (string | RegExp)[];
@@ -173,11 +159,6 @@ export interface OutputFileOptions extends Partial<CommonOptions> {
173
159
  filterEndpoints?: EndpointMatcher;
174
160
  endpointOverrides?: EndpointOverrides[];
175
161
  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
162
  sharedTypesFile?: string;
182
163
  /**
183
164
  * groupKey for service class naming, e.g., "room" -> "RoomService"
@@ -204,30 +185,23 @@ export type ConfigFile =
204
185
  | Id<
205
186
  Omit<CommonOptions, 'outputFile'> & {
206
187
  // outputFiles: { [outputFile: string]: Omit<OutputFileOptions, 'outputFile'> };
207
- outputFiles: OutputFilesConfig
188
+ outputFiles: OutputFilesConfig;
208
189
  }
209
190
  >;
210
191
 
211
192
  export type GenerateApiResult = {
212
193
  operationNames: string[];
194
+ tags: string[]; // 收集到的所有 tags
213
195
  files: {
214
196
  types: string;
215
- apiService: string;
216
- queryService: string;
197
+ queryService: string; // RTK Query generated file
217
198
  index: string;
199
+ enhanceEndpoints?: string; // RTK Query enhance endpoints file
218
200
  commonTypes?: string;
219
- cacheKeys?: string;
220
201
  componentSchema?: string;
221
- allEndpointCacheKeys?: Array<{
222
- operationName: string
223
- queryKeyName: string
224
- groupKey: string
225
- }>;
226
202
  };
227
203
  };
228
204
 
229
-
230
-
231
205
  export type QueryArgDefinition = {
232
206
  name: string;
233
207
  originalName: string;
@@ -236,13 +210,13 @@ export type QueryArgDefinition = {
236
210
  param?: OpenAPIV3.ParameterObject;
237
211
  } & (
238
212
  | {
239
- origin: 'param';
240
- param: OpenAPIV3.ParameterObject;
241
- }
213
+ origin: 'param';
214
+ param: OpenAPIV3.ParameterObject;
215
+ }
242
216
  | {
243
- origin: 'body';
244
- body: OpenAPIV3.RequestBodyObject;
245
- }
246
- );
217
+ origin: 'body';
218
+ body: OpenAPIV3.RequestBodyObject;
219
+ }
220
+ );
247
221
 
248
- export type QueryArgDefinitions = Record<string, QueryArgDefinition>;
222
+ 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
- }