@hexaijs/plugin-application-builder 0.1.1 → 0.2.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.
Files changed (53) hide show
  1. package/dist/cli.d.ts +0 -2
  2. package/dist/cli.js +569 -52
  3. package/dist/cli.js.map +1 -1
  4. package/dist/decorators/index.d.ts +8 -6
  5. package/dist/decorators/index.js +13 -31
  6. package/dist/decorators/index.js.map +1 -1
  7. package/dist/index.d.ts +48 -5
  8. package/dist/index.js +596 -15
  9. package/dist/index.js.map +1 -1
  10. package/package.json +24 -12
  11. package/dist/application-builder-generator.d.ts +0 -15
  12. package/dist/application-builder-generator.d.ts.map +0 -1
  13. package/dist/application-builder-generator.js +0 -81
  14. package/dist/application-builder-generator.js.map +0 -1
  15. package/dist/cli.d.ts.map +0 -1
  16. package/dist/code-generator.d.ts +0 -30
  17. package/dist/code-generator.d.ts.map +0 -1
  18. package/dist/code-generator.js +0 -131
  19. package/dist/code-generator.js.map +0 -1
  20. package/dist/config-loader.d.ts +0 -3
  21. package/dist/config-loader.d.ts.map +0 -1
  22. package/dist/config-loader.js +0 -65
  23. package/dist/config-loader.js.map +0 -1
  24. package/dist/config.d.ts +0 -13
  25. package/dist/config.d.ts.map +0 -1
  26. package/dist/config.js +0 -31
  27. package/dist/config.js.map +0 -1
  28. package/dist/decorators/index.d.ts.map +0 -1
  29. package/dist/errors.d.ts +0 -13
  30. package/dist/errors.d.ts.map +0 -1
  31. package/dist/errors.js +0 -32
  32. package/dist/errors.js.map +0 -1
  33. package/dist/hexai-plugin.d.ts +0 -30
  34. package/dist/hexai-plugin.d.ts.map +0 -1
  35. package/dist/hexai-plugin.js +0 -81
  36. package/dist/hexai-plugin.js.map +0 -1
  37. package/dist/index.d.ts.map +0 -1
  38. package/dist/main.d.ts +0 -6
  39. package/dist/main.d.ts.map +0 -1
  40. package/dist/main.js +0 -53
  41. package/dist/main.js.map +0 -1
  42. package/dist/metadata-extractor.d.ts +0 -25
  43. package/dist/metadata-extractor.d.ts.map +0 -1
  44. package/dist/metadata-extractor.js +0 -247
  45. package/dist/metadata-extractor.js.map +0 -1
  46. package/dist/test.d.ts +0 -15
  47. package/dist/test.d.ts.map +0 -1
  48. package/dist/test.js +0 -104
  49. package/dist/test.js.map +0 -1
  50. package/dist/types.d.ts +0 -22
  51. package/dist/types.d.ts.map +0 -1
  52. package/dist/types.js +0 -3
  53. package/dist/types.js.map +0 -1
package/dist/index.js CHANGED
@@ -1,16 +1,597 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.cliPlugin = exports.DuplicateQueryHandlerError = exports.DuplicateEventHandlerError = exports.DuplicateCommandHandlerError = exports.QueryHandlerMarker = exports.EventHandlerMarker = exports.CommandHandlerMarker = exports.generateApplicationBuilder = void 0;
4
- var main_1 = require("./main");
5
- Object.defineProperty(exports, "generateApplicationBuilder", { enumerable: true, get: function () { return main_1.generateApplicationBuilder; } });
6
- var decorators_1 = require("./decorators");
7
- Object.defineProperty(exports, "CommandHandlerMarker", { enumerable: true, get: function () { return decorators_1.CommandHandlerMarker; } });
8
- Object.defineProperty(exports, "EventHandlerMarker", { enumerable: true, get: function () { return decorators_1.EventHandlerMarker; } });
9
- Object.defineProperty(exports, "QueryHandlerMarker", { enumerable: true, get: function () { return decorators_1.QueryHandlerMarker; } });
10
- var errors_1 = require("./errors");
11
- Object.defineProperty(exports, "DuplicateCommandHandlerError", { enumerable: true, get: function () { return errors_1.DuplicateCommandHandlerError; } });
12
- Object.defineProperty(exports, "DuplicateEventHandlerError", { enumerable: true, get: function () { return errors_1.DuplicateEventHandlerError; } });
13
- Object.defineProperty(exports, "DuplicateQueryHandlerError", { enumerable: true, get: function () { return errors_1.DuplicateQueryHandlerError; } });
14
- var hexai_plugin_1 = require("./hexai-plugin");
15
- Object.defineProperty(exports, "cliPlugin", { enumerable: true, get: function () { return hexai_plugin_1.cliPlugin; } });
1
+ import * as path from 'path';
2
+ import * as fs from 'fs';
3
+ import { glob } from 'glob';
4
+ import * as ts from 'typescript';
5
+
6
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
7
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
8
+ }) : x)(function(x) {
9
+ if (typeof require !== "undefined") return require.apply(this, arguments);
10
+ throw Error('Dynamic require of "' + x + '" is not supported');
11
+ });
12
+
13
+ // src/errors.ts
14
+ var DuplicateCommandHandlerError = class extends Error {
15
+ constructor(commandClassName, handlers) {
16
+ super(
17
+ `Duplicate command handlers for "${commandClassName}": ${handlers.join(", ")}`
18
+ );
19
+ this.name = "DuplicateCommandHandlerError";
20
+ }
21
+ };
22
+ var DuplicateEventHandlerError = class extends Error {
23
+ constructor(eventName, handlers) {
24
+ super(
25
+ `Duplicate event handlers for event "${eventName}": ${handlers.join(", ")}`
26
+ );
27
+ this.name = "DuplicateEventHandlerError";
28
+ }
29
+ };
30
+ var DuplicateQueryHandlerError = class extends Error {
31
+ constructor(queryClassName, handlers) {
32
+ super(
33
+ `Duplicate query handlers for "${queryClassName}": ${handlers.join(", ")}`
34
+ );
35
+ this.name = "DuplicateQueryHandlerError";
36
+ }
37
+ };
38
+ var MessageClassNotFoundError = class extends Error {
39
+ constructor(messageClassName, filePath) {
40
+ super(
41
+ `Cannot find "${messageClassName}" - not imported and not defined in "${filePath}"`
42
+ );
43
+ this.name = "MessageClassNotFoundError";
44
+ }
45
+ };
46
+
47
+ // src/metadata-extractor.ts
48
+ var HandlerMetadataExtractor = class {
49
+ constructor(contextPath, outputFile, config = {}) {
50
+ this.contextPath = contextPath;
51
+ this.outputFile = outputFile;
52
+ if (config.commandHandlerDecorator) {
53
+ this.config.commandHandlerDecorator = config.commandHandlerDecorator;
54
+ }
55
+ if (config.eventHandlerDecorator) {
56
+ this.config.eventHandlerDecorator = config.eventHandlerDecorator;
57
+ }
58
+ }
59
+ config = {
60
+ commandHandlerDecorator: "CommandHandlerMarker",
61
+ eventHandlerDecorator: "EventHandlerMarker"
62
+ };
63
+ extractHandlersMetadata(files) {
64
+ const handlers = [];
65
+ for (const file of files) {
66
+ const sourceCode = fs.readFileSync(file, "utf-8");
67
+ const sourceFile = ts.createSourceFile(
68
+ file,
69
+ sourceCode,
70
+ ts.ScriptTarget.Latest,
71
+ true
72
+ );
73
+ ts.forEachChild(sourceFile, (node) => {
74
+ if (ts.isClassDeclaration(node)) {
75
+ const metadata = this.extractFromClass(
76
+ node,
77
+ file,
78
+ sourceFile
79
+ );
80
+ if (metadata) {
81
+ handlers.push(metadata);
82
+ }
83
+ }
84
+ });
85
+ }
86
+ return handlers;
87
+ }
88
+ extractFromClass(classNode, filePath, sourceFile) {
89
+ const className = classNode.name?.text;
90
+ if (!className) return null;
91
+ const decorators = ts.canHaveDecorators(classNode) ? ts.getDecorators(classNode) : void 0;
92
+ if (!decorators) return null;
93
+ for (const decorator of decorators) {
94
+ const expression = decorator.expression;
95
+ if (!ts.isCallExpression(expression)) continue;
96
+ const decoratorName = expression.expression.getText();
97
+ if (decoratorName === "CommandHandlerMarker") {
98
+ return this.extractCommandHandlerMetadata(
99
+ className,
100
+ expression,
101
+ filePath,
102
+ sourceFile
103
+ );
104
+ }
105
+ if (decoratorName === "EventHandlerMarker") {
106
+ return this.extractEventHandlerMetadata(
107
+ className,
108
+ expression,
109
+ filePath
110
+ );
111
+ }
112
+ if (decoratorName === "QueryHandlerMarker") {
113
+ return this.extractQueryHandlerMetadata(
114
+ className,
115
+ expression,
116
+ filePath,
117
+ sourceFile
118
+ );
119
+ }
120
+ }
121
+ return null;
122
+ }
123
+ extractMessageHandlerMetadata(className, expression, filePath, sourceFile) {
124
+ const messageClassArg = expression.arguments[0];
125
+ const messageClassName = messageClassArg.getText();
126
+ const messageImport = this.findImportForSymbol(
127
+ messageClassName,
128
+ sourceFile
129
+ );
130
+ let messagePath = "";
131
+ let resolvedMessageClassName = messageClassName;
132
+ if (messageImport) {
133
+ const handlerDir = path.dirname(filePath);
134
+ const resolvedImportPath = this.resolvePathAlias(messageImport.path);
135
+ const messageAbsolutePath = path.resolve(
136
+ handlerDir,
137
+ resolvedImportPath + ".ts"
138
+ );
139
+ messagePath = this.toRelativeImport(messageAbsolutePath);
140
+ resolvedMessageClassName = messageImport.symbol;
141
+ } else if (this.isClassDefinedInFile(messageClassName, sourceFile)) {
142
+ messagePath = this.toRelativeImport(filePath);
143
+ } else {
144
+ throw new MessageClassNotFoundError(messageClassName, filePath);
145
+ }
146
+ return {
147
+ messagePath,
148
+ messageClassName: resolvedMessageClassName
149
+ };
150
+ }
151
+ isClassDefinedInFile(className, sourceFile) {
152
+ for (const statement of sourceFile.statements) {
153
+ if (ts.isClassDeclaration(statement) && statement.name?.text === className) {
154
+ return true;
155
+ }
156
+ }
157
+ return false;
158
+ }
159
+ extractCommandHandlerMetadata(className, expression, filePath, sourceFile) {
160
+ const { messagePath, messageClassName } = this.extractMessageHandlerMetadata(
161
+ className,
162
+ expression,
163
+ filePath,
164
+ sourceFile
165
+ );
166
+ return {
167
+ type: "command",
168
+ handlerPath: this.toRelativeImport(filePath),
169
+ handlerClassName: className,
170
+ commandPath: messagePath,
171
+ commandClassName: messageClassName
172
+ };
173
+ }
174
+ extractEventHandlerMetadata(className, expression, filePath) {
175
+ let options = {};
176
+ if (expression.arguments.length > 0) {
177
+ const optionsArg = expression.arguments[0];
178
+ options = this.parseObjectLiteral(optionsArg);
179
+ }
180
+ return {
181
+ type: "event",
182
+ handlerPath: this.toRelativeImport(filePath),
183
+ handlerClassName: className,
184
+ eventHandlerOptions: options
185
+ };
186
+ }
187
+ extractQueryHandlerMetadata(className, expression, filePath, sourceFile) {
188
+ const { messagePath, messageClassName } = this.extractMessageHandlerMetadata(
189
+ className,
190
+ expression,
191
+ filePath,
192
+ sourceFile
193
+ );
194
+ return {
195
+ type: "query",
196
+ handlerPath: this.toRelativeImport(filePath),
197
+ handlerClassName: className,
198
+ queryPath: messagePath,
199
+ queryClassName: messageClassName
200
+ };
201
+ }
202
+ findImportForSymbol(symbol, sourceFile) {
203
+ for (const statement of sourceFile.statements) {
204
+ if (ts.isImportDeclaration(statement)) {
205
+ const importClause = statement.importClause;
206
+ const moduleSpecifier = statement.moduleSpecifier.text;
207
+ if (importClause?.namedBindings && ts.isNamedImports(importClause.namedBindings)) {
208
+ for (const element of importClause.namedBindings.elements) {
209
+ if (element.name.text === symbol) {
210
+ return {
211
+ path: moduleSpecifier,
212
+ symbol: element.name.text
213
+ };
214
+ }
215
+ }
216
+ }
217
+ }
218
+ }
219
+ return null;
220
+ }
221
+ toRelativeImport(absolutePath) {
222
+ const outputFileAbsolutePath = path.join(
223
+ this.contextPath,
224
+ this.outputFile
225
+ );
226
+ const outputDir = path.dirname(outputFileAbsolutePath);
227
+ const relative2 = path.relative(outputDir, absolutePath);
228
+ const withoutExtension = relative2.replace(/\.ts$/, "");
229
+ return withoutExtension.startsWith(".") ? withoutExtension : "./" + withoutExtension;
230
+ }
231
+ parseObjectLiteral(node) {
232
+ if (!ts.isObjectLiteralExpression(node)) {
233
+ return {};
234
+ }
235
+ const result = {};
236
+ for (const property of node.properties) {
237
+ if (ts.isPropertyAssignment(property)) {
238
+ const name = property.name.getText();
239
+ const value = property.initializer;
240
+ if (ts.isStringLiteral(value)) {
241
+ result[name] = value.text;
242
+ } else if (ts.isNumericLiteral(value)) {
243
+ result[name] = Number(value.text);
244
+ } else if (value.kind === ts.SyntaxKind.TrueKeyword) {
245
+ result[name] = true;
246
+ } else if (value.kind === ts.SyntaxKind.FalseKeyword) {
247
+ result[name] = false;
248
+ }
249
+ }
250
+ }
251
+ return result;
252
+ }
253
+ resolvePathAlias(importPath) {
254
+ const tsconfigPath = path.join(this.contextPath, "tsconfig.json");
255
+ if (!fs.existsSync(tsconfigPath)) return importPath;
256
+ const tsconfig = JSON.parse(fs.readFileSync(tsconfigPath, "utf-8"));
257
+ const paths = tsconfig.compilerOptions?.paths;
258
+ const baseUrl = tsconfig.compilerOptions?.baseUrl || ".";
259
+ if (!paths) return importPath;
260
+ for (const [alias, targets] of Object.entries(paths)) {
261
+ const aliasPrefix = alias.replace("/*", "");
262
+ if (importPath.startsWith(aliasPrefix)) {
263
+ const targetBase = targets[0].replace("/*", "");
264
+ const resolvedBase = path.join(this.contextPath, baseUrl, targetBase);
265
+ return importPath.replace(aliasPrefix, resolvedBase);
266
+ }
267
+ }
268
+ return importPath;
269
+ }
270
+ };
271
+
272
+ // src/code-generator.ts
273
+ var ApplicationCodeGenerator = class {
274
+ constructor(config) {
275
+ this.config = config;
276
+ }
277
+ generateCode(handlers) {
278
+ this.validateNoDuplicates(handlers);
279
+ const imports = this.collectImports(handlers);
280
+ const registrations = this.generateRegistrations(handlers);
281
+ return this.assembleGeneratedCode(imports, registrations);
282
+ }
283
+ validateNoDuplicates(handlers) {
284
+ this.validateNoDuplicateCommandHandlers(handlers);
285
+ this.validateNoDuplicateEventHandlers(handlers);
286
+ this.validateNoDuplicateQueryHandlers(handlers);
287
+ }
288
+ validateNoDuplicateHandlers(handlers, typeFilter, keyExtractor, errorFactory) {
289
+ const filteredHandlers = handlers.filter(typeFilter);
290
+ const keyToHandlers = /* @__PURE__ */ new Map();
291
+ for (const handler of filteredHandlers) {
292
+ const key = keyExtractor(handler);
293
+ const existing = keyToHandlers.get(key) ?? [];
294
+ existing.push(handler.handlerClassName);
295
+ keyToHandlers.set(key, existing);
296
+ }
297
+ for (const [key, handlerList] of keyToHandlers) {
298
+ if (handlerList.length > 1) {
299
+ throw errorFactory(key, handlerList);
300
+ }
301
+ }
302
+ }
303
+ validateNoDuplicateCommandHandlers(handlers) {
304
+ this.validateNoDuplicateHandlers(
305
+ handlers,
306
+ (h) => h.type === "command",
307
+ (h) => h.commandClassName,
308
+ (key, handlers2) => new DuplicateCommandHandlerError(key, handlers2)
309
+ );
310
+ }
311
+ validateNoDuplicateEventHandlers(handlers) {
312
+ const eventHandlers = handlers.filter(
313
+ (h) => h.type === "event"
314
+ );
315
+ const namedEventHandlers = eventHandlers.filter(
316
+ (h) => h.eventHandlerOptions.name !== void 0
317
+ );
318
+ this.validateNoDuplicateHandlers(
319
+ namedEventHandlers,
320
+ (h) => true,
321
+ (h) => h.eventHandlerOptions.name,
322
+ (key, handlers2) => new DuplicateEventHandlerError(key, handlers2)
323
+ );
324
+ }
325
+ validateNoDuplicateQueryHandlers(handlers) {
326
+ this.validateNoDuplicateHandlers(
327
+ handlers,
328
+ (h) => h.type === "query",
329
+ (h) => h.queryClassName,
330
+ (key, handlers2) => new DuplicateQueryHandlerError(key, handlers2)
331
+ );
332
+ }
333
+ createImportStatement(symbolName, importPath) {
334
+ return `import { ${symbolName} } from '${importPath}';`;
335
+ }
336
+ createCommandHandlerRegistration(commandClassName, handlerClassName) {
337
+ return ` .withCommandHandler(${commandClassName}, () => new ${handlerClassName}())`;
338
+ }
339
+ createEventHandlerRegistration(handlerClassName, eventName) {
340
+ const nameArg = eventName ? `, '${eventName}'` : "";
341
+ return ` .withEventHandler(() => new ${handlerClassName}()${nameArg})`;
342
+ }
343
+ createQueryHandlerRegistration(queryClassName, handlerClassName) {
344
+ return ` .withQueryHandler(${queryClassName}, () => new ${handlerClassName}())`;
345
+ }
346
+ isCommandHandler(handler) {
347
+ return handler.type === "command";
348
+ }
349
+ isEventHandler(handler) {
350
+ return handler.type === "event";
351
+ }
352
+ isQueryHandler(handler) {
353
+ return handler.type === "query";
354
+ }
355
+ collectImports(handlers) {
356
+ const imports = /* @__PURE__ */ new Set();
357
+ imports.add(
358
+ this.createImportStatement(
359
+ "ApplicationBuilder",
360
+ this.config.applicationBuilderImportPath
361
+ )
362
+ );
363
+ for (const handler of handlers) {
364
+ imports.add(
365
+ this.createImportStatement(
366
+ handler.handlerClassName,
367
+ handler.handlerPath
368
+ )
369
+ );
370
+ if (this.isCommandHandler(handler) && handler.commandPath) {
371
+ imports.add(
372
+ this.createImportStatement(
373
+ handler.commandClassName,
374
+ handler.commandPath
375
+ )
376
+ );
377
+ }
378
+ if (this.isQueryHandler(handler) && handler.queryPath) {
379
+ imports.add(
380
+ this.createImportStatement(
381
+ handler.queryClassName,
382
+ handler.queryPath
383
+ )
384
+ );
385
+ }
386
+ }
387
+ return imports;
388
+ }
389
+ generateRegistrations(handlers) {
390
+ const commandRegistrations = this.generateCommandRegistrations(handlers);
391
+ const queryRegistrations = this.generateQueryRegistrations(handlers);
392
+ const eventRegistrations = this.generateEventRegistrations(handlers);
393
+ return [...commandRegistrations, ...queryRegistrations, ...eventRegistrations];
394
+ }
395
+ generateCommandRegistrations(handlers) {
396
+ return handlers.filter(
397
+ (h) => this.isCommandHandler(h)
398
+ ).map(
399
+ (h) => this.createCommandHandlerRegistration(
400
+ h.commandClassName,
401
+ h.handlerClassName
402
+ )
403
+ );
404
+ }
405
+ generateQueryRegistrations(handlers) {
406
+ return handlers.filter(
407
+ (h) => this.isQueryHandler(h)
408
+ ).map(
409
+ (h) => this.createQueryHandlerRegistration(
410
+ h.queryClassName,
411
+ h.handlerClassName
412
+ )
413
+ );
414
+ }
415
+ generateEventRegistrations(handlers) {
416
+ return handlers.filter((h) => this.isEventHandler(h)).map((handler) => {
417
+ this.validateEventHandlerOptions(handler);
418
+ const eventName = handler.eventHandlerOptions.name;
419
+ return this.createEventHandlerRegistration(
420
+ handler.handlerClassName,
421
+ eventName
422
+ );
423
+ });
424
+ }
425
+ validateEventHandlerOptions(handler) {
426
+ const options = handler.eventHandlerOptions;
427
+ const invalidKeys = Object.keys(options).filter(
428
+ (key) => key !== "name"
429
+ );
430
+ if (invalidKeys.length > 0) {
431
+ throw new Error(
432
+ `EventHandler for ${handler.handlerClassName} has invalid options: ${invalidKeys.join(", ")}.
433
+ Only 'name' option is supported. Use @EventHandler({ name: 'event-name' })`
434
+ );
435
+ }
436
+ }
437
+ assembleGeneratedCode(imports, registrations) {
438
+ const registrationCode = registrations.length > 0 ? "\n" + registrations.join("\n") : "";
439
+ return `
440
+ ${Array.from(imports).join("\n")}
441
+
442
+ export function createApplicationBuilder(): ApplicationBuilder {
443
+ return new ApplicationBuilder()${registrationCode};
444
+ }
445
+ `;
446
+ }
447
+ };
448
+
449
+ // src/application-builder-generator.ts
450
+ var ApplicationBuilderGenerator = class {
451
+ constructor(contextPath, config) {
452
+ this.contextPath = contextPath;
453
+ this.config = config;
454
+ this.metadataExtractor = new HandlerMetadataExtractor(
455
+ contextPath,
456
+ config.outputFile
457
+ );
458
+ this.codeGenerator = new ApplicationCodeGenerator(config);
459
+ }
460
+ metadataExtractor;
461
+ codeGenerator;
462
+ async generate() {
463
+ const handlerFiles = await this.scanHandlerFiles();
464
+ const handlers = this.metadataExtractor.extractHandlersMetadata(handlerFiles);
465
+ const code = this.codeGenerator.generateCode(handlers);
466
+ this.writeToFile(code);
467
+ }
468
+ async scanHandlerFiles() {
469
+ const allFiles = [];
470
+ for (const pattern of this.config.handlers) {
471
+ const files = await glob(pattern, {
472
+ cwd: this.contextPath,
473
+ absolute: true
474
+ });
475
+ allFiles.push(...files);
476
+ }
477
+ return allFiles.sort();
478
+ }
479
+ writeToFile(code) {
480
+ const outputFile = path.join(this.contextPath, this.config.outputFile);
481
+ const outputDir = path.dirname(outputFile);
482
+ fs.mkdirSync(outputDir, { recursive: true });
483
+ fs.writeFileSync(outputFile, code, "utf-8");
484
+ }
485
+ };
486
+
487
+ // src/config.ts
488
+ var BuildPluginConfig = class _BuildPluginConfig {
489
+ handlers;
490
+ outputFile;
491
+ applicationBuilderImportPath;
492
+ constructor(config) {
493
+ this.handlers = config.handlers;
494
+ this.outputFile = config.outputFile;
495
+ this.applicationBuilderImportPath = config.applicationBuilderImportPath;
496
+ }
497
+ static fromRawConfig(raw) {
498
+ if (!raw.applicationBuilderImportPath) {
499
+ throw new Error(
500
+ "applicationBuilderImportPath is required in hexai.config.ts\nExample: { applicationBuilderImportPath: '@/application', ... }"
501
+ );
502
+ }
503
+ if (!raw.handlers || raw.handlers.length === 0) {
504
+ throw new Error(
505
+ "handlers array is required and must not be empty in hexai.config.ts"
506
+ );
507
+ }
508
+ return new _BuildPluginConfig({
509
+ handlers: raw.handlers,
510
+ outputFile: raw.outputFile ?? "src/.generated/application-builder.ts",
511
+ applicationBuilderImportPath: raw.applicationBuilderImportPath
512
+ });
513
+ }
514
+ };
515
+
516
+ // src/config-loader.ts
517
+ async function loadConfig(configPath) {
518
+ const configSource = fs.readFileSync(configPath, "utf-8");
519
+ const transpiledCode = transpileConfigFile(configSource);
520
+ const moduleExports = evaluateConfigModule(transpiledCode);
521
+ const rawConfig = extractConfigFromModule(moduleExports);
522
+ return BuildPluginConfig.fromRawConfig(rawConfig);
523
+ }
524
+ function transpileConfigFile(source) {
525
+ const result = ts.transpileModule(source, {
526
+ compilerOptions: {
527
+ module: ts.ModuleKind.CommonJS,
528
+ target: ts.ScriptTarget.ES2020
529
+ }
530
+ });
531
+ return result.outputText;
532
+ }
533
+ function evaluateConfigModule(code) {
534
+ const tempModule = { exports: {} };
535
+ const fn = new Function("module", "exports", "require", code);
536
+ fn(tempModule, tempModule.exports, __require);
537
+ return tempModule.exports;
538
+ }
539
+ function extractConfigFromModule(moduleExports) {
540
+ return moduleExports.default || moduleExports;
541
+ }
542
+
543
+ // src/main.ts
544
+ async function generateApplicationBuilder(contextPath, options = {}) {
545
+ let configFile = "hexai.config.ts";
546
+ if (options.configFile) {
547
+ configFile = options.configFile;
548
+ }
549
+ const configPath = path.join(contextPath, configFile);
550
+ const config = await loadConfig(configPath);
551
+ const generator = new ApplicationBuilderGenerator(contextPath, config);
552
+ await generator.generate();
553
+ }
554
+
555
+ // src/decorators/index.ts
556
+ function createMessageHandlerMarker() {
557
+ return function(messageClass) {
558
+ return function(target) {
559
+ return target;
560
+ };
561
+ };
562
+ }
563
+ var CommandHandlerMarker = createMessageHandlerMarker();
564
+ var QueryHandlerMarker = createMessageHandlerMarker();
565
+ function EventHandlerMarker(options) {
566
+ return function(target) {
567
+ return target;
568
+ };
569
+ }
570
+ var cliPlugin = {
571
+ name: "generate-app-builder",
572
+ description: "Generate ApplicationBuilder code from decorated handlers",
573
+ options: [
574
+ {
575
+ flags: "-p, --context-path <path>",
576
+ description: "Path to the bounded context directory",
577
+ required: true
578
+ },
579
+ {
580
+ flags: "-f, --config-file <name>",
581
+ description: "Config file name to use (default: hexai.config.ts)"
582
+ }
583
+ ],
584
+ run: async (args, config) => {
585
+ const contextPath = path.resolve(String(args.contextPath));
586
+ const configFile = args.configFile !== void 0 ? String(args.configFile) : config.configFile;
587
+ console.log(`Generating application builder for: ${contextPath}`);
588
+ await generateApplicationBuilder(contextPath, {
589
+ configFile
590
+ });
591
+ console.log("\u2713 Application builder generated successfully");
592
+ }
593
+ };
594
+
595
+ export { CommandHandlerMarker, DuplicateCommandHandlerError, DuplicateEventHandlerError, DuplicateQueryHandlerError, EventHandlerMarker, QueryHandlerMarker, cliPlugin, generateApplicationBuilder };
596
+ //# sourceMappingURL=index.js.map
16
597
  //# sourceMappingURL=index.js.map