@hexaijs/plugin-contracts-generator 0.1.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/LICENSE +21 -0
- package/README.md +337 -0
- package/dist/ast-utils.d.ts +6 -0
- package/dist/ast-utils.d.ts.map +1 -0
- package/dist/ast-utils.js +111 -0
- package/dist/ast-utils.js.map +1 -0
- package/dist/class-analyzer.d.ts +16 -0
- package/dist/class-analyzer.d.ts.map +1 -0
- package/dist/class-analyzer.js +155 -0
- package/dist/class-analyzer.js.map +1 -0
- package/dist/cli.d.ts +36 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +321 -0
- package/dist/cli.js.map +1 -0
- package/dist/config-loader.d.ts +34 -0
- package/dist/config-loader.d.ts.map +1 -0
- package/dist/config-loader.js +188 -0
- package/dist/config-loader.js.map +1 -0
- package/dist/decorators/index.d.ts +143 -0
- package/dist/decorators/index.d.ts.map +1 -0
- package/dist/decorators/index.js +123 -0
- package/dist/decorators/index.js.map +1 -0
- package/dist/domain/index.d.ts +2 -0
- package/dist/domain/index.d.ts.map +1 -0
- package/dist/domain/index.js +18 -0
- package/dist/domain/index.js.map +1 -0
- package/dist/domain/types.d.ts +182 -0
- package/dist/domain/types.d.ts.map +1 -0
- package/dist/domain/types.js +65 -0
- package/dist/domain/types.js.map +1 -0
- package/dist/errors.d.ts +79 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +138 -0
- package/dist/errors.js.map +1 -0
- package/dist/file-copier.d.ts +85 -0
- package/dist/file-copier.d.ts.map +1 -0
- package/dist/file-copier.js +773 -0
- package/dist/file-copier.js.map +1 -0
- package/dist/file-graph-resolver.d.ts +47 -0
- package/dist/file-graph-resolver.d.ts.map +1 -0
- package/dist/file-graph-resolver.js +230 -0
- package/dist/file-graph-resolver.js.map +1 -0
- package/dist/file-system.d.ts +26 -0
- package/dist/file-system.d.ts.map +1 -0
- package/dist/file-system.js +34 -0
- package/dist/file-system.js.map +1 -0
- package/dist/hexai-plugin.d.ts +16 -0
- package/dist/hexai-plugin.d.ts.map +1 -0
- package/dist/hexai-plugin.js +59 -0
- package/dist/hexai-plugin.js.map +1 -0
- package/dist/import-analyzer.d.ts +6 -0
- package/dist/import-analyzer.d.ts.map +1 -0
- package/dist/import-analyzer.js +77 -0
- package/dist/import-analyzer.js.map +1 -0
- package/dist/index.d.ts +58 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +97 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +21 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +47 -0
- package/dist/logger.js.map +1 -0
- package/dist/parser.d.ts +32 -0
- package/dist/parser.d.ts.map +1 -0
- package/dist/parser.js +209 -0
- package/dist/parser.js.map +1 -0
- package/dist/pipeline.d.ts +56 -0
- package/dist/pipeline.d.ts.map +1 -0
- package/dist/pipeline.js +152 -0
- package/dist/pipeline.js.map +1 -0
- package/dist/reexport-generator.d.ts +81 -0
- package/dist/reexport-generator.d.ts.map +1 -0
- package/dist/reexport-generator.js +208 -0
- package/dist/reexport-generator.js.map +1 -0
- package/dist/registry-generator.d.ts +27 -0
- package/dist/registry-generator.d.ts.map +1 -0
- package/dist/registry-generator.js +108 -0
- package/dist/registry-generator.js.map +1 -0
- package/dist/runtime/index.d.ts +2 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +6 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/runtime/message-registry.d.ts +23 -0
- package/dist/runtime/message-registry.d.ts.map +1 -0
- package/dist/runtime/message-registry.js +39 -0
- package/dist/runtime/message-registry.js.map +1 -0
- package/dist/scanner.d.ts +21 -0
- package/dist/scanner.d.ts.map +1 -0
- package/dist/scanner.js +53 -0
- package/dist/scanner.js.map +1 -0
- package/dist/test-utils.d.ts +23 -0
- package/dist/test-utils.d.ts.map +1 -0
- package/dist/test-utils.js +198 -0
- package/dist/test-utils.js.map +1 -0
- package/dist/tsconfig-loader.d.ts +8 -0
- package/dist/tsconfig-loader.d.ts.map +1 -0
- package/dist/tsconfig-loader.js +64 -0
- package/dist/tsconfig-loader.js.map +1 -0
- package/package.json +79 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Sangwoo Hyun
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
# @hexaijs/plugin-contracts-generator
|
|
2
|
+
|
|
3
|
+
> Extract Domain Events, Commands, and Queries from backend source code to generate frontend-compatible contract types
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
`@hexaijs/plugin-contracts-generator` solves the problem of keeping frontend and backend type definitions in sync. In a hexagonal architecture, your backend defines domain events, commands, and queries - but your frontend also needs type-safe access to these message types for API calls, event handling, and validation.
|
|
8
|
+
|
|
9
|
+
Instead of manually duplicating type definitions (which inevitably drift out of sync), this plugin scans your backend source code for specially decorated classes and extracts them into a standalone contracts package. The generated package contains only the public API surface - the message types and their payloads - without any backend implementation details.
|
|
10
|
+
|
|
11
|
+
The plugin works at build time by:
|
|
12
|
+
|
|
13
|
+
1. Scanning TypeScript files for classes decorated with `@PublicEvent()`, `@PublicCommand()`, or `@PublicQuery()`
|
|
14
|
+
2. Resolving all type dependencies (including response types and shared value objects)
|
|
15
|
+
3. Generating a clean contracts package with namespace exports and a MessageRegistry for deserialization
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install @hexaijs/plugin-contracts-generator
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
**Peer dependencies:**
|
|
24
|
+
- `typescript ^5.0.0`
|
|
25
|
+
|
|
26
|
+
## Core Concepts
|
|
27
|
+
|
|
28
|
+
### Decorators
|
|
29
|
+
|
|
30
|
+
The package provides three decorators that mark messages for extraction. These decorators have **no runtime overhead** - they simply tag classes for discovery during the build process.
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
import { PublicEvent, PublicCommand, PublicQuery } from "@hexaijs/plugin-contracts-generator/decorators";
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
**@PublicEvent()** - Marks a domain event as part of the public contract:
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
import { DomainEvent } from "@hexaijs/core";
|
|
40
|
+
import { PublicEvent } from "@hexaijs/plugin-contracts-generator/decorators";
|
|
41
|
+
|
|
42
|
+
@PublicEvent()
|
|
43
|
+
export class OrderPlaced extends DomainEvent<{
|
|
44
|
+
orderId: string;
|
|
45
|
+
customerId: string;
|
|
46
|
+
totalAmount: number;
|
|
47
|
+
}> {
|
|
48
|
+
static readonly type = "order.order-placed";
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
**@PublicCommand()** - Marks a command as part of the public contract:
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
import { PublicCommand } from "@hexaijs/plugin-contracts-generator/decorators";
|
|
56
|
+
|
|
57
|
+
@PublicCommand()
|
|
58
|
+
export class CreateOrderRequest extends BaseRequest<{
|
|
59
|
+
customerId: string;
|
|
60
|
+
items: OrderItem[];
|
|
61
|
+
}> {
|
|
62
|
+
static type = "order.create-order";
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export type CreateOrderResponse = {
|
|
66
|
+
orderId: string;
|
|
67
|
+
};
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**@PublicQuery()** - Marks a query as part of the public contract:
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
import { PublicQuery } from "@hexaijs/plugin-contracts-generator/decorators";
|
|
74
|
+
|
|
75
|
+
@PublicQuery({ response: "OrderDetails" })
|
|
76
|
+
export class GetOrderQuery extends BaseRequest<{
|
|
77
|
+
orderId: string;
|
|
78
|
+
}> {}
|
|
79
|
+
|
|
80
|
+
type OrderDetails = {
|
|
81
|
+
orderId: string;
|
|
82
|
+
status: string;
|
|
83
|
+
items: OrderItem[];
|
|
84
|
+
};
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Each decorator accepts optional configuration:
|
|
88
|
+
- `context` - Override the context name for this message
|
|
89
|
+
- `version` - Specify a version number for versioned events
|
|
90
|
+
- `response` - Explicitly name the response type (for commands/queries)
|
|
91
|
+
|
|
92
|
+
### Configuration
|
|
93
|
+
|
|
94
|
+
Create an `application.config.ts` file in your monorepo root:
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
// application.config.ts
|
|
98
|
+
export default {
|
|
99
|
+
contracts: {
|
|
100
|
+
// Context definitions (required)
|
|
101
|
+
contexts: [
|
|
102
|
+
{
|
|
103
|
+
name: "order",
|
|
104
|
+
sourceDir: "packages/order/src",
|
|
105
|
+
tsconfigPath: "packages/order/tsconfig.json", // optional
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
name: "inventory",
|
|
109
|
+
sourceDir: "packages/inventory/src",
|
|
110
|
+
},
|
|
111
|
+
],
|
|
112
|
+
|
|
113
|
+
// Output package configuration (required)
|
|
114
|
+
outputPackage: {
|
|
115
|
+
name: "@myorg/contracts",
|
|
116
|
+
dir: "packages/contracts",
|
|
117
|
+
},
|
|
118
|
+
|
|
119
|
+
// Path alias rewrite rules (optional)
|
|
120
|
+
pathAliasRewrites: {
|
|
121
|
+
"@myorg/": "@/",
|
|
122
|
+
},
|
|
123
|
+
|
|
124
|
+
// Additional dependencies for contracts package (optional)
|
|
125
|
+
externalDependencies: {
|
|
126
|
+
"@hexaijs/core": "workspace:*",
|
|
127
|
+
},
|
|
128
|
+
|
|
129
|
+
// Response type naming conventions (optional)
|
|
130
|
+
responseNamingConventions: [
|
|
131
|
+
{ messageSuffix: "Command", responseSuffix: "CommandResult" },
|
|
132
|
+
{ messageSuffix: "Query", responseSuffix: "QueryResult" },
|
|
133
|
+
{ messageSuffix: "Request", responseSuffix: "Response" },
|
|
134
|
+
],
|
|
135
|
+
},
|
|
136
|
+
};
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
For monorepos with many packages, use glob patterns to auto-discover contexts:
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
export default {
|
|
143
|
+
contracts: {
|
|
144
|
+
contexts: ["packages/*"], // Matches all directories under packages/
|
|
145
|
+
outputPackage: {
|
|
146
|
+
name: "@myorg/contracts",
|
|
147
|
+
dir: "packages/contracts",
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
};
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Each matched package must have its own `application.config.ts` with `contextName` and `sourceDir`.
|
|
154
|
+
|
|
155
|
+
### Response Types
|
|
156
|
+
|
|
157
|
+
Commands and queries often have associated response types. The generator includes these in the contracts package automatically.
|
|
158
|
+
|
|
159
|
+
**Automatic detection via naming conventions:**
|
|
160
|
+
|
|
161
|
+
```typescript
|
|
162
|
+
// When responseNamingConventions includes { messageSuffix: "Command", responseSuffix: "CommandResult" }
|
|
163
|
+
|
|
164
|
+
@PublicCommand()
|
|
165
|
+
export class CreateOrderCommand extends Message<{ customerId: string }> {}
|
|
166
|
+
|
|
167
|
+
type CreateOrderCommandResult = { // Automatically detected by naming pattern
|
|
168
|
+
orderId: string;
|
|
169
|
+
};
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
**Explicit response option:**
|
|
173
|
+
|
|
174
|
+
```typescript
|
|
175
|
+
@PublicCommand({ response: "OrderCreationResult" })
|
|
176
|
+
export class CreateOrder extends Message<{ customerId: string }> {}
|
|
177
|
+
|
|
178
|
+
type OrderCreationResult = {
|
|
179
|
+
orderId: string;
|
|
180
|
+
createdAt: Date;
|
|
181
|
+
};
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Response types must be in the same file as the command/query. Both `type` aliases and `interface` declarations are supported. The generator adds `export` automatically if the type isn't already exported.
|
|
185
|
+
|
|
186
|
+
### Entry vs Dependency Files
|
|
187
|
+
|
|
188
|
+
The generator handles two types of files differently:
|
|
189
|
+
|
|
190
|
+
**Entry files** (files with `@Public*` decorators) undergo symbol extraction:
|
|
191
|
+
- Only decorated classes matching the specified message types are extracted
|
|
192
|
+
- Handler classes are excluded
|
|
193
|
+
- Response types are included based on naming conventions
|
|
194
|
+
- Unused imports are removed
|
|
195
|
+
|
|
196
|
+
**Dependency files** (imported by entry files) are copied entirely:
|
|
197
|
+
- Supports barrel files (`export * from './module'`)
|
|
198
|
+
- Preserves all exports for transitive dependencies
|
|
199
|
+
- Ensures type dependencies remain intact
|
|
200
|
+
|
|
201
|
+
## Usage
|
|
202
|
+
|
|
203
|
+
### CLI
|
|
204
|
+
|
|
205
|
+
Run the generator from your monorepo root:
|
|
206
|
+
|
|
207
|
+
```bash
|
|
208
|
+
# Uses application.config.ts by default
|
|
209
|
+
npx contracts-generator
|
|
210
|
+
|
|
211
|
+
# Specify config file path
|
|
212
|
+
npx contracts-generator --config ./application.config.ts
|
|
213
|
+
|
|
214
|
+
# Filter by message types
|
|
215
|
+
npx contracts-generator -m event # Extract only events
|
|
216
|
+
npx contracts-generator -m command # Extract only commands
|
|
217
|
+
npx contracts-generator -m query # Extract only queries
|
|
218
|
+
npx contracts-generator -m event,command # Extract events and commands
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### Programmatic API
|
|
222
|
+
|
|
223
|
+
For custom build scripts:
|
|
224
|
+
|
|
225
|
+
```typescript
|
|
226
|
+
import { processContext, ConsoleLogger } from "@hexaijs/plugin-contracts-generator";
|
|
227
|
+
|
|
228
|
+
const result = await processContext({
|
|
229
|
+
contextName: "order",
|
|
230
|
+
sourceDir: "packages/order/src",
|
|
231
|
+
outputDir: "packages/contracts/src",
|
|
232
|
+
pathAliasRewrites: new Map([["@myorg/", "@/"]]),
|
|
233
|
+
messageTypes: ["event", "command"],
|
|
234
|
+
responseNamingConventions: [
|
|
235
|
+
{ messageSuffix: "Command", responseSuffix: "CommandResult" },
|
|
236
|
+
],
|
|
237
|
+
logger: new ConsoleLogger({ level: "info" }),
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
console.log(`Extracted ${result.events.length} events, ${result.commands.length} commands`);
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
For fine-grained control, use the `ContractsPipeline` class which provides step-by-step execution: `scan()`, `parse()`, `resolve()`, `copy()`, and `exportBarrel()`.
|
|
244
|
+
|
|
245
|
+
### Output Structure
|
|
246
|
+
|
|
247
|
+
The generated contracts package follows this structure:
|
|
248
|
+
|
|
249
|
+
```
|
|
250
|
+
contracts/
|
|
251
|
+
├── src/
|
|
252
|
+
│ ├── {context}/
|
|
253
|
+
│ │ ├── events.ts
|
|
254
|
+
│ │ ├── commands.ts
|
|
255
|
+
│ │ ├── types.ts # Dependent types + Response types
|
|
256
|
+
│ │ └── index.ts # Barrel exports
|
|
257
|
+
│ └── index.ts # Namespace exports + MessageRegistry
|
|
258
|
+
├── package.json
|
|
259
|
+
└── tsconfig.json
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
The root `index.ts` uses namespace exports to prevent name collisions:
|
|
263
|
+
|
|
264
|
+
```typescript
|
|
265
|
+
// contracts/src/index.ts
|
|
266
|
+
import { MessageRegistry } from "@hexaijs/plugin-contracts-generator/runtime";
|
|
267
|
+
|
|
268
|
+
export * as order from "./order";
|
|
269
|
+
export * as inventory from "./inventory";
|
|
270
|
+
|
|
271
|
+
export const messageRegistry = new MessageRegistry()
|
|
272
|
+
.register(order.OrderPlaced)
|
|
273
|
+
.register(inventory.StockUpdated);
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
Use namespace exports in your frontend:
|
|
277
|
+
|
|
278
|
+
```typescript
|
|
279
|
+
import { order, messageRegistry } from "@myorg/contracts";
|
|
280
|
+
|
|
281
|
+
// Access types via namespace
|
|
282
|
+
const event = new order.OrderPlaced({ orderId: "123", customerId: "456" });
|
|
283
|
+
|
|
284
|
+
// Deserialize messages from the backend
|
|
285
|
+
const message = messageRegistry.dehydrate(header, body);
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
## Error Handling
|
|
289
|
+
|
|
290
|
+
The generator provides specific error types for different failure modes:
|
|
291
|
+
|
|
292
|
+
```typescript
|
|
293
|
+
import {
|
|
294
|
+
processContext,
|
|
295
|
+
MessageParserError,
|
|
296
|
+
FileReadError,
|
|
297
|
+
ConfigLoadError,
|
|
298
|
+
} from "@hexaijs/plugin-contracts-generator";
|
|
299
|
+
|
|
300
|
+
try {
|
|
301
|
+
await processContext(options);
|
|
302
|
+
} catch (error) {
|
|
303
|
+
if (error instanceof FileReadError) {
|
|
304
|
+
console.error(`Failed to read: ${error.path}`, error.cause);
|
|
305
|
+
} else if (error instanceof ConfigLoadError) {
|
|
306
|
+
console.error(`Config error: ${error.message}`);
|
|
307
|
+
} else if (error instanceof MessageParserError) {
|
|
308
|
+
console.error(`Parser error: ${error.message}`);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
**Error hierarchy:**
|
|
314
|
+
|
|
315
|
+
- `MessageParserError` (base)
|
|
316
|
+
- `ConfigurationError` → `ConfigLoadError`, `TsconfigLoadError`
|
|
317
|
+
- `FileSystemError` → `FileNotFoundError`, `FileReadError`, `FileWriteError`
|
|
318
|
+
- `ParseError` → `JsonParseError`
|
|
319
|
+
- `ResolutionError` → `ModuleResolutionError`
|
|
320
|
+
|
|
321
|
+
## API Highlights
|
|
322
|
+
|
|
323
|
+
| Export | Description |
|
|
324
|
+
|--------|-------------|
|
|
325
|
+
| `processContext(options)` | Main API for extracting and copying contracts |
|
|
326
|
+
| `ContractsPipeline` | Fine-grained control over extraction process |
|
|
327
|
+
| `PublicEvent` | Decorator to mark events for extraction |
|
|
328
|
+
| `PublicCommand` | Decorator to mark commands for extraction |
|
|
329
|
+
| `PublicQuery` | Decorator to mark queries for extraction |
|
|
330
|
+
| `MessageRegistry` | Runtime registry for message deserialization |
|
|
331
|
+
| `ConsoleLogger` | Configurable logger for build output |
|
|
332
|
+
| Error types | `ConfigLoadError`, `FileReadError`, `MessageParserError`, etc. |
|
|
333
|
+
|
|
334
|
+
## See Also
|
|
335
|
+
|
|
336
|
+
- [@hexaijs/core](../core/README.md) - DomainEvent and Message base classes used by contracts
|
|
337
|
+
- [@hexaijs/plugin-application-builder](../plugin-application-builder/README.md) - Companion plugin for handler registration
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import * as ts from "typescript";
|
|
2
|
+
import type { TypeRef, Field } from "./domain";
|
|
3
|
+
export declare function isPrimitiveTypeName(name: string): boolean;
|
|
4
|
+
export declare function parseTypeNode(typeNode: ts.TypeNode): TypeRef;
|
|
5
|
+
export declare function extractFieldsFromMembers(members: ts.NodeArray<ts.TypeElement>): Field[];
|
|
6
|
+
//# sourceMappingURL=ast-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ast-utils.d.ts","sourceRoot":"","sources":["../src/ast-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAEjC,OAAO,KAAK,EACR,OAAO,EAOP,KAAK,EACR,MAAM,UAAU,CAAC;AAgBlB,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,GAAG,OAAO,CAwC5D;AAED,wBAAgB,wBAAwB,CACpC,OAAO,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,WAAW,CAAC,GACtC,KAAK,EAAE,CAsBT"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.isPrimitiveTypeName = isPrimitiveTypeName;
|
|
37
|
+
exports.parseTypeNode = parseTypeNode;
|
|
38
|
+
exports.extractFieldsFromMembers = extractFieldsFromMembers;
|
|
39
|
+
const ts = __importStar(require("typescript"));
|
|
40
|
+
const PRIMITIVE_TYPE_NAMES = new Set([
|
|
41
|
+
"string",
|
|
42
|
+
"number",
|
|
43
|
+
"boolean",
|
|
44
|
+
"void",
|
|
45
|
+
"null",
|
|
46
|
+
"undefined",
|
|
47
|
+
"any",
|
|
48
|
+
"unknown",
|
|
49
|
+
"never",
|
|
50
|
+
"bigint",
|
|
51
|
+
"symbol",
|
|
52
|
+
]);
|
|
53
|
+
function isPrimitiveTypeName(name) {
|
|
54
|
+
return PRIMITIVE_TYPE_NAMES.has(name);
|
|
55
|
+
}
|
|
56
|
+
function parseTypeNode(typeNode) {
|
|
57
|
+
if (typeNode.kind === ts.SyntaxKind.StringKeyword) {
|
|
58
|
+
return { kind: "primitive", name: "string" };
|
|
59
|
+
}
|
|
60
|
+
if (typeNode.kind === ts.SyntaxKind.NumberKeyword) {
|
|
61
|
+
return { kind: "primitive", name: "number" };
|
|
62
|
+
}
|
|
63
|
+
if (typeNode.kind === ts.SyntaxKind.BooleanKeyword) {
|
|
64
|
+
return { kind: "primitive", name: "boolean" };
|
|
65
|
+
}
|
|
66
|
+
if (ts.isArrayTypeNode(typeNode)) {
|
|
67
|
+
const elementType = parseTypeNode(typeNode.elementType);
|
|
68
|
+
return { kind: "array", elementType };
|
|
69
|
+
}
|
|
70
|
+
if (ts.isTypeReferenceNode(typeNode)) {
|
|
71
|
+
const name = typeNode.typeName.getText();
|
|
72
|
+
const typeArguments = typeNode.typeArguments
|
|
73
|
+
? typeNode.typeArguments.map((t) => parseTypeNode(t))
|
|
74
|
+
: undefined;
|
|
75
|
+
return { kind: "reference", name, typeArguments };
|
|
76
|
+
}
|
|
77
|
+
if (ts.isIntersectionTypeNode(typeNode)) {
|
|
78
|
+
const types = typeNode.types.map((t) => parseTypeNode(t));
|
|
79
|
+
return { kind: "intersection", types };
|
|
80
|
+
}
|
|
81
|
+
if (ts.isUnionTypeNode(typeNode)) {
|
|
82
|
+
const types = typeNode.types.map((t) => parseTypeNode(t));
|
|
83
|
+
return { kind: "union", types };
|
|
84
|
+
}
|
|
85
|
+
if (ts.isTypeLiteralNode(typeNode)) {
|
|
86
|
+
const fields = extractFieldsFromMembers(typeNode.members);
|
|
87
|
+
return { kind: "object", fields };
|
|
88
|
+
}
|
|
89
|
+
return { kind: "reference", name: typeNode.getText() };
|
|
90
|
+
}
|
|
91
|
+
function extractFieldsFromMembers(members) {
|
|
92
|
+
const fields = [];
|
|
93
|
+
for (const member of members) {
|
|
94
|
+
if (ts.isPropertySignature(member) && member.name) {
|
|
95
|
+
const fieldName = member.name.getText();
|
|
96
|
+
const fieldType = member.type
|
|
97
|
+
? parseTypeNode(member.type)
|
|
98
|
+
: { kind: "primitive", name: "any" };
|
|
99
|
+
const optional = !!member.questionToken;
|
|
100
|
+
const readonly = member.modifiers?.some((m) => m.kind === ts.SyntaxKind.ReadonlyKeyword) ?? false;
|
|
101
|
+
fields.push({
|
|
102
|
+
name: fieldName,
|
|
103
|
+
type: fieldType,
|
|
104
|
+
optional,
|
|
105
|
+
readonly,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return fields;
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=ast-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ast-utils.js","sourceRoot":"","sources":["../src/ast-utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as ts from "typescript";
|
|
2
|
+
export declare function hasDecorator(node: ts.ClassDeclaration, decoratorName: string): boolean;
|
|
3
|
+
export interface DecoratorOptions {
|
|
4
|
+
response?: string;
|
|
5
|
+
context?: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Extracts options from a decorator call expression.
|
|
9
|
+
* For example, @PublicCommand({ response: 'CreateUserResult' }) returns { response: 'CreateUserResult' }
|
|
10
|
+
*/
|
|
11
|
+
export declare function getDecoratorOptions(node: ts.ClassDeclaration, decoratorName: string): DecoratorOptions | undefined;
|
|
12
|
+
export declare function hasExportModifier(node: ts.Node): boolean;
|
|
13
|
+
export declare function extractClassSourceText(node: ts.ClassDeclaration, sourceCode: string): string;
|
|
14
|
+
export declare function getBaseClassName(node: ts.ClassDeclaration): string | undefined;
|
|
15
|
+
export declare function collectClassReferences(node: ts.ClassDeclaration): Set<string>;
|
|
16
|
+
//# sourceMappingURL=class-analyzer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"class-analyzer.d.ts","sourceRoot":"","sources":["../src/class-analyzer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAIjC,wBAAgB,YAAY,CACxB,IAAI,EAAE,EAAE,CAAC,gBAAgB,EACzB,aAAa,EAAE,MAAM,GACtB,OAAO,CAaT;AAED,MAAM,WAAW,gBAAgB;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAC/B,IAAI,EAAE,EAAE,CAAC,gBAAgB,EACzB,aAAa,EAAE,MAAM,GACtB,gBAAgB,GAAG,SAAS,CAmC9B;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,GAAG,OAAO,CAOxD;AAED,wBAAgB,sBAAsB,CAClC,IAAI,EAAE,EAAE,CAAC,gBAAgB,EACzB,UAAU,EAAE,MAAM,GACnB,MAAM,CAMR;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,EAAE,CAAC,gBAAgB,GAAG,MAAM,GAAG,SAAS,CAe9E;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,EAAE,CAAC,gBAAgB,GAAG,GAAG,CAAC,MAAM,CAAC,CAgC7E"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.hasDecorator = hasDecorator;
|
|
37
|
+
exports.getDecoratorOptions = getDecoratorOptions;
|
|
38
|
+
exports.hasExportModifier = hasExportModifier;
|
|
39
|
+
exports.extractClassSourceText = extractClassSourceText;
|
|
40
|
+
exports.getBaseClassName = getBaseClassName;
|
|
41
|
+
exports.collectClassReferences = collectClassReferences;
|
|
42
|
+
const ts = __importStar(require("typescript"));
|
|
43
|
+
const ast_utils_1 = require("./ast-utils");
|
|
44
|
+
function hasDecorator(node, decoratorName) {
|
|
45
|
+
const decorators = ts.getDecorators(node);
|
|
46
|
+
if (!decorators)
|
|
47
|
+
return false;
|
|
48
|
+
return decorators.some((decorator) => {
|
|
49
|
+
if (ts.isCallExpression(decorator.expression)) {
|
|
50
|
+
const expr = decorator.expression.expression;
|
|
51
|
+
if (ts.isIdentifier(expr)) {
|
|
52
|
+
return expr.text === decoratorName;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return false;
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Extracts options from a decorator call expression.
|
|
60
|
+
* For example, @PublicCommand({ response: 'CreateUserResult' }) returns { response: 'CreateUserResult' }
|
|
61
|
+
*/
|
|
62
|
+
function getDecoratorOptions(node, decoratorName) {
|
|
63
|
+
const decorators = ts.getDecorators(node);
|
|
64
|
+
if (!decorators)
|
|
65
|
+
return undefined;
|
|
66
|
+
for (const decorator of decorators) {
|
|
67
|
+
if (!ts.isCallExpression(decorator.expression))
|
|
68
|
+
continue;
|
|
69
|
+
const expr = decorator.expression.expression;
|
|
70
|
+
if (!ts.isIdentifier(expr) || expr.text !== decoratorName)
|
|
71
|
+
continue;
|
|
72
|
+
// Found the decorator, now extract options from the first argument
|
|
73
|
+
const args = decorator.expression.arguments;
|
|
74
|
+
if (args.length === 0)
|
|
75
|
+
return {};
|
|
76
|
+
const firstArg = args[0];
|
|
77
|
+
if (!ts.isObjectLiteralExpression(firstArg))
|
|
78
|
+
return {};
|
|
79
|
+
const options = {};
|
|
80
|
+
for (const prop of firstArg.properties) {
|
|
81
|
+
if (!ts.isPropertyAssignment(prop))
|
|
82
|
+
continue;
|
|
83
|
+
if (!ts.isIdentifier(prop.name))
|
|
84
|
+
continue;
|
|
85
|
+
const propName = prop.name.text;
|
|
86
|
+
if (propName === "response" && ts.isStringLiteral(prop.initializer)) {
|
|
87
|
+
options.response = prop.initializer.text;
|
|
88
|
+
}
|
|
89
|
+
else if (propName === "context" && ts.isStringLiteral(prop.initializer)) {
|
|
90
|
+
options.context = prop.initializer.text;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return options;
|
|
94
|
+
}
|
|
95
|
+
return undefined;
|
|
96
|
+
}
|
|
97
|
+
function hasExportModifier(node) {
|
|
98
|
+
const modifiers = ts.canHaveModifiers(node)
|
|
99
|
+
? ts.getModifiers(node)
|
|
100
|
+
: undefined;
|
|
101
|
+
return (modifiers?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword) ?? false);
|
|
102
|
+
}
|
|
103
|
+
function extractClassSourceText(node, sourceCode) {
|
|
104
|
+
const fullStart = node.getFullStart();
|
|
105
|
+
const end = node.getEnd();
|
|
106
|
+
let sourceText = sourceCode.slice(fullStart, end);
|
|
107
|
+
sourceText = sourceText.replace(/^\s*\n/, "");
|
|
108
|
+
return sourceText;
|
|
109
|
+
}
|
|
110
|
+
function getBaseClassName(node) {
|
|
111
|
+
if (!node.heritageClauses)
|
|
112
|
+
return undefined;
|
|
113
|
+
for (const clause of node.heritageClauses) {
|
|
114
|
+
if (clause.token === ts.SyntaxKind.ExtendsKeyword) {
|
|
115
|
+
const firstType = clause.types[0];
|
|
116
|
+
if (firstType && ts.isExpressionWithTypeArguments(firstType)) {
|
|
117
|
+
const expr = firstType.expression;
|
|
118
|
+
if (ts.isIdentifier(expr)) {
|
|
119
|
+
return expr.text;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return undefined;
|
|
125
|
+
}
|
|
126
|
+
function collectClassReferences(node) {
|
|
127
|
+
const references = new Set();
|
|
128
|
+
const baseClass = getBaseClassName(node);
|
|
129
|
+
if (baseClass) {
|
|
130
|
+
references.add(baseClass);
|
|
131
|
+
}
|
|
132
|
+
const visitNode = (child) => {
|
|
133
|
+
if (ts.isTypeReferenceNode(child)) {
|
|
134
|
+
const name = child.typeName.getText();
|
|
135
|
+
if (!(0, ast_utils_1.isPrimitiveTypeName)(name)) {
|
|
136
|
+
references.add(name);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
else if (ts.isIdentifier(child)) {
|
|
140
|
+
const parent = child.parent;
|
|
141
|
+
if (parent &&
|
|
142
|
+
(ts.isTypeReferenceNode(parent) ||
|
|
143
|
+
ts.isExpressionWithTypeArguments(parent))) {
|
|
144
|
+
const name = child.text;
|
|
145
|
+
if (!(0, ast_utils_1.isPrimitiveTypeName)(name)) {
|
|
146
|
+
references.add(name);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
ts.forEachChild(child, visitNode);
|
|
151
|
+
};
|
|
152
|
+
ts.forEachChild(node, visitNode);
|
|
153
|
+
return references;
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=class-analyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"class-analyzer.js","sourceRoot":"","sources":["../src/class-analyzer.ts"],"names":[],"mappings":"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"}
|