@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.cjs
CHANGED
|
@@ -1055,6 +1055,118 @@ export default {
|
|
|
1055
1055
|
}
|
|
1056
1056
|
`;
|
|
1057
1057
|
}
|
|
1058
|
+
/**
|
|
1059
|
+
* Generate workers configuration for job queue system
|
|
1060
|
+
*/
|
|
1061
|
+
static generateWorkersConfig(level = "basic") {
|
|
1062
|
+
switch (level) {
|
|
1063
|
+
case "advanced":
|
|
1064
|
+
return this.generateAdvancedWorkersConfig();
|
|
1065
|
+
case "production":
|
|
1066
|
+
return this.generateProductionWorkersConfig();
|
|
1067
|
+
default:
|
|
1068
|
+
return this.generateBasicWorkersConfig();
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
1071
|
+
/**
|
|
1072
|
+
* Generate basic workers configuration
|
|
1073
|
+
*/
|
|
1074
|
+
static generateBasicWorkersConfig() {
|
|
1075
|
+
return ` /**
|
|
1076
|
+
* Workers Configuration
|
|
1077
|
+
*
|
|
1078
|
+
* Manages job execution in isolated worker threads.
|
|
1079
|
+
* Automatically selects best available runtime (Bun or Node.js).
|
|
1080
|
+
*/
|
|
1081
|
+
workers: {
|
|
1082
|
+
// Runtime environment: 'auto' | 'bun' | 'node'
|
|
1083
|
+
runtime: process.env.WORKERS_RUNTIME as 'auto' | 'bun' | 'node' ?? 'auto',
|
|
1084
|
+
|
|
1085
|
+
pool: {
|
|
1086
|
+
poolSize: Number.parseInt(process.env.WORKERS_POOL_SIZE ?? '4', 10),
|
|
1087
|
+
minWorkers: Number.parseInt(process.env.WORKERS_MIN_WORKERS ?? '0', 10),
|
|
1088
|
+
healthCheckInterval: 30000,
|
|
1089
|
+
},
|
|
1090
|
+
|
|
1091
|
+
execution: {
|
|
1092
|
+
maxExecutionTime: Number.parseInt(process.env.WORKERS_MAX_EXECUTION_TIME ?? '30000', 10),
|
|
1093
|
+
maxMemory: Number.parseInt(process.env.WORKERS_MAX_MEMORY ?? '0', 10),
|
|
1094
|
+
idleTimeout: Number.parseInt(process.env.WORKERS_IDLE_TIMEOUT ?? '60000', 10),
|
|
1095
|
+
isolateContexts: process.env.WORKERS_ISOLATE_CONTEXTS === 'true',
|
|
1096
|
+
},
|
|
1097
|
+
},`;
|
|
1098
|
+
}
|
|
1099
|
+
/**
|
|
1100
|
+
* Generate advanced workers configuration with Bun optimizations
|
|
1101
|
+
*/
|
|
1102
|
+
static generateAdvancedWorkersConfig() {
|
|
1103
|
+
return ` /**
|
|
1104
|
+
* Workers Configuration (Advanced)
|
|
1105
|
+
*
|
|
1106
|
+
* Manages job execution in isolated worker threads.
|
|
1107
|
+
* Includes Bun-specific optimizations for enhanced performance.
|
|
1108
|
+
*
|
|
1109
|
+
* Performance characteristics:
|
|
1110
|
+
* - Bun: 2-241x faster message passing, 20-30% less memory (smol mode)
|
|
1111
|
+
* - Node.js: Stable, widely tested, compatible
|
|
1112
|
+
*/
|
|
1113
|
+
workers: {
|
|
1114
|
+
runtime: process.env.WORKERS_RUNTIME as 'auto' | 'bun' | 'node' ?? 'auto',
|
|
1115
|
+
|
|
1116
|
+
pool: {
|
|
1117
|
+
poolSize: Number.parseInt(process.env.WORKERS_POOL_SIZE ?? '4', 10),
|
|
1118
|
+
minWorkers: Number.parseInt(process.env.WORKERS_MIN_WORKERS ?? '1', 10),
|
|
1119
|
+
healthCheckInterval: 30000,
|
|
1120
|
+
},
|
|
1121
|
+
|
|
1122
|
+
execution: {
|
|
1123
|
+
maxExecutionTime: Number.parseInt(process.env.WORKERS_MAX_EXECUTION_TIME ?? '30000', 10),
|
|
1124
|
+
maxMemory: Number.parseInt(process.env.WORKERS_MAX_MEMORY ?? '0', 10),
|
|
1125
|
+
idleTimeout: Number.parseInt(process.env.WORKERS_IDLE_TIMEOUT ?? '60000', 10),
|
|
1126
|
+
isolateContexts: process.env.WORKERS_ISOLATE_CONTEXTS === 'true',
|
|
1127
|
+
},
|
|
1128
|
+
|
|
1129
|
+
// Bun-specific optimizations
|
|
1130
|
+
bun: {
|
|
1131
|
+
smol: process.env.WORKERS_BUN_SMOL === 'true',
|
|
1132
|
+
preload: process.env.WORKERS_BUN_PRELOAD
|
|
1133
|
+
? process.env.WORKERS_BUN_PRELOAD.split(',').map((p) => p.trim())
|
|
1134
|
+
: undefined,
|
|
1135
|
+
inspectPort: process.env.WORKERS_BUN_INSPECT_PORT
|
|
1136
|
+
? Number.parseInt(process.env.WORKERS_BUN_INSPECT_PORT, 10)
|
|
1137
|
+
: undefined,
|
|
1138
|
+
},
|
|
1139
|
+
},`;
|
|
1140
|
+
}
|
|
1141
|
+
/**
|
|
1142
|
+
* Generate production-optimized workers configuration
|
|
1143
|
+
*/
|
|
1144
|
+
static generateProductionWorkersConfig() {
|
|
1145
|
+
return ` /**
|
|
1146
|
+
* Workers Configuration (Production Optimized)
|
|
1147
|
+
*/
|
|
1148
|
+
workers: {
|
|
1149
|
+
runtime: 'auto' as const,
|
|
1150
|
+
|
|
1151
|
+
pool: {
|
|
1152
|
+
poolSize: Number.parseInt(process.env.WORKERS_POOL_SIZE ?? '8', 10),
|
|
1153
|
+
minWorkers: 2,
|
|
1154
|
+
healthCheckInterval: 30000,
|
|
1155
|
+
},
|
|
1156
|
+
|
|
1157
|
+
execution: {
|
|
1158
|
+
maxExecutionTime: 30000,
|
|
1159
|
+
maxMemory: Number.parseInt(process.env.WORKERS_MAX_MEMORY ?? '512', 10),
|
|
1160
|
+
idleTimeout: 60000,
|
|
1161
|
+
isolateContexts: false,
|
|
1162
|
+
},
|
|
1163
|
+
|
|
1164
|
+
bun: {
|
|
1165
|
+
smol: true,
|
|
1166
|
+
preload: process.env.WORKERS_BUN_PRELOAD?.split(',').map((p) => p.trim()),
|
|
1167
|
+
},
|
|
1168
|
+
},`;
|
|
1169
|
+
}
|
|
1058
1170
|
};
|
|
1059
1171
|
|
|
1060
1172
|
// src/utils/ServiceProviderGenerator.ts
|
|
@@ -2442,6 +2554,30 @@ var ModuleGenerator = class {
|
|
|
2442
2554
|
]
|
|
2443
2555
|
}
|
|
2444
2556
|
]
|
|
2557
|
+
},
|
|
2558
|
+
// UserInterface Layer
|
|
2559
|
+
{
|
|
2560
|
+
type: "directory",
|
|
2561
|
+
name: "UserInterface",
|
|
2562
|
+
children: [
|
|
2563
|
+
{
|
|
2564
|
+
type: "directory",
|
|
2565
|
+
name: "Http",
|
|
2566
|
+
children: [
|
|
2567
|
+
{
|
|
2568
|
+
type: "directory",
|
|
2569
|
+
name: "Controllers",
|
|
2570
|
+
children: [
|
|
2571
|
+
{
|
|
2572
|
+
type: "file",
|
|
2573
|
+
name: `${name}Controller.ts`,
|
|
2574
|
+
content: this.generateController(name)
|
|
2575
|
+
}
|
|
2576
|
+
]
|
|
2577
|
+
}
|
|
2578
|
+
]
|
|
2579
|
+
}
|
|
2580
|
+
]
|
|
2445
2581
|
}
|
|
2446
2582
|
]
|
|
2447
2583
|
};
|
|
@@ -2457,17 +2593,13 @@ import { ${name}Created } from '../../Events/${name}Created'
|
|
|
2457
2593
|
import { ${name}Status } from './${name}Status'
|
|
2458
2594
|
|
|
2459
2595
|
export interface ${name}Props {
|
|
2460
|
-
// Add properties here
|
|
2461
2596
|
status: ${name}Status
|
|
2462
2597
|
createdAt: Date
|
|
2463
2598
|
}
|
|
2464
2599
|
|
|
2465
2600
|
export class ${name} extends AggregateRoot<Id> {
|
|
2466
|
-
private props: ${name}Props
|
|
2467
|
-
|
|
2468
|
-
private constructor(id: Id, props: ${name}Props) {
|
|
2601
|
+
private constructor(id: Id, private props: ${name}Props) {
|
|
2469
2602
|
super(id)
|
|
2470
|
-
this.props = props
|
|
2471
2603
|
}
|
|
2472
2604
|
|
|
2473
2605
|
static create(id: Id): ${name} {
|
|
@@ -2485,7 +2617,12 @@ export class ${name} extends AggregateRoot<Id> {
|
|
|
2485
2617
|
return this.props.status
|
|
2486
2618
|
}
|
|
2487
2619
|
|
|
2488
|
-
|
|
2620
|
+
/**
|
|
2621
|
+
* Complete the ${name} process
|
|
2622
|
+
*/
|
|
2623
|
+
complete(): void {
|
|
2624
|
+
this.props.status = ${name}Status.COMPLETED
|
|
2625
|
+
}
|
|
2489
2626
|
}
|
|
2490
2627
|
`;
|
|
2491
2628
|
}
|
|
@@ -2510,17 +2647,13 @@ export enum ${name}Status {
|
|
|
2510
2647
|
import { DomainEvent } from '@gravito/enterprise'
|
|
2511
2648
|
|
|
2512
2649
|
export class ${name}Created extends DomainEvent {
|
|
2513
|
-
constructor(public readonly
|
|
2650
|
+
constructor(public readonly aggregateId: string) {
|
|
2514
2651
|
super()
|
|
2515
2652
|
}
|
|
2516
2653
|
|
|
2517
2654
|
override get eventName(): string {
|
|
2518
2655
|
return '${name.toLowerCase()}.created'
|
|
2519
2656
|
}
|
|
2520
|
-
|
|
2521
|
-
get aggregateId(): string {
|
|
2522
|
-
return this.${name.toLowerCase()}Id
|
|
2523
|
-
}
|
|
2524
2657
|
}
|
|
2525
2658
|
`;
|
|
2526
2659
|
}
|
|
@@ -2547,7 +2680,6 @@ import { Command } from '@gravito/enterprise'
|
|
|
2547
2680
|
|
|
2548
2681
|
export class Create${name}Command extends Command {
|
|
2549
2682
|
constructor(
|
|
2550
|
-
// Add command properties
|
|
2551
2683
|
public readonly id?: string
|
|
2552
2684
|
) {
|
|
2553
2685
|
super()
|
|
@@ -2602,13 +2734,15 @@ export class Get${name}ByIdQuery extends Query {
|
|
|
2602
2734
|
import { QueryHandler } from '@gravito/enterprise'
|
|
2603
2735
|
import type { I${name}Repository } from '../../../Domain/Repositories/I${name}Repository'
|
|
2604
2736
|
import type { ${name}DTO } from '../../DTOs/${name}DTO'
|
|
2737
|
+
import { Id } from '../../../../../Shared/Domain/ValueObjects/Id'
|
|
2605
2738
|
import type { Get${name}ByIdQuery } from './Get${name}ByIdQuery'
|
|
2606
2739
|
|
|
2607
2740
|
export class Get${name}ByIdHandler implements QueryHandler<Get${name}ByIdQuery, ${name}DTO | null> {
|
|
2608
2741
|
constructor(private repository: I${name}Repository) {}
|
|
2609
2742
|
|
|
2610
2743
|
async handle(query: Get${name}ByIdQuery): Promise<${name}DTO | null> {
|
|
2611
|
-
const
|
|
2744
|
+
const id = Id.from(query.id)
|
|
2745
|
+
const aggregate = await this.repository.findById(id)
|
|
2612
2746
|
if (!aggregate) return null
|
|
2613
2747
|
|
|
2614
2748
|
return {
|
|
@@ -2629,7 +2763,6 @@ import type { ${name}Status } from '../../Domain/Aggregates/${name}/${name}Statu
|
|
|
2629
2763
|
export interface ${name}DTO {
|
|
2630
2764
|
id: string
|
|
2631
2765
|
status: ${name}Status
|
|
2632
|
-
// Add more fields
|
|
2633
2766
|
}
|
|
2634
2767
|
`;
|
|
2635
2768
|
}
|
|
@@ -2640,29 +2773,29 @@ export interface ${name}DTO {
|
|
|
2640
2773
|
|
|
2641
2774
|
import type { ${name} } from '../../Domain/Aggregates/${name}/${name}'
|
|
2642
2775
|
import type { I${name}Repository } from '../../Domain/Repositories/I${name}Repository'
|
|
2643
|
-
import
|
|
2644
|
-
|
|
2645
|
-
const store = new Map<string, ${name}>()
|
|
2776
|
+
import { Id } from '../../../../../Shared/Domain/ValueObjects/Id'
|
|
2646
2777
|
|
|
2647
2778
|
export class ${name}Repository implements I${name}Repository {
|
|
2779
|
+
private store = new Map<string, ${name}>()
|
|
2780
|
+
|
|
2648
2781
|
async findById(id: Id): Promise<${name} | null> {
|
|
2649
|
-
return store.get(id.value) ?? null
|
|
2782
|
+
return this.store.get(id.value) ?? null
|
|
2650
2783
|
}
|
|
2651
2784
|
|
|
2652
2785
|
async save(aggregate: ${name}): Promise<void> {
|
|
2653
|
-
store.set(aggregate.id.value, aggregate)
|
|
2786
|
+
this.store.set(aggregate.id.value, aggregate)
|
|
2654
2787
|
}
|
|
2655
2788
|
|
|
2656
2789
|
async delete(id: Id): Promise<void> {
|
|
2657
|
-
store.delete(id.value)
|
|
2790
|
+
this.store.delete(id.value)
|
|
2658
2791
|
}
|
|
2659
2792
|
|
|
2660
2793
|
async findAll(): Promise<${name}[]> {
|
|
2661
|
-
return Array.from(store.values())
|
|
2794
|
+
return Array.from(this.store.values())
|
|
2662
2795
|
}
|
|
2663
2796
|
|
|
2664
2797
|
async exists(id: Id): Promise<boolean> {
|
|
2665
|
-
return store.has(id.value)
|
|
2798
|
+
return this.store.has(id.value)
|
|
2666
2799
|
}
|
|
2667
2800
|
}
|
|
2668
2801
|
`;
|
|
@@ -2684,6 +2817,37 @@ export class ${name}ServiceProvider extends ServiceProvider {
|
|
|
2684
2817
|
console.log('[${name}] Module loaded')
|
|
2685
2818
|
}
|
|
2686
2819
|
}
|
|
2820
|
+
`;
|
|
2821
|
+
}
|
|
2822
|
+
generateController(name) {
|
|
2823
|
+
return `/**
|
|
2824
|
+
* ${name} Controller
|
|
2825
|
+
*/
|
|
2826
|
+
|
|
2827
|
+
import type { GravitoContext } from '@gravito/core'
|
|
2828
|
+
|
|
2829
|
+
export class ${name}Controller {
|
|
2830
|
+
/**
|
|
2831
|
+
* GET /${name.toLowerCase()}
|
|
2832
|
+
*/
|
|
2833
|
+
async index(ctx: GravitoContext) {
|
|
2834
|
+
return ctx.json({
|
|
2835
|
+
success: true,
|
|
2836
|
+
data: []
|
|
2837
|
+
})
|
|
2838
|
+
}
|
|
2839
|
+
|
|
2840
|
+
/**
|
|
2841
|
+
* GET /${name.toLowerCase()}/:id
|
|
2842
|
+
*/
|
|
2843
|
+
async show(ctx: GravitoContext) {
|
|
2844
|
+
const id = ctx.req.param('id')
|
|
2845
|
+
return ctx.json({
|
|
2846
|
+
success: true,
|
|
2847
|
+
data: { id }
|
|
2848
|
+
})
|
|
2849
|
+
}
|
|
2850
|
+
}
|
|
2687
2851
|
`;
|
|
2688
2852
|
}
|
|
2689
2853
|
};
|
|
@@ -2858,24 +3022,39 @@ export class Email extends ValueObject<EmailProps> {
|
|
|
2858
3022
|
|
|
2859
3023
|
import type { DomainEvent } from '@gravito/enterprise'
|
|
2860
3024
|
|
|
2861
|
-
type EventHandler = (event:
|
|
3025
|
+
type EventHandler<T extends DomainEvent = any> = (event: T) => void | Promise<void>
|
|
2862
3026
|
|
|
2863
3027
|
export class EventDispatcher {
|
|
2864
3028
|
private handlers: Map<string, EventHandler[]> = new Map()
|
|
2865
3029
|
|
|
2866
|
-
|
|
3030
|
+
/**
|
|
3031
|
+
* Subscribe to an event
|
|
3032
|
+
*/
|
|
3033
|
+
subscribe<T extends DomainEvent>(eventName: string, handler: EventHandler<T>): void {
|
|
2867
3034
|
const handlers = this.handlers.get(eventName) ?? []
|
|
2868
3035
|
handlers.push(handler)
|
|
2869
3036
|
this.handlers.set(eventName, handlers)
|
|
2870
3037
|
}
|
|
2871
3038
|
|
|
3039
|
+
/**
|
|
3040
|
+
* Dispatch a single event
|
|
3041
|
+
*/
|
|
2872
3042
|
async dispatch(event: DomainEvent): Promise<void> {
|
|
2873
3043
|
const handlers = this.handlers.get(event.eventName) ?? []
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
3044
|
+
const promises = handlers.map(handler => {
|
|
3045
|
+
try {
|
|
3046
|
+
return handler(event)
|
|
3047
|
+
} catch (error) {
|
|
3048
|
+
console.error(\`[EventDispatcher] Error in handler for \${event.eventName}:\`, error)
|
|
3049
|
+
}
|
|
3050
|
+
})
|
|
3051
|
+
|
|
3052
|
+
await Promise.all(promises)
|
|
2877
3053
|
}
|
|
2878
3054
|
|
|
3055
|
+
/**
|
|
3056
|
+
* Dispatch multiple events sequentially
|
|
3057
|
+
*/
|
|
2879
3058
|
async dispatchAll(events: DomainEvent[]): Promise<void> {
|
|
2880
3059
|
for (const event of events) {
|
|
2881
3060
|
await this.dispatch(event)
|
|
@@ -3985,9 +4164,9 @@ var SatelliteGenerator = class extends BaseGenerator {
|
|
|
3985
4164
|
children: [
|
|
3986
4165
|
{
|
|
3987
4166
|
type: "directory",
|
|
3988
|
-
name: "
|
|
4167
|
+
name: "Aggregates",
|
|
3989
4168
|
children: [
|
|
3990
|
-
{ type: "file", name: `${name}.ts`, content: this.
|
|
4169
|
+
{ type: "file", name: `${name}.ts`, content: this.generateAggregate(name) }
|
|
3991
4170
|
]
|
|
3992
4171
|
},
|
|
3993
4172
|
{
|
|
@@ -4001,8 +4180,24 @@ var SatelliteGenerator = class extends BaseGenerator {
|
|
|
4001
4180
|
}
|
|
4002
4181
|
]
|
|
4003
4182
|
},
|
|
4004
|
-
{
|
|
4005
|
-
|
|
4183
|
+
{
|
|
4184
|
+
type: "directory",
|
|
4185
|
+
name: "ValueObjects",
|
|
4186
|
+
children: [
|
|
4187
|
+
{ type: "file", name: `${name}Id.ts`, content: this.generateIdValueObject(name) }
|
|
4188
|
+
]
|
|
4189
|
+
},
|
|
4190
|
+
{
|
|
4191
|
+
type: "directory",
|
|
4192
|
+
name: "Events",
|
|
4193
|
+
children: [
|
|
4194
|
+
{
|
|
4195
|
+
type: "file",
|
|
4196
|
+
name: `${name}Created.ts`,
|
|
4197
|
+
content: this.generateCreatedEvent(name)
|
|
4198
|
+
}
|
|
4199
|
+
]
|
|
4200
|
+
}
|
|
4006
4201
|
]
|
|
4007
4202
|
},
|
|
4008
4203
|
// Application Layer
|
|
@@ -4043,6 +4238,31 @@ var SatelliteGenerator = class extends BaseGenerator {
|
|
|
4043
4238
|
}
|
|
4044
4239
|
]
|
|
4045
4240
|
},
|
|
4241
|
+
// Interface Layer (HTTP/API)
|
|
4242
|
+
{
|
|
4243
|
+
type: "directory",
|
|
4244
|
+
name: "Interface",
|
|
4245
|
+
children: [
|
|
4246
|
+
{
|
|
4247
|
+
type: "directory",
|
|
4248
|
+
name: "Http",
|
|
4249
|
+
children: [
|
|
4250
|
+
{
|
|
4251
|
+
type: "directory",
|
|
4252
|
+
name: "Controllers",
|
|
4253
|
+
children: [
|
|
4254
|
+
{
|
|
4255
|
+
type: "file",
|
|
4256
|
+
name: `${name}Controller.ts`,
|
|
4257
|
+
content: this.generateController(name)
|
|
4258
|
+
}
|
|
4259
|
+
]
|
|
4260
|
+
},
|
|
4261
|
+
{ type: "directory", name: "Middleware", children: [] }
|
|
4262
|
+
]
|
|
4263
|
+
}
|
|
4264
|
+
]
|
|
4265
|
+
},
|
|
4046
4266
|
// Entry Point
|
|
4047
4267
|
{ type: "file", name: "index.ts", content: this.generateEntryPoint(name) },
|
|
4048
4268
|
{
|
|
@@ -4060,13 +4280,12 @@ var SatelliteGenerator = class extends BaseGenerator {
|
|
|
4060
4280
|
{
|
|
4061
4281
|
type: "file",
|
|
4062
4282
|
name: "unit.test.ts",
|
|
4063
|
-
content:
|
|
4064
|
-
|
|
4065
|
-
|
|
4066
|
-
|
|
4067
|
-
|
|
4068
|
-
|
|
4069
|
-
});`
|
|
4283
|
+
content: this.generateUnitTest(name)
|
|
4284
|
+
},
|
|
4285
|
+
{
|
|
4286
|
+
type: "file",
|
|
4287
|
+
name: "integration.test.ts",
|
|
4288
|
+
content: this.generateIntegrationTest(name)
|
|
4070
4289
|
}
|
|
4071
4290
|
]
|
|
4072
4291
|
}
|
|
@@ -4075,35 +4294,76 @@ describe("${name}", () => {
|
|
|
4075
4294
|
// ─────────────────────────────────────────────────────────────
|
|
4076
4295
|
// Domain Templates
|
|
4077
4296
|
// ─────────────────────────────────────────────────────────────
|
|
4078
|
-
|
|
4079
|
-
return `import {
|
|
4297
|
+
generateIdValueObject(name) {
|
|
4298
|
+
return `import { ValueObject } from '@gravito/enterprise'
|
|
4299
|
+
|
|
4300
|
+
interface IdProps {
|
|
4301
|
+
value: string
|
|
4302
|
+
}
|
|
4303
|
+
|
|
4304
|
+
export class ${name}Id extends ValueObject<IdProps> {
|
|
4305
|
+
constructor(value: string) {
|
|
4306
|
+
super({ value })
|
|
4307
|
+
}
|
|
4308
|
+
|
|
4309
|
+
static create(): ${name}Id {
|
|
4310
|
+
return new ${name}Id(crypto.randomUUID())
|
|
4311
|
+
}
|
|
4312
|
+
|
|
4313
|
+
get value(): string { return this.props.value }
|
|
4314
|
+
}
|
|
4315
|
+
`;
|
|
4316
|
+
}
|
|
4317
|
+
generateAggregate(name) {
|
|
4318
|
+
return `import { AggregateRoot } from '@gravito/enterprise'
|
|
4319
|
+
import { ${name}Id } from '../ValueObjects/${name}Id'
|
|
4320
|
+
import { ${name}Created } from '../Events/${name}Created'
|
|
4080
4321
|
|
|
4081
4322
|
export interface ${name}Props {
|
|
4082
4323
|
name: string
|
|
4083
4324
|
createdAt: Date
|
|
4084
4325
|
}
|
|
4085
4326
|
|
|
4086
|
-
export class ${name} extends
|
|
4087
|
-
constructor(id:
|
|
4327
|
+
export class ${name} extends AggregateRoot<${name}Id> {
|
|
4328
|
+
constructor(id: ${name}Id, private props: ${name}Props) {
|
|
4088
4329
|
super(id)
|
|
4089
4330
|
}
|
|
4090
4331
|
|
|
4091
|
-
static create(id:
|
|
4092
|
-
|
|
4332
|
+
static create(id: ${name}Id, name: string): ${name} {
|
|
4333
|
+
const aggregate = new ${name}(id, {
|
|
4093
4334
|
name,
|
|
4094
4335
|
createdAt: new Date()
|
|
4095
4336
|
})
|
|
4337
|
+
|
|
4338
|
+
aggregate.addDomainEvent(new ${name}Created(id.value))
|
|
4339
|
+
|
|
4340
|
+
return aggregate
|
|
4096
4341
|
}
|
|
4097
4342
|
|
|
4098
4343
|
get name() { return this.props.name }
|
|
4099
4344
|
}
|
|
4345
|
+
`;
|
|
4346
|
+
}
|
|
4347
|
+
generateCreatedEvent(name) {
|
|
4348
|
+
return `import { DomainEvent } from '@gravito/enterprise'
|
|
4349
|
+
|
|
4350
|
+
export class ${name}Created extends DomainEvent {
|
|
4351
|
+
constructor(public readonly aggregateId: string) {
|
|
4352
|
+
super()
|
|
4353
|
+
}
|
|
4354
|
+
|
|
4355
|
+
get eventName(): string {
|
|
4356
|
+
return '${this.context?.nameKebabCase}.created'
|
|
4357
|
+
}
|
|
4358
|
+
}
|
|
4100
4359
|
`;
|
|
4101
4360
|
}
|
|
4102
4361
|
generateRepositoryInterface(name) {
|
|
4103
4362
|
return `import { Repository } from '@gravito/enterprise'
|
|
4104
|
-
import { ${name} } from '../
|
|
4363
|
+
import { ${name} } from '../Aggregates/${name}'
|
|
4364
|
+
import { ${name}Id } from '../ValueObjects/${name}Id'
|
|
4105
4365
|
|
|
4106
|
-
export interface I${name}Repository extends Repository<${name},
|
|
4366
|
+
export interface I${name}Repository extends Repository<${name}, ${name}Id> {
|
|
4107
4367
|
// Add custom methods here
|
|
4108
4368
|
}
|
|
4109
4369
|
`;
|
|
@@ -4114,7 +4374,8 @@ export interface I${name}Repository extends Repository<${name}, string> {
|
|
|
4114
4374
|
generateUseCase(name) {
|
|
4115
4375
|
return `import { UseCase } from '@gravito/enterprise'
|
|
4116
4376
|
import { I${name}Repository } from '../../Domain/Contracts/I${name}Repository'
|
|
4117
|
-
import { ${name} } from '../../Domain/
|
|
4377
|
+
import { ${name} } from '../../Domain/Aggregates/${name}'
|
|
4378
|
+
import { ${name}Id } from '../../Domain/ValueObjects/${name}Id'
|
|
4118
4379
|
|
|
4119
4380
|
export interface Create${name}Input {
|
|
4120
4381
|
name: string
|
|
@@ -4126,12 +4387,12 @@ export class Create${name} extends UseCase<Create${name}Input, string> {
|
|
|
4126
4387
|
}
|
|
4127
4388
|
|
|
4128
4389
|
async execute(input: Create${name}Input): Promise<string> {
|
|
4129
|
-
const id =
|
|
4390
|
+
const id = ${name}Id.create()
|
|
4130
4391
|
const entity = ${name}.create(id, input.name)
|
|
4131
4392
|
|
|
4132
4393
|
await this.repository.save(entity)
|
|
4133
4394
|
|
|
4134
|
-
return id
|
|
4395
|
+
return id.value
|
|
4135
4396
|
}
|
|
4136
4397
|
}
|
|
4137
4398
|
`;
|
|
@@ -4141,17 +4402,16 @@ export class Create${name} extends UseCase<Create${name}Input, string> {
|
|
|
4141
4402
|
// ─────────────────────────────────────────────────────────────
|
|
4142
4403
|
generateAtlasRepository(name) {
|
|
4143
4404
|
return `import { I${name}Repository } from '../../Domain/Contracts/I${name}Repository'
|
|
4144
|
-
import { ${name} } from '../../Domain/
|
|
4145
|
-
import {
|
|
4405
|
+
import { ${name} } from '../../Domain/Aggregates/${name}'
|
|
4406
|
+
import { ${name}Id } from '../../Domain/ValueObjects/${name}Id'
|
|
4146
4407
|
|
|
4147
4408
|
export class Atlas${name}Repository implements I${name}Repository {
|
|
4148
4409
|
async save(entity: ${name}): Promise<void> {
|
|
4149
|
-
//
|
|
4150
|
-
console.log('[Atlas] Saving
|
|
4151
|
-
// await DB.table('${name.toLowerCase()}s').insert({ ... })
|
|
4410
|
+
// Implementation using @gravito/atlas
|
|
4411
|
+
console.log('[Atlas] Saving aggregate:', entity.id.value)
|
|
4152
4412
|
}
|
|
4153
4413
|
|
|
4154
|
-
async findById(id:
|
|
4414
|
+
async findById(id: ${name}Id): Promise<${name} | null> {
|
|
4155
4415
|
return null
|
|
4156
4416
|
}
|
|
4157
4417
|
|
|
@@ -4159,12 +4419,77 @@ export class Atlas${name}Repository implements I${name}Repository {
|
|
|
4159
4419
|
return []
|
|
4160
4420
|
}
|
|
4161
4421
|
|
|
4162
|
-
async delete(id:
|
|
4422
|
+
async delete(id: ${name}Id): Promise<void> {}
|
|
4163
4423
|
|
|
4164
|
-
async exists(id:
|
|
4424
|
+
async exists(id: ${name}Id): Promise<boolean> {
|
|
4165
4425
|
return false
|
|
4166
4426
|
}
|
|
4167
4427
|
}
|
|
4428
|
+
`;
|
|
4429
|
+
}
|
|
4430
|
+
// ─────────────────────────────────────────────────────────────
|
|
4431
|
+
// Test Templates
|
|
4432
|
+
// ─────────────────────────────────────────────────────────────
|
|
4433
|
+
generateUnitTest(name) {
|
|
4434
|
+
return `import { describe, it, expect } from "bun:test";
|
|
4435
|
+
import { ${name} } from "../src/Domain/Aggregates/${name}";
|
|
4436
|
+
import { ${name}Id } from "../src/Domain/ValueObjects/${name}Id";
|
|
4437
|
+
|
|
4438
|
+
describe("${name} Aggregate", () => {
|
|
4439
|
+
it("should create a new aggregate with a domain event", () => {
|
|
4440
|
+
const id = ${name}Id.create();
|
|
4441
|
+
const aggregate = ${name}.create(id, "Test Name");
|
|
4442
|
+
|
|
4443
|
+
expect(aggregate.id).toBe(id);
|
|
4444
|
+
expect(aggregate.name).toBe("Test Name");
|
|
4445
|
+
expect(aggregate.pullDomainEvents()).toHaveLength(1);
|
|
4446
|
+
});
|
|
4447
|
+
});`;
|
|
4448
|
+
}
|
|
4449
|
+
generateIntegrationTest(name) {
|
|
4450
|
+
return `import { describe, it, expect, beforeAll } from "bun:test";
|
|
4451
|
+
import { PlanetCore } from "@gravito/core";
|
|
4452
|
+
|
|
4453
|
+
describe("${name} Integration", () => {
|
|
4454
|
+
let core: PlanetCore;
|
|
4455
|
+
|
|
4456
|
+
beforeAll(async () => {
|
|
4457
|
+
core = new PlanetCore();
|
|
4458
|
+
// Setup dependencies here
|
|
4459
|
+
});
|
|
4460
|
+
|
|
4461
|
+
it("should handle the creation flow", async () => {
|
|
4462
|
+
expect(true).toBe(true); // Placeholder for actual integration logic
|
|
4463
|
+
});
|
|
4464
|
+
});`;
|
|
4465
|
+
}
|
|
4466
|
+
// ─────────────────────────────────────────────────────────────
|
|
4467
|
+
// Interface Templates
|
|
4468
|
+
// ─────────────────────────────────────────────────────────────
|
|
4469
|
+
generateController(name) {
|
|
4470
|
+
return `import type { GravitoContext } from '@gravito/core'
|
|
4471
|
+
import { Create${name} } from '../../../Application/UseCases/Create${name}'
|
|
4472
|
+
|
|
4473
|
+
export class ${name}Controller {
|
|
4474
|
+
constructor(private createUseCase: Create${name}) {}
|
|
4475
|
+
|
|
4476
|
+
async store(ctx: GravitoContext) {
|
|
4477
|
+
const body = await ctx.req.json()
|
|
4478
|
+
const id = await this.createUseCase.execute({ name: body.name })
|
|
4479
|
+
|
|
4480
|
+
return ctx.json({
|
|
4481
|
+
success: true,
|
|
4482
|
+
data: { id }
|
|
4483
|
+
}, 201)
|
|
4484
|
+
}
|
|
4485
|
+
|
|
4486
|
+
async index(ctx: GravitoContext) {
|
|
4487
|
+
return ctx.json({
|
|
4488
|
+
success: true,
|
|
4489
|
+
data: []
|
|
4490
|
+
})
|
|
4491
|
+
}
|
|
4492
|
+
}
|
|
4168
4493
|
`;
|
|
4169
4494
|
}
|
|
4170
4495
|
// ─────────────────────────────────────────────────────────────
|
|
@@ -4173,17 +4498,22 @@ export class Atlas${name}Repository implements I${name}Repository {
|
|
|
4173
4498
|
generateEntryPoint(name) {
|
|
4174
4499
|
return `import { ServiceProvider, type Container } from '@gravito/core'
|
|
4175
4500
|
import { Atlas${name}Repository } from './Infrastructure/Persistence/Atlas${name}Repository'
|
|
4501
|
+
import { Create${name} } from './Application/UseCases/Create${name}'
|
|
4502
|
+
import { ${name}Controller } from './Interface/Http/Controllers/${name}Controller'
|
|
4176
4503
|
|
|
4177
4504
|
export class ${name}ServiceProvider extends ServiceProvider {
|
|
4178
4505
|
register(container: Container): void {
|
|
4179
|
-
// Bind Repository
|
|
4506
|
+
// 1. Bind Repository (Infrastructure)
|
|
4180
4507
|
container.singleton('${name.toLowerCase()}.repo', () => new Atlas${name}Repository())
|
|
4181
4508
|
|
|
4182
|
-
// Bind UseCases
|
|
4183
|
-
container.singleton('${name.toLowerCase()}.create', () => {
|
|
4184
|
-
return new
|
|
4185
|
-
|
|
4186
|
-
|
|
4509
|
+
// 2. Bind UseCases (Application)
|
|
4510
|
+
container.singleton('${name.toLowerCase()}.usecase.create', (c) => {
|
|
4511
|
+
return new Create${name}(c.make('${name.toLowerCase()}.repo'))
|
|
4512
|
+
})
|
|
4513
|
+
|
|
4514
|
+
// 3. Bind Controllers (Interface)
|
|
4515
|
+
container.singleton('${name.toLowerCase()}.controller', (c) => {
|
|
4516
|
+
return new ${name}Controller(c.make('${name.toLowerCase()}.usecase.create'))
|
|
4187
4517
|
})
|
|
4188
4518
|
}
|
|
4189
4519
|
|
|
@@ -4294,7 +4624,9 @@ var ProfileResolver = class _ProfileResolver {
|
|
|
4294
4624
|
storage: "local",
|
|
4295
4625
|
session: "file"
|
|
4296
4626
|
},
|
|
4297
|
-
features: []
|
|
4627
|
+
features: [],
|
|
4628
|
+
workers: "basic"
|
|
4629
|
+
// Basic workers configuration for core profile
|
|
4298
4630
|
},
|
|
4299
4631
|
scale: {
|
|
4300
4632
|
drivers: {
|
|
@@ -4304,7 +4636,9 @@ var ProfileResolver = class _ProfileResolver {
|
|
|
4304
4636
|
storage: "s3",
|
|
4305
4637
|
session: "redis"
|
|
4306
4638
|
},
|
|
4307
|
-
features: ["stream", "nebula"]
|
|
4639
|
+
features: ["stream", "nebula"],
|
|
4640
|
+
workers: "advanced"
|
|
4641
|
+
// Advanced workers with Bun optimizations
|
|
4308
4642
|
},
|
|
4309
4643
|
enterprise: {
|
|
4310
4644
|
drivers: {
|
|
@@ -4314,14 +4648,17 @@ var ProfileResolver = class _ProfileResolver {
|
|
|
4314
4648
|
storage: "s3",
|
|
4315
4649
|
session: "redis"
|
|
4316
4650
|
},
|
|
4317
|
-
features: ["stream", "nebula", "monitor", "sentinel", "fortify"]
|
|
4651
|
+
features: ["stream", "nebula", "monitor", "sentinel", "fortify"],
|
|
4652
|
+
workers: "production"
|
|
4653
|
+
// Production-optimized workers
|
|
4318
4654
|
}
|
|
4319
4655
|
};
|
|
4320
4656
|
resolve(profile = "core", withFeatures = []) {
|
|
4321
4657
|
const base = _ProfileResolver.DEFAULTS[profile] || _ProfileResolver.DEFAULTS.core;
|
|
4322
4658
|
const config = {
|
|
4323
4659
|
drivers: { ...base.drivers },
|
|
4324
|
-
features: [...base.features]
|
|
4660
|
+
features: [...base.features],
|
|
4661
|
+
workers: base.workers
|
|
4325
4662
|
};
|
|
4326
4663
|
for (const feature of withFeatures) {
|
|
4327
4664
|
this.applyFeature(config, feature);
|