@hexaijs/plugin-contracts-generator 0.2.0 → 0.2.2

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.
Files changed (98) hide show
  1. package/README.md +33 -25
  2. package/dist/ast-utils.d.ts +6 -0
  3. package/dist/ast-utils.d.ts.map +1 -0
  4. package/dist/ast-utils.js +73 -0
  5. package/dist/ast-utils.js.map +1 -0
  6. package/dist/class-analyzer.d.ts +16 -0
  7. package/dist/class-analyzer.d.ts.map +1 -0
  8. package/dist/class-analyzer.js +114 -0
  9. package/dist/class-analyzer.js.map +1 -0
  10. package/dist/cli.d.ts +32 -1
  11. package/dist/cli.d.ts.map +1 -0
  12. package/dist/cli.js +226 -2480
  13. package/dist/cli.js.map +1 -1
  14. package/dist/config-loader.d.ts +24 -0
  15. package/dist/config-loader.d.ts.map +1 -0
  16. package/dist/config-loader.js +126 -0
  17. package/dist/config-loader.js.map +1 -0
  18. package/dist/context-config.d.ts +44 -0
  19. package/dist/context-config.d.ts.map +1 -0
  20. package/dist/context-config.js +140 -0
  21. package/dist/context-config.js.map +1 -0
  22. package/dist/domain/index.d.ts +2 -0
  23. package/dist/domain/index.d.ts.map +1 -0
  24. package/dist/domain/index.js +2 -0
  25. package/dist/domain/index.js.map +1 -0
  26. package/dist/domain/types.d.ts +182 -0
  27. package/dist/domain/types.d.ts.map +1 -0
  28. package/dist/domain/types.js +49 -0
  29. package/dist/domain/types.js.map +1 -0
  30. package/dist/errors.d.ts +72 -0
  31. package/dist/errors.d.ts.map +1 -0
  32. package/dist/errors.js +112 -0
  33. package/dist/errors.js.map +1 -0
  34. package/dist/file-copier.d.ts +84 -0
  35. package/dist/file-copier.d.ts.map +1 -0
  36. package/dist/file-copier.js +721 -0
  37. package/dist/file-copier.js.map +1 -0
  38. package/dist/file-graph-resolver.d.ts +42 -0
  39. package/dist/file-graph-resolver.d.ts.map +1 -0
  40. package/dist/file-graph-resolver.js +138 -0
  41. package/dist/file-graph-resolver.js.map +1 -0
  42. package/dist/file-system.d.ts +26 -0
  43. package/dist/file-system.d.ts.map +1 -0
  44. package/dist/file-system.js +30 -0
  45. package/dist/file-system.js.map +1 -0
  46. package/dist/hexai-plugin.d.ts +16 -0
  47. package/dist/hexai-plugin.d.ts.map +1 -0
  48. package/dist/hexai-plugin.js +56 -0
  49. package/dist/hexai-plugin.js.map +1 -0
  50. package/dist/import-analyzer.d.ts +6 -0
  51. package/dist/import-analyzer.d.ts.map +1 -0
  52. package/dist/import-analyzer.js +39 -0
  53. package/dist/import-analyzer.js.map +1 -0
  54. package/dist/index.d.ts +39 -531
  55. package/dist/index.d.ts.map +1 -0
  56. package/dist/index.js +56 -2739
  57. package/dist/index.js.map +1 -1
  58. package/dist/logger.d.ts +21 -0
  59. package/dist/logger.d.ts.map +1 -0
  60. package/dist/logger.js +43 -0
  61. package/dist/logger.js.map +1 -0
  62. package/dist/parser.d.ts +32 -0
  63. package/dist/parser.d.ts.map +1 -0
  64. package/dist/parser.js +202 -0
  65. package/dist/parser.js.map +1 -0
  66. package/dist/pipeline.d.ts +57 -0
  67. package/dist/pipeline.d.ts.map +1 -0
  68. package/dist/pipeline.js +148 -0
  69. package/dist/pipeline.js.map +1 -0
  70. package/dist/reexport-generator.d.ts +81 -0
  71. package/dist/reexport-generator.d.ts.map +1 -0
  72. package/dist/reexport-generator.js +171 -0
  73. package/dist/reexport-generator.js.map +1 -0
  74. package/dist/registry-generator.d.ts +27 -0
  75. package/dist/registry-generator.d.ts.map +1 -0
  76. package/dist/registry-generator.js +104 -0
  77. package/dist/registry-generator.js.map +1 -0
  78. package/dist/runtime/index.d.ts +2 -23
  79. package/dist/runtime/index.d.ts.map +1 -0
  80. package/dist/runtime/index.js +1 -38
  81. package/dist/runtime/index.js.map +1 -1
  82. package/dist/runtime/message-registry.d.ts +23 -0
  83. package/dist/runtime/message-registry.d.ts.map +1 -0
  84. package/dist/runtime/message-registry.js +35 -0
  85. package/dist/runtime/message-registry.js.map +1 -0
  86. package/dist/scanner.d.ts +21 -0
  87. package/dist/scanner.d.ts.map +1 -0
  88. package/dist/scanner.js +49 -0
  89. package/dist/scanner.js.map +1 -0
  90. package/dist/test-utils.d.ts +23 -0
  91. package/dist/test-utils.d.ts.map +1 -0
  92. package/dist/test-utils.js +188 -0
  93. package/dist/test-utils.js.map +1 -0
  94. package/package.json +69 -64
  95. package/dist/cli-CPg-O4OY.d.ts +0 -214
  96. package/dist/decorators/index.d.ts +0 -144
  97. package/dist/decorators/index.js +0 -28
  98. package/dist/decorators/index.js.map +0 -1
package/README.md CHANGED
@@ -30,14 +30,14 @@ npm install @hexaijs/plugin-contracts-generator
30
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
31
 
32
32
  ```typescript
33
- import { PublicEvent, PublicCommand, PublicQuery } from "@hexaijs/plugin-contracts-generator/decorators";
33
+ import { PublicEvent, PublicCommand, PublicQuery } from "@hexaijs/contracts/decorators";
34
34
  ```
35
35
 
36
36
  **@PublicEvent()** - Marks a domain event as part of the public contract:
37
37
 
38
38
  ```typescript
39
39
  import { DomainEvent } from "@hexaijs/core";
40
- import { PublicEvent } from "@hexaijs/plugin-contracts-generator/decorators";
40
+ import { PublicEvent } from "@hexaijs/contracts/decorators";
41
41
 
42
42
  @PublicEvent()
43
43
  export class OrderPlaced extends DomainEvent<{
@@ -52,7 +52,7 @@ export class OrderPlaced extends DomainEvent<{
52
52
  **@PublicCommand()** - Marks a command as part of the public contract:
53
53
 
54
54
  ```typescript
55
- import { PublicCommand } from "@hexaijs/plugin-contracts-generator/decorators";
55
+ import { PublicCommand } from "@hexaijs/contracts/decorators";
56
56
 
57
57
  @PublicCommand()
58
58
  export class CreateOrderRequest extends BaseRequest<{
@@ -70,7 +70,7 @@ export type CreateOrderResponse = {
70
70
  **@PublicQuery()** - Marks a query as part of the public contract:
71
71
 
72
72
  ```typescript
73
- import { PublicQuery } from "@hexaijs/plugin-contracts-generator/decorators";
73
+ import { PublicQuery } from "@hexaijs/contracts/decorators";
74
74
 
75
75
  @PublicQuery({ response: "OrderDetails" })
76
76
  export class GetOrderQuery extends BaseRequest<{
@@ -101,21 +101,16 @@ export default {
101
101
  contexts: [
102
102
  {
103
103
  name: "order",
104
- sourceDir: "packages/order/src",
105
- tsconfigPath: "packages/order/tsconfig.json", // optional
104
+ path: "packages/order",
105
+ tsconfigPath: "tsconfig.json", // optional, relative to path
106
106
  },
107
107
  {
108
108
  name: "inventory",
109
- sourceDir: "packages/inventory/src",
109
+ path: "packages/inventory",
110
+ sourceDir: "lib", // optional, defaults to "src"
110
111
  },
111
112
  ],
112
113
 
113
- // Output package configuration (required)
114
- outputPackage: {
115
- name: "@myorg/contracts",
116
- dir: "packages/contracts",
117
- },
118
-
119
114
  // Path alias rewrite rules (optional)
120
115
  pathAliasRewrites: {
121
116
  "@myorg/": "@/",
@@ -132,20 +127,30 @@ export default {
132
127
  { messageSuffix: "Query", responseSuffix: "QueryResult" },
133
128
  { messageSuffix: "Request", responseSuffix: "Response" },
134
129
  ],
130
+
131
+ // Custom decorator names (optional, defaults shown)
132
+ decoratorNames: {
133
+ event: "PublicEvent",
134
+ command: "PublicCommand",
135
+ query: "PublicQuery",
136
+ },
137
+
138
+ // Strip decorators from generated output (optional, default: true)
139
+ removeDecorators: true,
135
140
  },
136
141
  };
137
142
  ```
138
143
 
144
+ Each context requires `name` and `path`. The `path` is the base directory of the context (relative to the config file). Within that directory:
145
+ - `sourceDir` defaults to `"src"` (resolved relative to `path`)
146
+ - `tsconfigPath` defaults to `"tsconfig.json"` (resolved relative to `path`)
147
+
139
148
  For monorepos with many packages, use glob patterns to auto-discover contexts:
140
149
 
141
150
  ```typescript
142
151
  export default {
143
152
  contracts: {
144
153
  contexts: ["packages/*"], // Matches all directories under packages/
145
- outputPackage: {
146
- name: "@myorg/contracts",
147
- dir: "packages/contracts",
148
- },
149
154
  },
150
155
  };
151
156
  ```
@@ -208,17 +213,19 @@ The generator handles two types of files differently:
208
213
  Run the generator from your monorepo root:
209
214
 
210
215
  ```bash
211
- # Uses application.config.ts by default
212
- npx contracts-generator
216
+ # Required: --output-dir (-o) specifies where contracts are generated
217
+ npx contracts-generator --output-dir packages/contracts/src
213
218
 
214
- # Specify config file path
215
- npx contracts-generator --config ./application.config.ts
219
+ # Specify config file path (default: application.config.ts)
220
+ npx contracts-generator -o packages/contracts/src --config ./app.config.ts
216
221
 
217
222
  # Filter by message types
218
- npx contracts-generator -m event # Extract only events
219
- npx contracts-generator -m command # Extract only commands
220
- npx contracts-generator -m query # Extract only queries
221
- npx contracts-generator -m event,command # Extract events and commands
223
+ npx contracts-generator -o packages/contracts/src -m event # Extract only events
224
+ npx contracts-generator -o packages/contracts/src -m command # Extract only commands
225
+ npx contracts-generator -o packages/contracts/src -m event,command # Extract events and commands
226
+
227
+ # Generate with message registry (index.ts)
228
+ npx contracts-generator -o packages/contracts/src --generate-message-registry
222
229
  ```
223
230
 
224
231
  ### Programmatic API
@@ -255,6 +262,7 @@ contracts/
255
262
  │ ├── {context}/
256
263
  │ │ ├── events.ts
257
264
  │ │ ├── commands.ts
265
+ │ │ ├── queries.ts
258
266
  │ │ ├── types.ts # Dependent types + Response types
259
267
  │ │ └── index.ts # Barrel exports
260
268
  │ └── index.ts # Namespace exports + MessageRegistry
@@ -0,0 +1,6 @@
1
+ import * as ts from "typescript";
2
+ import type { TypeRef, Field } from "./domain/index.js";
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,mBAAmB,CAAC;AAgB3B,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,73 @@
1
+ import * as ts from "typescript";
2
+ const PRIMITIVE_TYPE_NAMES = new Set([
3
+ "string",
4
+ "number",
5
+ "boolean",
6
+ "void",
7
+ "null",
8
+ "undefined",
9
+ "any",
10
+ "unknown",
11
+ "never",
12
+ "bigint",
13
+ "symbol",
14
+ ]);
15
+ export function isPrimitiveTypeName(name) {
16
+ return PRIMITIVE_TYPE_NAMES.has(name);
17
+ }
18
+ export function parseTypeNode(typeNode) {
19
+ if (typeNode.kind === ts.SyntaxKind.StringKeyword) {
20
+ return { kind: "primitive", name: "string" };
21
+ }
22
+ if (typeNode.kind === ts.SyntaxKind.NumberKeyword) {
23
+ return { kind: "primitive", name: "number" };
24
+ }
25
+ if (typeNode.kind === ts.SyntaxKind.BooleanKeyword) {
26
+ return { kind: "primitive", name: "boolean" };
27
+ }
28
+ if (ts.isArrayTypeNode(typeNode)) {
29
+ const elementType = parseTypeNode(typeNode.elementType);
30
+ return { kind: "array", elementType };
31
+ }
32
+ if (ts.isTypeReferenceNode(typeNode)) {
33
+ const name = typeNode.typeName.getText();
34
+ const typeArguments = typeNode.typeArguments
35
+ ? typeNode.typeArguments.map((t) => parseTypeNode(t))
36
+ : undefined;
37
+ return { kind: "reference", name, typeArguments };
38
+ }
39
+ if (ts.isIntersectionTypeNode(typeNode)) {
40
+ const types = typeNode.types.map((t) => parseTypeNode(t));
41
+ return { kind: "intersection", types };
42
+ }
43
+ if (ts.isUnionTypeNode(typeNode)) {
44
+ const types = typeNode.types.map((t) => parseTypeNode(t));
45
+ return { kind: "union", types };
46
+ }
47
+ if (ts.isTypeLiteralNode(typeNode)) {
48
+ const fields = extractFieldsFromMembers(typeNode.members);
49
+ return { kind: "object", fields };
50
+ }
51
+ return { kind: "reference", name: typeNode.getText() };
52
+ }
53
+ export function extractFieldsFromMembers(members) {
54
+ const fields = [];
55
+ for (const member of members) {
56
+ if (ts.isPropertySignature(member) && member.name) {
57
+ const fieldName = member.name.getText();
58
+ const fieldType = member.type
59
+ ? parseTypeNode(member.type)
60
+ : { kind: "primitive", name: "any" };
61
+ const optional = !!member.questionToken;
62
+ const readonly = member.modifiers?.some((m) => m.kind === ts.SyntaxKind.ReadonlyKeyword) ?? false;
63
+ fields.push({
64
+ name: fieldName,
65
+ type: fieldType,
66
+ optional,
67
+ readonly,
68
+ });
69
+ }
70
+ }
71
+ return fields;
72
+ }
73
+ //# 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,114 @@
1
+ import * as ts from "typescript";
2
+ import { isPrimitiveTypeName } from "./ast-utils.js";
3
+ export function hasDecorator(node, decoratorName) {
4
+ const decorators = ts.getDecorators(node);
5
+ if (!decorators)
6
+ return false;
7
+ return decorators.some((decorator) => {
8
+ if (ts.isCallExpression(decorator.expression)) {
9
+ const expr = decorator.expression.expression;
10
+ if (ts.isIdentifier(expr)) {
11
+ return expr.text === decoratorName;
12
+ }
13
+ }
14
+ return false;
15
+ });
16
+ }
17
+ /**
18
+ * Extracts options from a decorator call expression.
19
+ * For example, @PublicCommand({ response: 'CreateUserResult' }) returns { response: 'CreateUserResult' }
20
+ */
21
+ export function getDecoratorOptions(node, decoratorName) {
22
+ const decorators = ts.getDecorators(node);
23
+ if (!decorators)
24
+ return undefined;
25
+ for (const decorator of decorators) {
26
+ if (!ts.isCallExpression(decorator.expression))
27
+ continue;
28
+ const expr = decorator.expression.expression;
29
+ if (!ts.isIdentifier(expr) || expr.text !== decoratorName)
30
+ continue;
31
+ // Found the decorator, now extract options from the first argument
32
+ const args = decorator.expression.arguments;
33
+ if (args.length === 0)
34
+ return {};
35
+ const firstArg = args[0];
36
+ if (!ts.isObjectLiteralExpression(firstArg))
37
+ return {};
38
+ const options = {};
39
+ for (const prop of firstArg.properties) {
40
+ if (!ts.isPropertyAssignment(prop))
41
+ continue;
42
+ if (!ts.isIdentifier(prop.name))
43
+ continue;
44
+ const propName = prop.name.text;
45
+ if (propName === "response" && ts.isStringLiteral(prop.initializer)) {
46
+ options.response = prop.initializer.text;
47
+ }
48
+ else if (propName === "context" && ts.isStringLiteral(prop.initializer)) {
49
+ options.context = prop.initializer.text;
50
+ }
51
+ }
52
+ return options;
53
+ }
54
+ return undefined;
55
+ }
56
+ export function hasExportModifier(node) {
57
+ const modifiers = ts.canHaveModifiers(node)
58
+ ? ts.getModifiers(node)
59
+ : undefined;
60
+ return (modifiers?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword) ?? false);
61
+ }
62
+ export function extractClassSourceText(node, sourceCode) {
63
+ const fullStart = node.getFullStart();
64
+ const end = node.getEnd();
65
+ let sourceText = sourceCode.slice(fullStart, end);
66
+ sourceText = sourceText.replace(/^\s*\n/, "");
67
+ return sourceText;
68
+ }
69
+ export function getBaseClassName(node) {
70
+ if (!node.heritageClauses)
71
+ return undefined;
72
+ for (const clause of node.heritageClauses) {
73
+ if (clause.token === ts.SyntaxKind.ExtendsKeyword) {
74
+ const firstType = clause.types[0];
75
+ if (firstType && ts.isExpressionWithTypeArguments(firstType)) {
76
+ const expr = firstType.expression;
77
+ if (ts.isIdentifier(expr)) {
78
+ return expr.text;
79
+ }
80
+ }
81
+ }
82
+ }
83
+ return undefined;
84
+ }
85
+ export function collectClassReferences(node) {
86
+ const references = new Set();
87
+ const baseClass = getBaseClassName(node);
88
+ if (baseClass) {
89
+ references.add(baseClass);
90
+ }
91
+ const visitNode = (child) => {
92
+ if (ts.isTypeReferenceNode(child)) {
93
+ const name = child.typeName.getText();
94
+ if (!isPrimitiveTypeName(name)) {
95
+ references.add(name);
96
+ }
97
+ }
98
+ else if (ts.isIdentifier(child)) {
99
+ const parent = child.parent;
100
+ if (parent &&
101
+ (ts.isTypeReferenceNode(parent) ||
102
+ ts.isExpressionWithTypeArguments(parent))) {
103
+ const name = child.text;
104
+ if (!isPrimitiveTypeName(name)) {
105
+ references.add(name);
106
+ }
107
+ }
108
+ }
109
+ ts.forEachChild(child, visitNode);
110
+ };
111
+ ts.forEachChild(node, visitNode);
112
+ return references;
113
+ }
114
+ //# 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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"}
package/dist/cli.d.ts CHANGED
@@ -1,2 +1,33 @@
1
1
  #!/usr/bin/env node
2
- export { b as ContractsPluginConfig, N as RunWithConfigOptions, V as run, W as runWithConfig } from './cli-CPg-O4OY.js';
2
+ import type { InputContextConfig } from "./context-config.js";
3
+ import type { MessageType, DecoratorNames, ResponseNamingConvention } from "./domain/types.js";
4
+ /**
5
+ * Options for runWithConfig when config is provided directly.
6
+ */
7
+ export interface RunWithConfigOptions {
8
+ outputDir: string;
9
+ messageTypes?: MessageType[];
10
+ generateMessageRegistry?: boolean;
11
+ }
12
+ /**
13
+ * Plugin configuration structure for contracts generator.
14
+ * This is the config passed from hexai.config.ts.
15
+ */
16
+ export interface ContractsPluginConfig {
17
+ contexts: Array<string | InputContextConfig>;
18
+ pathAliasRewrites?: Record<string, string>;
19
+ externalDependencies?: Record<string, string>;
20
+ decoratorNames?: DecoratorNames;
21
+ responseNamingConventions?: ResponseNamingConvention[];
22
+ removeDecorators?: boolean;
23
+ }
24
+ export declare function run(args: string[]): Promise<void>;
25
+ /**
26
+ * Run contracts generator with config provided directly.
27
+ * This is used by the hexai CLI integration where config comes from hexai.config.ts.
28
+ *
29
+ * @param options - CLI options (outputDir, messageTypes, generateMessageRegistry)
30
+ * @param pluginConfig - Plugin configuration from hexai.config.ts
31
+ */
32
+ export declare function runWithConfig(options: RunWithConfigOptions, pluginConfig: ContractsPluginConfig): Promise<void>;
33
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAKA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAK9D,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAsB/F;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,WAAW,EAAE,CAAC;IAC7B,uBAAuB,CAAC,EAAE,OAAO,CAAC;CACrC;AAED;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IAClC,QAAQ,EAAE,KAAK,CAAC,MAAM,GAAG,kBAAkB,CAAC,CAAC;IAC7C,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3C,oBAAoB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9C,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,yBAAyB,CAAC,EAAE,wBAAwB,EAAE,CAAC;IACvD,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAwKD,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAoDvD;AAsBD;;;;;;GAMG;AACH,wBAAsB,aAAa,CAC/B,OAAO,EAAE,oBAAoB,EAC7B,YAAY,EAAE,qBAAqB,GACpC,OAAO,CAAC,IAAI,CAAC,CA6Cf"}