@honestjs/rpc-plugin 1.2.0 → 1.3.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/README.md +97 -3
- package/dist/index.d.mts +88 -43
- package/dist/index.d.ts +88 -43
- package/dist/index.js +332 -136
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +324 -131
- package/dist/index.mjs.map +1 -1
- package/package.json +8 -5
package/README.md
CHANGED
|
@@ -32,11 +32,28 @@ interface RPCPluginOptions {
|
|
|
32
32
|
readonly tsConfigPath?: string // Path to tsconfig.json (default: 'tsconfig.json')
|
|
33
33
|
readonly outputDir?: string // Output directory for generated files (default: './generated/rpc')
|
|
34
34
|
readonly generateOnInit?: boolean // Generate files on initialization (default: true)
|
|
35
|
+
readonly openapi?: OpenApiOptions | boolean // Enable OpenAPI spec generation (default: false)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
interface OpenApiOptions {
|
|
39
|
+
readonly title?: string // API title (default: 'API')
|
|
40
|
+
readonly version?: string // API version (default: '1.0.0')
|
|
41
|
+
readonly description?: string // API description (default: '')
|
|
42
|
+
readonly servers?: readonly { url: string; description?: string }[] // Server list
|
|
43
|
+
readonly outputFile?: string // Output filename (default: 'openapi.json')
|
|
35
44
|
}
|
|
36
45
|
```
|
|
37
46
|
|
|
38
47
|
## What It Generates
|
|
39
48
|
|
|
49
|
+
The plugin generates files in the output directory (default: `./generated/rpc`):
|
|
50
|
+
|
|
51
|
+
| File | Description | When generated |
|
|
52
|
+
| --------------- | -------------------------------------------- | --------------------- |
|
|
53
|
+
| `client.ts` | Type-safe RPC client with all DTOs | Always |
|
|
54
|
+
| `openapi.json` | OpenAPI 3.0.3 specification | When `openapi` is set |
|
|
55
|
+
| `.rpc-checksum` | Hash of source files for incremental caching | Always |
|
|
56
|
+
|
|
40
57
|
### TypeScript RPC Client (`client.ts`)
|
|
41
58
|
|
|
42
59
|
The plugin generates a single comprehensive file that includes both the client and all type definitions:
|
|
@@ -173,6 +190,67 @@ const testApiClient = new ApiClient('http://test.com', {
|
|
|
173
190
|
expect(mockFetch).toHaveBeenCalledWith('http://test.com/api/v1/users/123', expect.objectContaining({ method: 'GET' }))
|
|
174
191
|
```
|
|
175
192
|
|
|
193
|
+
## OpenAPI Spec Generation
|
|
194
|
+
|
|
195
|
+
The plugin can produce an OpenAPI 3.0.3 JSON specification alongside the client. This is useful for Swagger UI, documentation portals, and third-party integrations. No extra dependencies are needed — the spec is built from the same route and schema data used for client generation.
|
|
196
|
+
|
|
197
|
+
### Enable with defaults
|
|
198
|
+
|
|
199
|
+
Pass `true` to use all default values:
|
|
200
|
+
|
|
201
|
+
```typescript
|
|
202
|
+
new RPCPlugin({
|
|
203
|
+
openapi: true
|
|
204
|
+
})
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Custom options
|
|
208
|
+
|
|
209
|
+
```typescript
|
|
210
|
+
new RPCPlugin({
|
|
211
|
+
openapi: {
|
|
212
|
+
title: 'My Service API',
|
|
213
|
+
version: '2.1.0',
|
|
214
|
+
description: 'User management service',
|
|
215
|
+
servers: [
|
|
216
|
+
{ url: 'https://api.example.com', description: 'Production' },
|
|
217
|
+
{ url: 'http://localhost:3000', description: 'Local' }
|
|
218
|
+
],
|
|
219
|
+
outputFile: 'api-spec.json'
|
|
220
|
+
}
|
|
221
|
+
})
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
The generated spec includes:
|
|
225
|
+
|
|
226
|
+
- **Paths** derived from your controller routes
|
|
227
|
+
- **Parameters** (path, query) with correct types
|
|
228
|
+
- **Request bodies** referencing component schemas for DTOs
|
|
229
|
+
- **Responses** with schema references and array type support
|
|
230
|
+
- **Component schemas** extracted from `ts-json-schema-generator` output
|
|
231
|
+
- **Tags** derived from controller names
|
|
232
|
+
|
|
233
|
+
## Hash-based Caching
|
|
234
|
+
|
|
235
|
+
On startup the plugin hashes all controller source files (SHA-256) and stores the checksum in `.rpc-checksum` inside the output directory. On subsequent runs, if the hash matches and the expected output files already exist, the expensive analysis and generation pipeline is skipped entirely. This significantly reduces startup time in large projects.
|
|
236
|
+
|
|
237
|
+
Caching is automatic and requires no configuration. To force regeneration:
|
|
238
|
+
|
|
239
|
+
```typescript
|
|
240
|
+
// Manual call — defaults to force=true, always regenerates
|
|
241
|
+
await rpcPlugin.analyze()
|
|
242
|
+
|
|
243
|
+
// Explicit cache bypass
|
|
244
|
+
await rpcPlugin.analyze(true)
|
|
245
|
+
|
|
246
|
+
// Respect the cache (same behavior as automatic startup)
|
|
247
|
+
await rpcPlugin.analyze(false)
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
You can also delete `.rpc-checksum` from the output directory to clear the cache.
|
|
251
|
+
|
|
252
|
+
> **Note:** The hash covers controller files matched by the `controllerPattern` glob. If you only change a DTO/model file that lives outside that pattern, the cache won't invalidate automatically. Use `analyze()` or delete `.rpc-checksum` in that case.
|
|
253
|
+
|
|
176
254
|
## How It Works
|
|
177
255
|
|
|
178
256
|
### 1. Route Analysis
|
|
@@ -196,6 +274,19 @@ expect(mockFetch).toHaveBeenCalledWith('http://test.com/api/v1/users/123', expec
|
|
|
196
274
|
- Creates parameter validation and typing
|
|
197
275
|
- Builds the complete RPC client with proper error handling
|
|
198
276
|
|
|
277
|
+
### 4. OpenAPI Generation (optional)
|
|
278
|
+
|
|
279
|
+
- Converts route and schema data to OpenAPI 3.0.3 paths and components
|
|
280
|
+
- Maps `@Param()`, `@Query()`, and `@Body()` decorators to the correct OpenAPI parameter locations
|
|
281
|
+
- References component schemas via `$ref` for DTOs
|
|
282
|
+
- Outputs a single JSON file ready for Swagger UI or any OpenAPI-compatible tool
|
|
283
|
+
|
|
284
|
+
### 5. Incremental Caching
|
|
285
|
+
|
|
286
|
+
- Hashes all matched controller files after glob resolution
|
|
287
|
+
- Compares against the stored `.rpc-checksum`
|
|
288
|
+
- Skips steps 1–4 when files are unchanged and output already exists
|
|
289
|
+
|
|
199
290
|
## Example Generated Output
|
|
200
291
|
|
|
201
292
|
### Generated Client
|
|
@@ -237,12 +328,15 @@ export type RequestOptions<
|
|
|
237
328
|
|
|
238
329
|
## Plugin Lifecycle
|
|
239
330
|
|
|
240
|
-
The plugin automatically generates files when your HonestJS application starts up (if `generateOnInit` is true).
|
|
241
|
-
|
|
331
|
+
The plugin automatically generates files when your HonestJS application starts up (if `generateOnInit` is true). On
|
|
332
|
+
subsequent startups, the hash-based cache will skip regeneration if controller files haven't changed.
|
|
333
|
+
|
|
334
|
+
You can also manually trigger generation:
|
|
242
335
|
|
|
243
336
|
```typescript
|
|
244
337
|
const rpcPlugin = new RPCPlugin()
|
|
245
|
-
await rpcPlugin.analyze() //
|
|
338
|
+
await rpcPlugin.analyze() // Force regeneration (bypasses cache)
|
|
339
|
+
await rpcPlugin.analyze(false) // Respect cache
|
|
246
340
|
```
|
|
247
341
|
|
|
248
342
|
## Advanced Usage
|
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { RouteInfo, ParameterMetadata, IPlugin, Application } from 'honestjs';
|
|
2
2
|
import { Hono } from 'hono';
|
|
3
|
-
import { Type } from 'ts-morph';
|
|
3
|
+
import { Project, Type } from 'ts-morph';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Parameter metadata with enhanced type information
|
|
@@ -9,6 +9,8 @@ interface ParameterMetadataWithType extends ParameterMetadata {
|
|
|
9
9
|
readonly type: string;
|
|
10
10
|
readonly required: boolean;
|
|
11
11
|
readonly name: string;
|
|
12
|
+
/** Original decorator kind: 'body', 'param', 'query', 'header', etc. */
|
|
13
|
+
readonly decoratorType: string;
|
|
12
14
|
}
|
|
13
15
|
/**
|
|
14
16
|
* Extended route information with comprehensive type data
|
|
@@ -49,21 +51,13 @@ interface GeneratedClientInfo {
|
|
|
49
51
|
/**
|
|
50
52
|
* Clean separation of concerns for request options
|
|
51
53
|
*/
|
|
52
|
-
type RequestOptions<TParams =
|
|
53
|
-
params?: never;
|
|
54
|
-
} : {
|
|
54
|
+
type RequestOptions<TParams = undefined, TQuery = undefined, TBody = undefined, THeaders = undefined> = (TParams extends undefined ? object : {
|
|
55
55
|
params: TParams;
|
|
56
|
-
}) & (TQuery extends
|
|
57
|
-
query
|
|
58
|
-
} : {
|
|
59
|
-
query?: TQuery;
|
|
60
|
-
}) & (TBody extends never ? {
|
|
61
|
-
body?: never;
|
|
62
|
-
} : {
|
|
56
|
+
}) & (TQuery extends undefined ? object : {
|
|
57
|
+
query: TQuery;
|
|
58
|
+
}) & (TBody extends undefined ? object : {
|
|
63
59
|
body: TBody;
|
|
64
|
-
}) & (THeaders extends
|
|
65
|
-
headers?: never;
|
|
66
|
-
} : {
|
|
60
|
+
}) & (THeaders extends undefined ? object : {
|
|
67
61
|
headers: THeaders;
|
|
68
62
|
});
|
|
69
63
|
/**
|
|
@@ -78,6 +72,16 @@ declare class ApiError extends Error {
|
|
|
78
72
|
constructor(statusCode: number, message: string);
|
|
79
73
|
}
|
|
80
74
|
|
|
75
|
+
interface OpenApiOptions {
|
|
76
|
+
readonly title?: string;
|
|
77
|
+
readonly version?: string;
|
|
78
|
+
readonly description?: string;
|
|
79
|
+
readonly servers?: readonly {
|
|
80
|
+
url: string;
|
|
81
|
+
description?: string;
|
|
82
|
+
}[];
|
|
83
|
+
readonly outputFile?: string;
|
|
84
|
+
}
|
|
81
85
|
/**
|
|
82
86
|
* Configuration options for the RPCPlugin
|
|
83
87
|
*/
|
|
@@ -86,6 +90,7 @@ interface RPCPluginOptions {
|
|
|
86
90
|
readonly tsConfigPath?: string;
|
|
87
91
|
readonly outputDir?: string;
|
|
88
92
|
readonly generateOnInit?: boolean;
|
|
93
|
+
readonly openapi?: OpenApiOptions | boolean;
|
|
89
94
|
}
|
|
90
95
|
/**
|
|
91
96
|
* Comprehensive RPC plugin that combines route analysis, schema generation, and client generation
|
|
@@ -98,10 +103,14 @@ declare class RPCPlugin implements IPlugin {
|
|
|
98
103
|
private readonly routeAnalyzer;
|
|
99
104
|
private readonly schemaGenerator;
|
|
100
105
|
private readonly clientGenerator;
|
|
106
|
+
private readonly openApiGenerator;
|
|
107
|
+
private readonly openApiOptions;
|
|
108
|
+
private project;
|
|
101
109
|
private analyzedRoutes;
|
|
102
110
|
private analyzedSchemas;
|
|
103
111
|
private generatedInfo;
|
|
104
112
|
constructor(options?: RPCPluginOptions);
|
|
113
|
+
private resolveOpenApiOptions;
|
|
105
114
|
/**
|
|
106
115
|
* Validates the plugin configuration
|
|
107
116
|
*/
|
|
@@ -115,9 +124,10 @@ declare class RPCPlugin implements IPlugin {
|
|
|
115
124
|
*/
|
|
116
125
|
private analyzeEverything;
|
|
117
126
|
/**
|
|
118
|
-
* Manually trigger analysis (useful for testing or re-generation)
|
|
127
|
+
* Manually trigger analysis (useful for testing or re-generation).
|
|
128
|
+
* Defaults to force=true to bypass cache; pass false to use caching.
|
|
119
129
|
*/
|
|
120
|
-
analyze(): Promise<void>;
|
|
130
|
+
analyze(force?: boolean): Promise<void>;
|
|
121
131
|
/**
|
|
122
132
|
* Get the analyzed routes
|
|
123
133
|
*/
|
|
@@ -130,6 +140,10 @@ declare class RPCPlugin implements IPlugin {
|
|
|
130
140
|
* Get the generation info
|
|
131
141
|
*/
|
|
132
142
|
getGenerationInfo(): GeneratedClientInfo | null;
|
|
143
|
+
/**
|
|
144
|
+
* Checks whether expected output files exist on disk
|
|
145
|
+
*/
|
|
146
|
+
private outputFilesExist;
|
|
133
147
|
/**
|
|
134
148
|
* Cleanup resources to prevent memory leaks
|
|
135
149
|
*/
|
|
@@ -184,26 +198,50 @@ declare class ClientGeneratorService {
|
|
|
184
198
|
private analyzeRouteParameters;
|
|
185
199
|
}
|
|
186
200
|
|
|
201
|
+
interface ResolvedOpenApiOptions {
|
|
202
|
+
readonly title: string;
|
|
203
|
+
readonly version: string;
|
|
204
|
+
readonly description: string;
|
|
205
|
+
readonly servers: readonly {
|
|
206
|
+
url: string;
|
|
207
|
+
description?: string;
|
|
208
|
+
}[];
|
|
209
|
+
readonly outputFile: string;
|
|
210
|
+
}
|
|
187
211
|
/**
|
|
188
|
-
* Service for
|
|
212
|
+
* Service for generating OpenAPI 3.0.3 specifications from analyzed routes and schemas
|
|
189
213
|
*/
|
|
190
|
-
declare class
|
|
191
|
-
private readonly
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
private
|
|
214
|
+
declare class OpenApiGeneratorService {
|
|
215
|
+
private readonly outputDir;
|
|
216
|
+
constructor(outputDir: string);
|
|
217
|
+
generateSpec(routes: readonly ExtendedRouteInfo[], schemas: readonly SchemaInfo[], options: ResolvedOpenApiOptions): Promise<string>;
|
|
218
|
+
private buildSpec;
|
|
219
|
+
private buildOperation;
|
|
220
|
+
private buildParameters;
|
|
221
|
+
private buildRequestBody;
|
|
222
|
+
private buildResponses;
|
|
223
|
+
private resolveResponseSchema;
|
|
224
|
+
private buildSchemaMap;
|
|
195
225
|
/**
|
|
196
|
-
*
|
|
226
|
+
* Converts Express-style `:param` path to OpenAPI `{param}` syntax
|
|
197
227
|
*/
|
|
198
|
-
|
|
228
|
+
private toOpenApiPath;
|
|
229
|
+
private tsTypeToJsonSchema;
|
|
199
230
|
/**
|
|
200
|
-
*
|
|
231
|
+
* Extracts the base type name from a TS type string, stripping
|
|
232
|
+
* wrappers like `Partial<...>`, `...[]`, `Promise<...>`.
|
|
201
233
|
*/
|
|
202
|
-
private
|
|
234
|
+
private extractBaseTypeName;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Service for analyzing controller methods and extracting type information
|
|
239
|
+
*/
|
|
240
|
+
declare class RouteAnalyzerService {
|
|
203
241
|
/**
|
|
204
|
-
*
|
|
242
|
+
* Analyzes controller methods to extract type information
|
|
205
243
|
*/
|
|
206
|
-
|
|
244
|
+
analyzeControllerMethods(project: Project): Promise<ExtendedRouteInfo[]>;
|
|
207
245
|
/**
|
|
208
246
|
* Finds controller classes in the project
|
|
209
247
|
*/
|
|
@@ -233,19 +271,10 @@ declare class SchemaGeneratorService {
|
|
|
233
271
|
private readonly controllerPattern;
|
|
234
272
|
private readonly tsConfigPath;
|
|
235
273
|
constructor(controllerPattern: string, tsConfigPath: string);
|
|
236
|
-
private projects;
|
|
237
274
|
/**
|
|
238
275
|
* Generates JSON schemas from types used in controllers
|
|
239
276
|
*/
|
|
240
|
-
generateSchemas(): Promise<SchemaInfo[]>;
|
|
241
|
-
/**
|
|
242
|
-
* Creates a new ts-morph project
|
|
243
|
-
*/
|
|
244
|
-
private createProject;
|
|
245
|
-
/**
|
|
246
|
-
* Cleanup resources to prevent memory leaks
|
|
247
|
-
*/
|
|
248
|
-
dispose(): void;
|
|
277
|
+
generateSchemas(project: Project): Promise<SchemaInfo[]>;
|
|
249
278
|
/**
|
|
250
279
|
* Collects types from controller files
|
|
251
280
|
*/
|
|
@@ -264,6 +293,26 @@ declare class SchemaGeneratorService {
|
|
|
264
293
|
private generateSchemaForType;
|
|
265
294
|
}
|
|
266
295
|
|
|
296
|
+
interface ChecksumData {
|
|
297
|
+
hash: string;
|
|
298
|
+
files: string[];
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Computes a deterministic SHA-256 hash from file contents.
|
|
302
|
+
* Sorts paths before reading to ensure consistent ordering.
|
|
303
|
+
* Includes the file count in the hash so adding/removing files changes it.
|
|
304
|
+
*/
|
|
305
|
+
declare function computeHash(filePaths: string[]): string;
|
|
306
|
+
/**
|
|
307
|
+
* Reads the stored checksum from the output directory.
|
|
308
|
+
* Returns null if the file is missing or corrupt.
|
|
309
|
+
*/
|
|
310
|
+
declare function readChecksum(outputDir: string): ChecksumData | null;
|
|
311
|
+
/**
|
|
312
|
+
* Writes the checksum data to the output directory.
|
|
313
|
+
*/
|
|
314
|
+
declare function writeChecksum(outputDir: string, data: ChecksumData): Promise<void>;
|
|
315
|
+
|
|
267
316
|
/**
|
|
268
317
|
* Builds the full path with parameter placeholders
|
|
269
318
|
*/
|
|
@@ -295,10 +344,6 @@ declare function camelCase(str: string): string;
|
|
|
295
344
|
* Extracts a named type from a TypeScript type
|
|
296
345
|
*/
|
|
297
346
|
declare function extractNamedType(type: Type): string | null;
|
|
298
|
-
/**
|
|
299
|
-
* Generates type imports for the client
|
|
300
|
-
*/
|
|
301
|
-
declare function generateTypeImports(routes: readonly any[]): string;
|
|
302
347
|
|
|
303
348
|
/**
|
|
304
349
|
* Default configuration options for the RPCPlugin
|
|
@@ -326,4 +371,4 @@ declare const BUILTIN_TYPES: Set<string>;
|
|
|
326
371
|
*/
|
|
327
372
|
declare const GENERIC_TYPES: Set<string>;
|
|
328
373
|
|
|
329
|
-
export { ApiError, BUILTIN_TYPES, BUILTIN_UTILITY_TYPES, ClientGeneratorService, type ControllerGroups, DEFAULT_OPTIONS, type ExtendedRouteInfo, type FetchFunction, GENERIC_TYPES, type GeneratedClientInfo, LOG_PREFIX, type ParameterMetadataWithType, RPCPlugin, type RPCPluginOptions, type RequestOptions, RouteAnalyzerService, type RouteParameter, SchemaGeneratorService, type SchemaInfo, buildFullApiPath, buildFullPath, camelCase,
|
|
374
|
+
export { ApiError, BUILTIN_TYPES, BUILTIN_UTILITY_TYPES, type ChecksumData, ClientGeneratorService, type ControllerGroups, DEFAULT_OPTIONS, type ExtendedRouteInfo, type FetchFunction, GENERIC_TYPES, type GeneratedClientInfo, LOG_PREFIX, OpenApiGeneratorService, type OpenApiOptions, type ParameterMetadataWithType, RPCPlugin, type RPCPluginOptions, type RequestOptions, RouteAnalyzerService, type RouteParameter, SchemaGeneratorService, type SchemaInfo, buildFullApiPath, buildFullPath, camelCase, computeHash, extractNamedType, generateTypeScriptInterface, mapJsonSchemaTypeToTypeScript, readChecksum, safeToString, writeChecksum };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { RouteInfo, ParameterMetadata, IPlugin, Application } from 'honestjs';
|
|
2
2
|
import { Hono } from 'hono';
|
|
3
|
-
import { Type } from 'ts-morph';
|
|
3
|
+
import { Project, Type } from 'ts-morph';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Parameter metadata with enhanced type information
|
|
@@ -9,6 +9,8 @@ interface ParameterMetadataWithType extends ParameterMetadata {
|
|
|
9
9
|
readonly type: string;
|
|
10
10
|
readonly required: boolean;
|
|
11
11
|
readonly name: string;
|
|
12
|
+
/** Original decorator kind: 'body', 'param', 'query', 'header', etc. */
|
|
13
|
+
readonly decoratorType: string;
|
|
12
14
|
}
|
|
13
15
|
/**
|
|
14
16
|
* Extended route information with comprehensive type data
|
|
@@ -49,21 +51,13 @@ interface GeneratedClientInfo {
|
|
|
49
51
|
/**
|
|
50
52
|
* Clean separation of concerns for request options
|
|
51
53
|
*/
|
|
52
|
-
type RequestOptions<TParams =
|
|
53
|
-
params?: never;
|
|
54
|
-
} : {
|
|
54
|
+
type RequestOptions<TParams = undefined, TQuery = undefined, TBody = undefined, THeaders = undefined> = (TParams extends undefined ? object : {
|
|
55
55
|
params: TParams;
|
|
56
|
-
}) & (TQuery extends
|
|
57
|
-
query
|
|
58
|
-
} : {
|
|
59
|
-
query?: TQuery;
|
|
60
|
-
}) & (TBody extends never ? {
|
|
61
|
-
body?: never;
|
|
62
|
-
} : {
|
|
56
|
+
}) & (TQuery extends undefined ? object : {
|
|
57
|
+
query: TQuery;
|
|
58
|
+
}) & (TBody extends undefined ? object : {
|
|
63
59
|
body: TBody;
|
|
64
|
-
}) & (THeaders extends
|
|
65
|
-
headers?: never;
|
|
66
|
-
} : {
|
|
60
|
+
}) & (THeaders extends undefined ? object : {
|
|
67
61
|
headers: THeaders;
|
|
68
62
|
});
|
|
69
63
|
/**
|
|
@@ -78,6 +72,16 @@ declare class ApiError extends Error {
|
|
|
78
72
|
constructor(statusCode: number, message: string);
|
|
79
73
|
}
|
|
80
74
|
|
|
75
|
+
interface OpenApiOptions {
|
|
76
|
+
readonly title?: string;
|
|
77
|
+
readonly version?: string;
|
|
78
|
+
readonly description?: string;
|
|
79
|
+
readonly servers?: readonly {
|
|
80
|
+
url: string;
|
|
81
|
+
description?: string;
|
|
82
|
+
}[];
|
|
83
|
+
readonly outputFile?: string;
|
|
84
|
+
}
|
|
81
85
|
/**
|
|
82
86
|
* Configuration options for the RPCPlugin
|
|
83
87
|
*/
|
|
@@ -86,6 +90,7 @@ interface RPCPluginOptions {
|
|
|
86
90
|
readonly tsConfigPath?: string;
|
|
87
91
|
readonly outputDir?: string;
|
|
88
92
|
readonly generateOnInit?: boolean;
|
|
93
|
+
readonly openapi?: OpenApiOptions | boolean;
|
|
89
94
|
}
|
|
90
95
|
/**
|
|
91
96
|
* Comprehensive RPC plugin that combines route analysis, schema generation, and client generation
|
|
@@ -98,10 +103,14 @@ declare class RPCPlugin implements IPlugin {
|
|
|
98
103
|
private readonly routeAnalyzer;
|
|
99
104
|
private readonly schemaGenerator;
|
|
100
105
|
private readonly clientGenerator;
|
|
106
|
+
private readonly openApiGenerator;
|
|
107
|
+
private readonly openApiOptions;
|
|
108
|
+
private project;
|
|
101
109
|
private analyzedRoutes;
|
|
102
110
|
private analyzedSchemas;
|
|
103
111
|
private generatedInfo;
|
|
104
112
|
constructor(options?: RPCPluginOptions);
|
|
113
|
+
private resolveOpenApiOptions;
|
|
105
114
|
/**
|
|
106
115
|
* Validates the plugin configuration
|
|
107
116
|
*/
|
|
@@ -115,9 +124,10 @@ declare class RPCPlugin implements IPlugin {
|
|
|
115
124
|
*/
|
|
116
125
|
private analyzeEverything;
|
|
117
126
|
/**
|
|
118
|
-
* Manually trigger analysis (useful for testing or re-generation)
|
|
127
|
+
* Manually trigger analysis (useful for testing or re-generation).
|
|
128
|
+
* Defaults to force=true to bypass cache; pass false to use caching.
|
|
119
129
|
*/
|
|
120
|
-
analyze(): Promise<void>;
|
|
130
|
+
analyze(force?: boolean): Promise<void>;
|
|
121
131
|
/**
|
|
122
132
|
* Get the analyzed routes
|
|
123
133
|
*/
|
|
@@ -130,6 +140,10 @@ declare class RPCPlugin implements IPlugin {
|
|
|
130
140
|
* Get the generation info
|
|
131
141
|
*/
|
|
132
142
|
getGenerationInfo(): GeneratedClientInfo | null;
|
|
143
|
+
/**
|
|
144
|
+
* Checks whether expected output files exist on disk
|
|
145
|
+
*/
|
|
146
|
+
private outputFilesExist;
|
|
133
147
|
/**
|
|
134
148
|
* Cleanup resources to prevent memory leaks
|
|
135
149
|
*/
|
|
@@ -184,26 +198,50 @@ declare class ClientGeneratorService {
|
|
|
184
198
|
private analyzeRouteParameters;
|
|
185
199
|
}
|
|
186
200
|
|
|
201
|
+
interface ResolvedOpenApiOptions {
|
|
202
|
+
readonly title: string;
|
|
203
|
+
readonly version: string;
|
|
204
|
+
readonly description: string;
|
|
205
|
+
readonly servers: readonly {
|
|
206
|
+
url: string;
|
|
207
|
+
description?: string;
|
|
208
|
+
}[];
|
|
209
|
+
readonly outputFile: string;
|
|
210
|
+
}
|
|
187
211
|
/**
|
|
188
|
-
* Service for
|
|
212
|
+
* Service for generating OpenAPI 3.0.3 specifications from analyzed routes and schemas
|
|
189
213
|
*/
|
|
190
|
-
declare class
|
|
191
|
-
private readonly
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
private
|
|
214
|
+
declare class OpenApiGeneratorService {
|
|
215
|
+
private readonly outputDir;
|
|
216
|
+
constructor(outputDir: string);
|
|
217
|
+
generateSpec(routes: readonly ExtendedRouteInfo[], schemas: readonly SchemaInfo[], options: ResolvedOpenApiOptions): Promise<string>;
|
|
218
|
+
private buildSpec;
|
|
219
|
+
private buildOperation;
|
|
220
|
+
private buildParameters;
|
|
221
|
+
private buildRequestBody;
|
|
222
|
+
private buildResponses;
|
|
223
|
+
private resolveResponseSchema;
|
|
224
|
+
private buildSchemaMap;
|
|
195
225
|
/**
|
|
196
|
-
*
|
|
226
|
+
* Converts Express-style `:param` path to OpenAPI `{param}` syntax
|
|
197
227
|
*/
|
|
198
|
-
|
|
228
|
+
private toOpenApiPath;
|
|
229
|
+
private tsTypeToJsonSchema;
|
|
199
230
|
/**
|
|
200
|
-
*
|
|
231
|
+
* Extracts the base type name from a TS type string, stripping
|
|
232
|
+
* wrappers like `Partial<...>`, `...[]`, `Promise<...>`.
|
|
201
233
|
*/
|
|
202
|
-
private
|
|
234
|
+
private extractBaseTypeName;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Service for analyzing controller methods and extracting type information
|
|
239
|
+
*/
|
|
240
|
+
declare class RouteAnalyzerService {
|
|
203
241
|
/**
|
|
204
|
-
*
|
|
242
|
+
* Analyzes controller methods to extract type information
|
|
205
243
|
*/
|
|
206
|
-
|
|
244
|
+
analyzeControllerMethods(project: Project): Promise<ExtendedRouteInfo[]>;
|
|
207
245
|
/**
|
|
208
246
|
* Finds controller classes in the project
|
|
209
247
|
*/
|
|
@@ -233,19 +271,10 @@ declare class SchemaGeneratorService {
|
|
|
233
271
|
private readonly controllerPattern;
|
|
234
272
|
private readonly tsConfigPath;
|
|
235
273
|
constructor(controllerPattern: string, tsConfigPath: string);
|
|
236
|
-
private projects;
|
|
237
274
|
/**
|
|
238
275
|
* Generates JSON schemas from types used in controllers
|
|
239
276
|
*/
|
|
240
|
-
generateSchemas(): Promise<SchemaInfo[]>;
|
|
241
|
-
/**
|
|
242
|
-
* Creates a new ts-morph project
|
|
243
|
-
*/
|
|
244
|
-
private createProject;
|
|
245
|
-
/**
|
|
246
|
-
* Cleanup resources to prevent memory leaks
|
|
247
|
-
*/
|
|
248
|
-
dispose(): void;
|
|
277
|
+
generateSchemas(project: Project): Promise<SchemaInfo[]>;
|
|
249
278
|
/**
|
|
250
279
|
* Collects types from controller files
|
|
251
280
|
*/
|
|
@@ -264,6 +293,26 @@ declare class SchemaGeneratorService {
|
|
|
264
293
|
private generateSchemaForType;
|
|
265
294
|
}
|
|
266
295
|
|
|
296
|
+
interface ChecksumData {
|
|
297
|
+
hash: string;
|
|
298
|
+
files: string[];
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Computes a deterministic SHA-256 hash from file contents.
|
|
302
|
+
* Sorts paths before reading to ensure consistent ordering.
|
|
303
|
+
* Includes the file count in the hash so adding/removing files changes it.
|
|
304
|
+
*/
|
|
305
|
+
declare function computeHash(filePaths: string[]): string;
|
|
306
|
+
/**
|
|
307
|
+
* Reads the stored checksum from the output directory.
|
|
308
|
+
* Returns null if the file is missing or corrupt.
|
|
309
|
+
*/
|
|
310
|
+
declare function readChecksum(outputDir: string): ChecksumData | null;
|
|
311
|
+
/**
|
|
312
|
+
* Writes the checksum data to the output directory.
|
|
313
|
+
*/
|
|
314
|
+
declare function writeChecksum(outputDir: string, data: ChecksumData): Promise<void>;
|
|
315
|
+
|
|
267
316
|
/**
|
|
268
317
|
* Builds the full path with parameter placeholders
|
|
269
318
|
*/
|
|
@@ -295,10 +344,6 @@ declare function camelCase(str: string): string;
|
|
|
295
344
|
* Extracts a named type from a TypeScript type
|
|
296
345
|
*/
|
|
297
346
|
declare function extractNamedType(type: Type): string | null;
|
|
298
|
-
/**
|
|
299
|
-
* Generates type imports for the client
|
|
300
|
-
*/
|
|
301
|
-
declare function generateTypeImports(routes: readonly any[]): string;
|
|
302
347
|
|
|
303
348
|
/**
|
|
304
349
|
* Default configuration options for the RPCPlugin
|
|
@@ -326,4 +371,4 @@ declare const BUILTIN_TYPES: Set<string>;
|
|
|
326
371
|
*/
|
|
327
372
|
declare const GENERIC_TYPES: Set<string>;
|
|
328
373
|
|
|
329
|
-
export { ApiError, BUILTIN_TYPES, BUILTIN_UTILITY_TYPES, ClientGeneratorService, type ControllerGroups, DEFAULT_OPTIONS, type ExtendedRouteInfo, type FetchFunction, GENERIC_TYPES, type GeneratedClientInfo, LOG_PREFIX, type ParameterMetadataWithType, RPCPlugin, type RPCPluginOptions, type RequestOptions, RouteAnalyzerService, type RouteParameter, SchemaGeneratorService, type SchemaInfo, buildFullApiPath, buildFullPath, camelCase,
|
|
374
|
+
export { ApiError, BUILTIN_TYPES, BUILTIN_UTILITY_TYPES, type ChecksumData, ClientGeneratorService, type ControllerGroups, DEFAULT_OPTIONS, type ExtendedRouteInfo, type FetchFunction, GENERIC_TYPES, type GeneratedClientInfo, LOG_PREFIX, OpenApiGeneratorService, type OpenApiOptions, type ParameterMetadataWithType, RPCPlugin, type RPCPluginOptions, type RequestOptions, RouteAnalyzerService, type RouteParameter, SchemaGeneratorService, type SchemaInfo, buildFullApiPath, buildFullPath, camelCase, computeHash, extractNamedType, generateTypeScriptInterface, mapJsonSchemaTypeToTypeScript, readChecksum, safeToString, writeChecksum };
|