@gravito/scaffold 4.0.0 → 4.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/README.md +30 -6
- package/dist/index.cjs +404 -67
- package/dist/index.d.ts +239 -3
- package/dist/index.js +404 -67
- package/package.json +5 -2
- package/dist/index.d.cts +0 -687
package/dist/index.js
CHANGED
|
@@ -1008,6 +1008,118 @@ export default {
|
|
|
1008
1008
|
}
|
|
1009
1009
|
`;
|
|
1010
1010
|
}
|
|
1011
|
+
/**
|
|
1012
|
+
* Generate workers configuration for job queue system
|
|
1013
|
+
*/
|
|
1014
|
+
static generateWorkersConfig(level = "basic") {
|
|
1015
|
+
switch (level) {
|
|
1016
|
+
case "advanced":
|
|
1017
|
+
return this.generateAdvancedWorkersConfig();
|
|
1018
|
+
case "production":
|
|
1019
|
+
return this.generateProductionWorkersConfig();
|
|
1020
|
+
default:
|
|
1021
|
+
return this.generateBasicWorkersConfig();
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
/**
|
|
1025
|
+
* Generate basic workers configuration
|
|
1026
|
+
*/
|
|
1027
|
+
static generateBasicWorkersConfig() {
|
|
1028
|
+
return ` /**
|
|
1029
|
+
* Workers Configuration
|
|
1030
|
+
*
|
|
1031
|
+
* Manages job execution in isolated worker threads.
|
|
1032
|
+
* Automatically selects best available runtime (Bun or Node.js).
|
|
1033
|
+
*/
|
|
1034
|
+
workers: {
|
|
1035
|
+
// Runtime environment: 'auto' | 'bun' | 'node'
|
|
1036
|
+
runtime: process.env.WORKERS_RUNTIME as 'auto' | 'bun' | 'node' ?? 'auto',
|
|
1037
|
+
|
|
1038
|
+
pool: {
|
|
1039
|
+
poolSize: Number.parseInt(process.env.WORKERS_POOL_SIZE ?? '4', 10),
|
|
1040
|
+
minWorkers: Number.parseInt(process.env.WORKERS_MIN_WORKERS ?? '0', 10),
|
|
1041
|
+
healthCheckInterval: 30000,
|
|
1042
|
+
},
|
|
1043
|
+
|
|
1044
|
+
execution: {
|
|
1045
|
+
maxExecutionTime: Number.parseInt(process.env.WORKERS_MAX_EXECUTION_TIME ?? '30000', 10),
|
|
1046
|
+
maxMemory: Number.parseInt(process.env.WORKERS_MAX_MEMORY ?? '0', 10),
|
|
1047
|
+
idleTimeout: Number.parseInt(process.env.WORKERS_IDLE_TIMEOUT ?? '60000', 10),
|
|
1048
|
+
isolateContexts: process.env.WORKERS_ISOLATE_CONTEXTS === 'true',
|
|
1049
|
+
},
|
|
1050
|
+
},`;
|
|
1051
|
+
}
|
|
1052
|
+
/**
|
|
1053
|
+
* Generate advanced workers configuration with Bun optimizations
|
|
1054
|
+
*/
|
|
1055
|
+
static generateAdvancedWorkersConfig() {
|
|
1056
|
+
return ` /**
|
|
1057
|
+
* Workers Configuration (Advanced)
|
|
1058
|
+
*
|
|
1059
|
+
* Manages job execution in isolated worker threads.
|
|
1060
|
+
* Includes Bun-specific optimizations for enhanced performance.
|
|
1061
|
+
*
|
|
1062
|
+
* Performance characteristics:
|
|
1063
|
+
* - Bun: 2-241x faster message passing, 20-30% less memory (smol mode)
|
|
1064
|
+
* - Node.js: Stable, widely tested, compatible
|
|
1065
|
+
*/
|
|
1066
|
+
workers: {
|
|
1067
|
+
runtime: process.env.WORKERS_RUNTIME as 'auto' | 'bun' | 'node' ?? 'auto',
|
|
1068
|
+
|
|
1069
|
+
pool: {
|
|
1070
|
+
poolSize: Number.parseInt(process.env.WORKERS_POOL_SIZE ?? '4', 10),
|
|
1071
|
+
minWorkers: Number.parseInt(process.env.WORKERS_MIN_WORKERS ?? '1', 10),
|
|
1072
|
+
healthCheckInterval: 30000,
|
|
1073
|
+
},
|
|
1074
|
+
|
|
1075
|
+
execution: {
|
|
1076
|
+
maxExecutionTime: Number.parseInt(process.env.WORKERS_MAX_EXECUTION_TIME ?? '30000', 10),
|
|
1077
|
+
maxMemory: Number.parseInt(process.env.WORKERS_MAX_MEMORY ?? '0', 10),
|
|
1078
|
+
idleTimeout: Number.parseInt(process.env.WORKERS_IDLE_TIMEOUT ?? '60000', 10),
|
|
1079
|
+
isolateContexts: process.env.WORKERS_ISOLATE_CONTEXTS === 'true',
|
|
1080
|
+
},
|
|
1081
|
+
|
|
1082
|
+
// Bun-specific optimizations
|
|
1083
|
+
bun: {
|
|
1084
|
+
smol: process.env.WORKERS_BUN_SMOL === 'true',
|
|
1085
|
+
preload: process.env.WORKERS_BUN_PRELOAD
|
|
1086
|
+
? process.env.WORKERS_BUN_PRELOAD.split(',').map((p) => p.trim())
|
|
1087
|
+
: undefined,
|
|
1088
|
+
inspectPort: process.env.WORKERS_BUN_INSPECT_PORT
|
|
1089
|
+
? Number.parseInt(process.env.WORKERS_BUN_INSPECT_PORT, 10)
|
|
1090
|
+
: undefined,
|
|
1091
|
+
},
|
|
1092
|
+
},`;
|
|
1093
|
+
}
|
|
1094
|
+
/**
|
|
1095
|
+
* Generate production-optimized workers configuration
|
|
1096
|
+
*/
|
|
1097
|
+
static generateProductionWorkersConfig() {
|
|
1098
|
+
return ` /**
|
|
1099
|
+
* Workers Configuration (Production Optimized)
|
|
1100
|
+
*/
|
|
1101
|
+
workers: {
|
|
1102
|
+
runtime: 'auto' as const,
|
|
1103
|
+
|
|
1104
|
+
pool: {
|
|
1105
|
+
poolSize: Number.parseInt(process.env.WORKERS_POOL_SIZE ?? '8', 10),
|
|
1106
|
+
minWorkers: 2,
|
|
1107
|
+
healthCheckInterval: 30000,
|
|
1108
|
+
},
|
|
1109
|
+
|
|
1110
|
+
execution: {
|
|
1111
|
+
maxExecutionTime: 30000,
|
|
1112
|
+
maxMemory: Number.parseInt(process.env.WORKERS_MAX_MEMORY ?? '512', 10),
|
|
1113
|
+
idleTimeout: 60000,
|
|
1114
|
+
isolateContexts: false,
|
|
1115
|
+
},
|
|
1116
|
+
|
|
1117
|
+
bun: {
|
|
1118
|
+
smol: true,
|
|
1119
|
+
preload: process.env.WORKERS_BUN_PRELOAD?.split(',').map((p) => p.trim()),
|
|
1120
|
+
},
|
|
1121
|
+
},`;
|
|
1122
|
+
}
|
|
1011
1123
|
};
|
|
1012
1124
|
|
|
1013
1125
|
// src/utils/ServiceProviderGenerator.ts
|
|
@@ -2395,6 +2507,30 @@ var ModuleGenerator = class {
|
|
|
2395
2507
|
]
|
|
2396
2508
|
}
|
|
2397
2509
|
]
|
|
2510
|
+
},
|
|
2511
|
+
// UserInterface Layer
|
|
2512
|
+
{
|
|
2513
|
+
type: "directory",
|
|
2514
|
+
name: "UserInterface",
|
|
2515
|
+
children: [
|
|
2516
|
+
{
|
|
2517
|
+
type: "directory",
|
|
2518
|
+
name: "Http",
|
|
2519
|
+
children: [
|
|
2520
|
+
{
|
|
2521
|
+
type: "directory",
|
|
2522
|
+
name: "Controllers",
|
|
2523
|
+
children: [
|
|
2524
|
+
{
|
|
2525
|
+
type: "file",
|
|
2526
|
+
name: `${name}Controller.ts`,
|
|
2527
|
+
content: this.generateController(name)
|
|
2528
|
+
}
|
|
2529
|
+
]
|
|
2530
|
+
}
|
|
2531
|
+
]
|
|
2532
|
+
}
|
|
2533
|
+
]
|
|
2398
2534
|
}
|
|
2399
2535
|
]
|
|
2400
2536
|
};
|
|
@@ -2410,17 +2546,13 @@ import { ${name}Created } from '../../Events/${name}Created'
|
|
|
2410
2546
|
import { ${name}Status } from './${name}Status'
|
|
2411
2547
|
|
|
2412
2548
|
export interface ${name}Props {
|
|
2413
|
-
// Add properties here
|
|
2414
2549
|
status: ${name}Status
|
|
2415
2550
|
createdAt: Date
|
|
2416
2551
|
}
|
|
2417
2552
|
|
|
2418
2553
|
export class ${name} extends AggregateRoot<Id> {
|
|
2419
|
-
private props: ${name}Props
|
|
2420
|
-
|
|
2421
|
-
private constructor(id: Id, props: ${name}Props) {
|
|
2554
|
+
private constructor(id: Id, private props: ${name}Props) {
|
|
2422
2555
|
super(id)
|
|
2423
|
-
this.props = props
|
|
2424
2556
|
}
|
|
2425
2557
|
|
|
2426
2558
|
static create(id: Id): ${name} {
|
|
@@ -2438,7 +2570,12 @@ export class ${name} extends AggregateRoot<Id> {
|
|
|
2438
2570
|
return this.props.status
|
|
2439
2571
|
}
|
|
2440
2572
|
|
|
2441
|
-
|
|
2573
|
+
/**
|
|
2574
|
+
* Complete the ${name} process
|
|
2575
|
+
*/
|
|
2576
|
+
complete(): void {
|
|
2577
|
+
this.props.status = ${name}Status.COMPLETED
|
|
2578
|
+
}
|
|
2442
2579
|
}
|
|
2443
2580
|
`;
|
|
2444
2581
|
}
|
|
@@ -2463,17 +2600,13 @@ export enum ${name}Status {
|
|
|
2463
2600
|
import { DomainEvent } from '@gravito/enterprise'
|
|
2464
2601
|
|
|
2465
2602
|
export class ${name}Created extends DomainEvent {
|
|
2466
|
-
constructor(public readonly
|
|
2603
|
+
constructor(public readonly aggregateId: string) {
|
|
2467
2604
|
super()
|
|
2468
2605
|
}
|
|
2469
2606
|
|
|
2470
2607
|
override get eventName(): string {
|
|
2471
2608
|
return '${name.toLowerCase()}.created'
|
|
2472
2609
|
}
|
|
2473
|
-
|
|
2474
|
-
get aggregateId(): string {
|
|
2475
|
-
return this.${name.toLowerCase()}Id
|
|
2476
|
-
}
|
|
2477
2610
|
}
|
|
2478
2611
|
`;
|
|
2479
2612
|
}
|
|
@@ -2500,7 +2633,6 @@ import { Command } from '@gravito/enterprise'
|
|
|
2500
2633
|
|
|
2501
2634
|
export class Create${name}Command extends Command {
|
|
2502
2635
|
constructor(
|
|
2503
|
-
// Add command properties
|
|
2504
2636
|
public readonly id?: string
|
|
2505
2637
|
) {
|
|
2506
2638
|
super()
|
|
@@ -2555,13 +2687,15 @@ export class Get${name}ByIdQuery extends Query {
|
|
|
2555
2687
|
import { QueryHandler } from '@gravito/enterprise'
|
|
2556
2688
|
import type { I${name}Repository } from '../../../Domain/Repositories/I${name}Repository'
|
|
2557
2689
|
import type { ${name}DTO } from '../../DTOs/${name}DTO'
|
|
2690
|
+
import { Id } from '../../../../../Shared/Domain/ValueObjects/Id'
|
|
2558
2691
|
import type { Get${name}ByIdQuery } from './Get${name}ByIdQuery'
|
|
2559
2692
|
|
|
2560
2693
|
export class Get${name}ByIdHandler implements QueryHandler<Get${name}ByIdQuery, ${name}DTO | null> {
|
|
2561
2694
|
constructor(private repository: I${name}Repository) {}
|
|
2562
2695
|
|
|
2563
2696
|
async handle(query: Get${name}ByIdQuery): Promise<${name}DTO | null> {
|
|
2564
|
-
const
|
|
2697
|
+
const id = Id.from(query.id)
|
|
2698
|
+
const aggregate = await this.repository.findById(id)
|
|
2565
2699
|
if (!aggregate) return null
|
|
2566
2700
|
|
|
2567
2701
|
return {
|
|
@@ -2582,7 +2716,6 @@ import type { ${name}Status } from '../../Domain/Aggregates/${name}/${name}Statu
|
|
|
2582
2716
|
export interface ${name}DTO {
|
|
2583
2717
|
id: string
|
|
2584
2718
|
status: ${name}Status
|
|
2585
|
-
// Add more fields
|
|
2586
2719
|
}
|
|
2587
2720
|
`;
|
|
2588
2721
|
}
|
|
@@ -2593,29 +2726,29 @@ export interface ${name}DTO {
|
|
|
2593
2726
|
|
|
2594
2727
|
import type { ${name} } from '../../Domain/Aggregates/${name}/${name}'
|
|
2595
2728
|
import type { I${name}Repository } from '../../Domain/Repositories/I${name}Repository'
|
|
2596
|
-
import
|
|
2597
|
-
|
|
2598
|
-
const store = new Map<string, ${name}>()
|
|
2729
|
+
import { Id } from '../../../../../Shared/Domain/ValueObjects/Id'
|
|
2599
2730
|
|
|
2600
2731
|
export class ${name}Repository implements I${name}Repository {
|
|
2732
|
+
private store = new Map<string, ${name}>()
|
|
2733
|
+
|
|
2601
2734
|
async findById(id: Id): Promise<${name} | null> {
|
|
2602
|
-
return store.get(id.value) ?? null
|
|
2735
|
+
return this.store.get(id.value) ?? null
|
|
2603
2736
|
}
|
|
2604
2737
|
|
|
2605
2738
|
async save(aggregate: ${name}): Promise<void> {
|
|
2606
|
-
store.set(aggregate.id.value, aggregate)
|
|
2739
|
+
this.store.set(aggregate.id.value, aggregate)
|
|
2607
2740
|
}
|
|
2608
2741
|
|
|
2609
2742
|
async delete(id: Id): Promise<void> {
|
|
2610
|
-
store.delete(id.value)
|
|
2743
|
+
this.store.delete(id.value)
|
|
2611
2744
|
}
|
|
2612
2745
|
|
|
2613
2746
|
async findAll(): Promise<${name}[]> {
|
|
2614
|
-
return Array.from(store.values())
|
|
2747
|
+
return Array.from(this.store.values())
|
|
2615
2748
|
}
|
|
2616
2749
|
|
|
2617
2750
|
async exists(id: Id): Promise<boolean> {
|
|
2618
|
-
return store.has(id.value)
|
|
2751
|
+
return this.store.has(id.value)
|
|
2619
2752
|
}
|
|
2620
2753
|
}
|
|
2621
2754
|
`;
|
|
@@ -2637,6 +2770,37 @@ export class ${name}ServiceProvider extends ServiceProvider {
|
|
|
2637
2770
|
console.log('[${name}] Module loaded')
|
|
2638
2771
|
}
|
|
2639
2772
|
}
|
|
2773
|
+
`;
|
|
2774
|
+
}
|
|
2775
|
+
generateController(name) {
|
|
2776
|
+
return `/**
|
|
2777
|
+
* ${name} Controller
|
|
2778
|
+
*/
|
|
2779
|
+
|
|
2780
|
+
import type { GravitoContext } from '@gravito/core'
|
|
2781
|
+
|
|
2782
|
+
export class ${name}Controller {
|
|
2783
|
+
/**
|
|
2784
|
+
* GET /${name.toLowerCase()}
|
|
2785
|
+
*/
|
|
2786
|
+
async index(ctx: GravitoContext) {
|
|
2787
|
+
return ctx.json({
|
|
2788
|
+
success: true,
|
|
2789
|
+
data: []
|
|
2790
|
+
})
|
|
2791
|
+
}
|
|
2792
|
+
|
|
2793
|
+
/**
|
|
2794
|
+
* GET /${name.toLowerCase()}/:id
|
|
2795
|
+
*/
|
|
2796
|
+
async show(ctx: GravitoContext) {
|
|
2797
|
+
const id = ctx.req.param('id')
|
|
2798
|
+
return ctx.json({
|
|
2799
|
+
success: true,
|
|
2800
|
+
data: { id }
|
|
2801
|
+
})
|
|
2802
|
+
}
|
|
2803
|
+
}
|
|
2640
2804
|
`;
|
|
2641
2805
|
}
|
|
2642
2806
|
};
|
|
@@ -2811,24 +2975,39 @@ export class Email extends ValueObject<EmailProps> {
|
|
|
2811
2975
|
|
|
2812
2976
|
import type { DomainEvent } from '@gravito/enterprise'
|
|
2813
2977
|
|
|
2814
|
-
type EventHandler = (event:
|
|
2978
|
+
type EventHandler<T extends DomainEvent = any> = (event: T) => void | Promise<void>
|
|
2815
2979
|
|
|
2816
2980
|
export class EventDispatcher {
|
|
2817
2981
|
private handlers: Map<string, EventHandler[]> = new Map()
|
|
2818
2982
|
|
|
2819
|
-
|
|
2983
|
+
/**
|
|
2984
|
+
* Subscribe to an event
|
|
2985
|
+
*/
|
|
2986
|
+
subscribe<T extends DomainEvent>(eventName: string, handler: EventHandler<T>): void {
|
|
2820
2987
|
const handlers = this.handlers.get(eventName) ?? []
|
|
2821
2988
|
handlers.push(handler)
|
|
2822
2989
|
this.handlers.set(eventName, handlers)
|
|
2823
2990
|
}
|
|
2824
2991
|
|
|
2992
|
+
/**
|
|
2993
|
+
* Dispatch a single event
|
|
2994
|
+
*/
|
|
2825
2995
|
async dispatch(event: DomainEvent): Promise<void> {
|
|
2826
2996
|
const handlers = this.handlers.get(event.eventName) ?? []
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2997
|
+
const promises = handlers.map(handler => {
|
|
2998
|
+
try {
|
|
2999
|
+
return handler(event)
|
|
3000
|
+
} catch (error) {
|
|
3001
|
+
console.error(\`[EventDispatcher] Error in handler for \${event.eventName}:\`, error)
|
|
3002
|
+
}
|
|
3003
|
+
})
|
|
3004
|
+
|
|
3005
|
+
await Promise.all(promises)
|
|
2830
3006
|
}
|
|
2831
3007
|
|
|
3008
|
+
/**
|
|
3009
|
+
* Dispatch multiple events sequentially
|
|
3010
|
+
*/
|
|
2832
3011
|
async dispatchAll(events: DomainEvent[]): Promise<void> {
|
|
2833
3012
|
for (const event of events) {
|
|
2834
3013
|
await this.dispatch(event)
|
|
@@ -3938,9 +4117,9 @@ var SatelliteGenerator = class extends BaseGenerator {
|
|
|
3938
4117
|
children: [
|
|
3939
4118
|
{
|
|
3940
4119
|
type: "directory",
|
|
3941
|
-
name: "
|
|
4120
|
+
name: "Aggregates",
|
|
3942
4121
|
children: [
|
|
3943
|
-
{ type: "file", name: `${name}.ts`, content: this.
|
|
4122
|
+
{ type: "file", name: `${name}.ts`, content: this.generateAggregate(name) }
|
|
3944
4123
|
]
|
|
3945
4124
|
},
|
|
3946
4125
|
{
|
|
@@ -3954,8 +4133,24 @@ var SatelliteGenerator = class extends BaseGenerator {
|
|
|
3954
4133
|
}
|
|
3955
4134
|
]
|
|
3956
4135
|
},
|
|
3957
|
-
{
|
|
3958
|
-
|
|
4136
|
+
{
|
|
4137
|
+
type: "directory",
|
|
4138
|
+
name: "ValueObjects",
|
|
4139
|
+
children: [
|
|
4140
|
+
{ type: "file", name: `${name}Id.ts`, content: this.generateIdValueObject(name) }
|
|
4141
|
+
]
|
|
4142
|
+
},
|
|
4143
|
+
{
|
|
4144
|
+
type: "directory",
|
|
4145
|
+
name: "Events",
|
|
4146
|
+
children: [
|
|
4147
|
+
{
|
|
4148
|
+
type: "file",
|
|
4149
|
+
name: `${name}Created.ts`,
|
|
4150
|
+
content: this.generateCreatedEvent(name)
|
|
4151
|
+
}
|
|
4152
|
+
]
|
|
4153
|
+
}
|
|
3959
4154
|
]
|
|
3960
4155
|
},
|
|
3961
4156
|
// Application Layer
|
|
@@ -3996,6 +4191,31 @@ var SatelliteGenerator = class extends BaseGenerator {
|
|
|
3996
4191
|
}
|
|
3997
4192
|
]
|
|
3998
4193
|
},
|
|
4194
|
+
// Interface Layer (HTTP/API)
|
|
4195
|
+
{
|
|
4196
|
+
type: "directory",
|
|
4197
|
+
name: "Interface",
|
|
4198
|
+
children: [
|
|
4199
|
+
{
|
|
4200
|
+
type: "directory",
|
|
4201
|
+
name: "Http",
|
|
4202
|
+
children: [
|
|
4203
|
+
{
|
|
4204
|
+
type: "directory",
|
|
4205
|
+
name: "Controllers",
|
|
4206
|
+
children: [
|
|
4207
|
+
{
|
|
4208
|
+
type: "file",
|
|
4209
|
+
name: `${name}Controller.ts`,
|
|
4210
|
+
content: this.generateController(name)
|
|
4211
|
+
}
|
|
4212
|
+
]
|
|
4213
|
+
},
|
|
4214
|
+
{ type: "directory", name: "Middleware", children: [] }
|
|
4215
|
+
]
|
|
4216
|
+
}
|
|
4217
|
+
]
|
|
4218
|
+
},
|
|
3999
4219
|
// Entry Point
|
|
4000
4220
|
{ type: "file", name: "index.ts", content: this.generateEntryPoint(name) },
|
|
4001
4221
|
{
|
|
@@ -4013,13 +4233,12 @@ var SatelliteGenerator = class extends BaseGenerator {
|
|
|
4013
4233
|
{
|
|
4014
4234
|
type: "file",
|
|
4015
4235
|
name: "unit.test.ts",
|
|
4016
|
-
content:
|
|
4017
|
-
|
|
4018
|
-
|
|
4019
|
-
|
|
4020
|
-
|
|
4021
|
-
|
|
4022
|
-
});`
|
|
4236
|
+
content: this.generateUnitTest(name)
|
|
4237
|
+
},
|
|
4238
|
+
{
|
|
4239
|
+
type: "file",
|
|
4240
|
+
name: "integration.test.ts",
|
|
4241
|
+
content: this.generateIntegrationTest(name)
|
|
4023
4242
|
}
|
|
4024
4243
|
]
|
|
4025
4244
|
}
|
|
@@ -4028,35 +4247,76 @@ describe("${name}", () => {
|
|
|
4028
4247
|
// ─────────────────────────────────────────────────────────────
|
|
4029
4248
|
// Domain Templates
|
|
4030
4249
|
// ─────────────────────────────────────────────────────────────
|
|
4031
|
-
|
|
4032
|
-
return `import {
|
|
4250
|
+
generateIdValueObject(name) {
|
|
4251
|
+
return `import { ValueObject } from '@gravito/enterprise'
|
|
4252
|
+
|
|
4253
|
+
interface IdProps {
|
|
4254
|
+
value: string
|
|
4255
|
+
}
|
|
4256
|
+
|
|
4257
|
+
export class ${name}Id extends ValueObject<IdProps> {
|
|
4258
|
+
constructor(value: string) {
|
|
4259
|
+
super({ value })
|
|
4260
|
+
}
|
|
4261
|
+
|
|
4262
|
+
static create(): ${name}Id {
|
|
4263
|
+
return new ${name}Id(crypto.randomUUID())
|
|
4264
|
+
}
|
|
4265
|
+
|
|
4266
|
+
get value(): string { return this.props.value }
|
|
4267
|
+
}
|
|
4268
|
+
`;
|
|
4269
|
+
}
|
|
4270
|
+
generateAggregate(name) {
|
|
4271
|
+
return `import { AggregateRoot } from '@gravito/enterprise'
|
|
4272
|
+
import { ${name}Id } from '../ValueObjects/${name}Id'
|
|
4273
|
+
import { ${name}Created } from '../Events/${name}Created'
|
|
4033
4274
|
|
|
4034
4275
|
export interface ${name}Props {
|
|
4035
4276
|
name: string
|
|
4036
4277
|
createdAt: Date
|
|
4037
4278
|
}
|
|
4038
4279
|
|
|
4039
|
-
export class ${name} extends
|
|
4040
|
-
constructor(id:
|
|
4280
|
+
export class ${name} extends AggregateRoot<${name}Id> {
|
|
4281
|
+
constructor(id: ${name}Id, private props: ${name}Props) {
|
|
4041
4282
|
super(id)
|
|
4042
4283
|
}
|
|
4043
4284
|
|
|
4044
|
-
static create(id:
|
|
4045
|
-
|
|
4285
|
+
static create(id: ${name}Id, name: string): ${name} {
|
|
4286
|
+
const aggregate = new ${name}(id, {
|
|
4046
4287
|
name,
|
|
4047
4288
|
createdAt: new Date()
|
|
4048
4289
|
})
|
|
4290
|
+
|
|
4291
|
+
aggregate.addDomainEvent(new ${name}Created(id.value))
|
|
4292
|
+
|
|
4293
|
+
return aggregate
|
|
4049
4294
|
}
|
|
4050
4295
|
|
|
4051
4296
|
get name() { return this.props.name }
|
|
4052
4297
|
}
|
|
4298
|
+
`;
|
|
4299
|
+
}
|
|
4300
|
+
generateCreatedEvent(name) {
|
|
4301
|
+
return `import { DomainEvent } from '@gravito/enterprise'
|
|
4302
|
+
|
|
4303
|
+
export class ${name}Created extends DomainEvent {
|
|
4304
|
+
constructor(public readonly aggregateId: string) {
|
|
4305
|
+
super()
|
|
4306
|
+
}
|
|
4307
|
+
|
|
4308
|
+
get eventName(): string {
|
|
4309
|
+
return '${this.context?.nameKebabCase}.created'
|
|
4310
|
+
}
|
|
4311
|
+
}
|
|
4053
4312
|
`;
|
|
4054
4313
|
}
|
|
4055
4314
|
generateRepositoryInterface(name) {
|
|
4056
4315
|
return `import { Repository } from '@gravito/enterprise'
|
|
4057
|
-
import { ${name} } from '../
|
|
4316
|
+
import { ${name} } from '../Aggregates/${name}'
|
|
4317
|
+
import { ${name}Id } from '../ValueObjects/${name}Id'
|
|
4058
4318
|
|
|
4059
|
-
export interface I${name}Repository extends Repository<${name},
|
|
4319
|
+
export interface I${name}Repository extends Repository<${name}, ${name}Id> {
|
|
4060
4320
|
// Add custom methods here
|
|
4061
4321
|
}
|
|
4062
4322
|
`;
|
|
@@ -4067,7 +4327,8 @@ export interface I${name}Repository extends Repository<${name}, string> {
|
|
|
4067
4327
|
generateUseCase(name) {
|
|
4068
4328
|
return `import { UseCase } from '@gravito/enterprise'
|
|
4069
4329
|
import { I${name}Repository } from '../../Domain/Contracts/I${name}Repository'
|
|
4070
|
-
import { ${name} } from '../../Domain/
|
|
4330
|
+
import { ${name} } from '../../Domain/Aggregates/${name}'
|
|
4331
|
+
import { ${name}Id } from '../../Domain/ValueObjects/${name}Id'
|
|
4071
4332
|
|
|
4072
4333
|
export interface Create${name}Input {
|
|
4073
4334
|
name: string
|
|
@@ -4079,12 +4340,12 @@ export class Create${name} extends UseCase<Create${name}Input, string> {
|
|
|
4079
4340
|
}
|
|
4080
4341
|
|
|
4081
4342
|
async execute(input: Create${name}Input): Promise<string> {
|
|
4082
|
-
const id =
|
|
4343
|
+
const id = ${name}Id.create()
|
|
4083
4344
|
const entity = ${name}.create(id, input.name)
|
|
4084
4345
|
|
|
4085
4346
|
await this.repository.save(entity)
|
|
4086
4347
|
|
|
4087
|
-
return id
|
|
4348
|
+
return id.value
|
|
4088
4349
|
}
|
|
4089
4350
|
}
|
|
4090
4351
|
`;
|
|
@@ -4094,17 +4355,16 @@ export class Create${name} extends UseCase<Create${name}Input, string> {
|
|
|
4094
4355
|
// ─────────────────────────────────────────────────────────────
|
|
4095
4356
|
generateAtlasRepository(name) {
|
|
4096
4357
|
return `import { I${name}Repository } from '../../Domain/Contracts/I${name}Repository'
|
|
4097
|
-
import { ${name} } from '../../Domain/
|
|
4098
|
-
import {
|
|
4358
|
+
import { ${name} } from '../../Domain/Aggregates/${name}'
|
|
4359
|
+
import { ${name}Id } from '../../Domain/ValueObjects/${name}Id'
|
|
4099
4360
|
|
|
4100
4361
|
export class Atlas${name}Repository implements I${name}Repository {
|
|
4101
4362
|
async save(entity: ${name}): Promise<void> {
|
|
4102
|
-
//
|
|
4103
|
-
console.log('[Atlas] Saving
|
|
4104
|
-
// await DB.table('${name.toLowerCase()}s').insert({ ... })
|
|
4363
|
+
// Implementation using @gravito/atlas
|
|
4364
|
+
console.log('[Atlas] Saving aggregate:', entity.id.value)
|
|
4105
4365
|
}
|
|
4106
4366
|
|
|
4107
|
-
async findById(id:
|
|
4367
|
+
async findById(id: ${name}Id): Promise<${name} | null> {
|
|
4108
4368
|
return null
|
|
4109
4369
|
}
|
|
4110
4370
|
|
|
@@ -4112,12 +4372,77 @@ export class Atlas${name}Repository implements I${name}Repository {
|
|
|
4112
4372
|
return []
|
|
4113
4373
|
}
|
|
4114
4374
|
|
|
4115
|
-
async delete(id:
|
|
4375
|
+
async delete(id: ${name}Id): Promise<void> {}
|
|
4116
4376
|
|
|
4117
|
-
async exists(id:
|
|
4377
|
+
async exists(id: ${name}Id): Promise<boolean> {
|
|
4118
4378
|
return false
|
|
4119
4379
|
}
|
|
4120
4380
|
}
|
|
4381
|
+
`;
|
|
4382
|
+
}
|
|
4383
|
+
// ─────────────────────────────────────────────────────────────
|
|
4384
|
+
// Test Templates
|
|
4385
|
+
// ─────────────────────────────────────────────────────────────
|
|
4386
|
+
generateUnitTest(name) {
|
|
4387
|
+
return `import { describe, it, expect } from "bun:test";
|
|
4388
|
+
import { ${name} } from "../src/Domain/Aggregates/${name}";
|
|
4389
|
+
import { ${name}Id } from "../src/Domain/ValueObjects/${name}Id";
|
|
4390
|
+
|
|
4391
|
+
describe("${name} Aggregate", () => {
|
|
4392
|
+
it("should create a new aggregate with a domain event", () => {
|
|
4393
|
+
const id = ${name}Id.create();
|
|
4394
|
+
const aggregate = ${name}.create(id, "Test Name");
|
|
4395
|
+
|
|
4396
|
+
expect(aggregate.id).toBe(id);
|
|
4397
|
+
expect(aggregate.name).toBe("Test Name");
|
|
4398
|
+
expect(aggregate.pullDomainEvents()).toHaveLength(1);
|
|
4399
|
+
});
|
|
4400
|
+
});`;
|
|
4401
|
+
}
|
|
4402
|
+
generateIntegrationTest(name) {
|
|
4403
|
+
return `import { describe, it, expect, beforeAll } from "bun:test";
|
|
4404
|
+
import { PlanetCore } from "@gravito/core";
|
|
4405
|
+
|
|
4406
|
+
describe("${name} Integration", () => {
|
|
4407
|
+
let core: PlanetCore;
|
|
4408
|
+
|
|
4409
|
+
beforeAll(async () => {
|
|
4410
|
+
core = new PlanetCore();
|
|
4411
|
+
// Setup dependencies here
|
|
4412
|
+
});
|
|
4413
|
+
|
|
4414
|
+
it("should handle the creation flow", async () => {
|
|
4415
|
+
expect(true).toBe(true); // Placeholder for actual integration logic
|
|
4416
|
+
});
|
|
4417
|
+
});`;
|
|
4418
|
+
}
|
|
4419
|
+
// ─────────────────────────────────────────────────────────────
|
|
4420
|
+
// Interface Templates
|
|
4421
|
+
// ─────────────────────────────────────────────────────────────
|
|
4422
|
+
generateController(name) {
|
|
4423
|
+
return `import type { GravitoContext } from '@gravito/core'
|
|
4424
|
+
import { Create${name} } from '../../../Application/UseCases/Create${name}'
|
|
4425
|
+
|
|
4426
|
+
export class ${name}Controller {
|
|
4427
|
+
constructor(private createUseCase: Create${name}) {}
|
|
4428
|
+
|
|
4429
|
+
async store(ctx: GravitoContext) {
|
|
4430
|
+
const body = await ctx.req.json()
|
|
4431
|
+
const id = await this.createUseCase.execute({ name: body.name })
|
|
4432
|
+
|
|
4433
|
+
return ctx.json({
|
|
4434
|
+
success: true,
|
|
4435
|
+
data: { id }
|
|
4436
|
+
}, 201)
|
|
4437
|
+
}
|
|
4438
|
+
|
|
4439
|
+
async index(ctx: GravitoContext) {
|
|
4440
|
+
return ctx.json({
|
|
4441
|
+
success: true,
|
|
4442
|
+
data: []
|
|
4443
|
+
})
|
|
4444
|
+
}
|
|
4445
|
+
}
|
|
4121
4446
|
`;
|
|
4122
4447
|
}
|
|
4123
4448
|
// ─────────────────────────────────────────────────────────────
|
|
@@ -4126,17 +4451,22 @@ export class Atlas${name}Repository implements I${name}Repository {
|
|
|
4126
4451
|
generateEntryPoint(name) {
|
|
4127
4452
|
return `import { ServiceProvider, type Container } from '@gravito/core'
|
|
4128
4453
|
import { Atlas${name}Repository } from './Infrastructure/Persistence/Atlas${name}Repository'
|
|
4454
|
+
import { Create${name} } from './Application/UseCases/Create${name}'
|
|
4455
|
+
import { ${name}Controller } from './Interface/Http/Controllers/${name}Controller'
|
|
4129
4456
|
|
|
4130
4457
|
export class ${name}ServiceProvider extends ServiceProvider {
|
|
4131
4458
|
register(container: Container): void {
|
|
4132
|
-
// Bind Repository
|
|
4459
|
+
// 1. Bind Repository (Infrastructure)
|
|
4133
4460
|
container.singleton('${name.toLowerCase()}.repo', () => new Atlas${name}Repository())
|
|
4134
4461
|
|
|
4135
|
-
// Bind UseCases
|
|
4136
|
-
container.singleton('${name.toLowerCase()}.create', () => {
|
|
4137
|
-
return new
|
|
4138
|
-
|
|
4139
|
-
|
|
4462
|
+
// 2. Bind UseCases (Application)
|
|
4463
|
+
container.singleton('${name.toLowerCase()}.usecase.create', (c) => {
|
|
4464
|
+
return new Create${name}(c.make('${name.toLowerCase()}.repo'))
|
|
4465
|
+
})
|
|
4466
|
+
|
|
4467
|
+
// 3. Bind Controllers (Interface)
|
|
4468
|
+
container.singleton('${name.toLowerCase()}.controller', (c) => {
|
|
4469
|
+
return new ${name}Controller(c.make('${name.toLowerCase()}.usecase.create'))
|
|
4140
4470
|
})
|
|
4141
4471
|
}
|
|
4142
4472
|
|
|
@@ -4247,7 +4577,9 @@ var ProfileResolver = class _ProfileResolver {
|
|
|
4247
4577
|
storage: "local",
|
|
4248
4578
|
session: "file"
|
|
4249
4579
|
},
|
|
4250
|
-
features: []
|
|
4580
|
+
features: [],
|
|
4581
|
+
workers: "basic"
|
|
4582
|
+
// Basic workers configuration for core profile
|
|
4251
4583
|
},
|
|
4252
4584
|
scale: {
|
|
4253
4585
|
drivers: {
|
|
@@ -4257,7 +4589,9 @@ var ProfileResolver = class _ProfileResolver {
|
|
|
4257
4589
|
storage: "s3",
|
|
4258
4590
|
session: "redis"
|
|
4259
4591
|
},
|
|
4260
|
-
features: ["stream", "nebula"]
|
|
4592
|
+
features: ["stream", "nebula"],
|
|
4593
|
+
workers: "advanced"
|
|
4594
|
+
// Advanced workers with Bun optimizations
|
|
4261
4595
|
},
|
|
4262
4596
|
enterprise: {
|
|
4263
4597
|
drivers: {
|
|
@@ -4267,14 +4601,17 @@ var ProfileResolver = class _ProfileResolver {
|
|
|
4267
4601
|
storage: "s3",
|
|
4268
4602
|
session: "redis"
|
|
4269
4603
|
},
|
|
4270
|
-
features: ["stream", "nebula", "monitor", "sentinel", "fortify"]
|
|
4604
|
+
features: ["stream", "nebula", "monitor", "sentinel", "fortify"],
|
|
4605
|
+
workers: "production"
|
|
4606
|
+
// Production-optimized workers
|
|
4271
4607
|
}
|
|
4272
4608
|
};
|
|
4273
4609
|
resolve(profile = "core", withFeatures = []) {
|
|
4274
4610
|
const base = _ProfileResolver.DEFAULTS[profile] || _ProfileResolver.DEFAULTS.core;
|
|
4275
4611
|
const config = {
|
|
4276
4612
|
drivers: { ...base.drivers },
|
|
4277
|
-
features: [...base.features]
|
|
4613
|
+
features: [...base.features],
|
|
4614
|
+
workers: base.workers
|
|
4278
4615
|
};
|
|
4279
4616
|
for (const feature of withFeatures) {
|
|
4280
4617
|
this.applyFeature(config, feature);
|