@currentjs/gen 0.3.1 → 0.5.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 (69) hide show
  1. package/CHANGELOG.md +8 -289
  2. package/README.md +623 -427
  3. package/dist/cli.js +2 -1
  4. package/dist/commands/commit.js +25 -42
  5. package/dist/commands/createApp.js +1 -0
  6. package/dist/commands/createModule.js +151 -45
  7. package/dist/commands/diff.js +27 -40
  8. package/dist/commands/generateAll.js +141 -291
  9. package/dist/commands/migrateCommit.js +6 -18
  10. package/dist/commands/migratePush.d.ts +1 -0
  11. package/dist/commands/migratePush.js +135 -0
  12. package/dist/commands/migrateUpdate.d.ts +1 -0
  13. package/dist/commands/migrateUpdate.js +147 -0
  14. package/dist/commands/newGenerateAll.d.ts +4 -0
  15. package/dist/commands/newGenerateAll.js +336 -0
  16. package/dist/generators/controllerGenerator.d.ts +43 -19
  17. package/dist/generators/controllerGenerator.js +547 -329
  18. package/dist/generators/domainLayerGenerator.d.ts +21 -0
  19. package/dist/generators/domainLayerGenerator.js +276 -0
  20. package/dist/generators/dtoGenerator.d.ts +21 -0
  21. package/dist/generators/dtoGenerator.js +518 -0
  22. package/dist/generators/newControllerGenerator.d.ts +55 -0
  23. package/dist/generators/newControllerGenerator.js +644 -0
  24. package/dist/generators/newServiceGenerator.d.ts +19 -0
  25. package/dist/generators/newServiceGenerator.js +266 -0
  26. package/dist/generators/newStoreGenerator.d.ts +39 -0
  27. package/dist/generators/newStoreGenerator.js +408 -0
  28. package/dist/generators/newTemplateGenerator.d.ts +29 -0
  29. package/dist/generators/newTemplateGenerator.js +510 -0
  30. package/dist/generators/serviceGenerator.d.ts +16 -51
  31. package/dist/generators/serviceGenerator.js +167 -586
  32. package/dist/generators/storeGenerator.d.ts +35 -32
  33. package/dist/generators/storeGenerator.js +291 -238
  34. package/dist/generators/storeGeneratorV2.d.ts +31 -0
  35. package/dist/generators/storeGeneratorV2.js +190 -0
  36. package/dist/generators/templateGenerator.d.ts +21 -21
  37. package/dist/generators/templateGenerator.js +393 -268
  38. package/dist/generators/templates/appTemplates.d.ts +3 -1
  39. package/dist/generators/templates/appTemplates.js +15 -10
  40. package/dist/generators/templates/data/appYamlTemplate +5 -2
  41. package/dist/generators/templates/data/cursorRulesTemplate +315 -221
  42. package/dist/generators/templates/data/frontendScriptTemplate +76 -47
  43. package/dist/generators/templates/data/mainViewTemplate +1 -1
  44. package/dist/generators/templates/data/systemTsTemplate +5 -0
  45. package/dist/generators/templates/index.d.ts +0 -3
  46. package/dist/generators/templates/index.js +0 -3
  47. package/dist/generators/templates/newStoreTemplates.d.ts +5 -0
  48. package/dist/generators/templates/newStoreTemplates.js +141 -0
  49. package/dist/generators/templates/storeTemplates.d.ts +1 -5
  50. package/dist/generators/templates/storeTemplates.js +102 -219
  51. package/dist/generators/templates/viewTemplates.js +1 -1
  52. package/dist/generators/useCaseGenerator.d.ts +13 -0
  53. package/dist/generators/useCaseGenerator.js +188 -0
  54. package/dist/types/configTypes.d.ts +148 -0
  55. package/dist/types/configTypes.js +10 -0
  56. package/dist/utils/childEntityUtils.d.ts +18 -0
  57. package/dist/utils/childEntityUtils.js +78 -0
  58. package/dist/utils/commandUtils.d.ts +43 -0
  59. package/dist/utils/commandUtils.js +124 -0
  60. package/dist/utils/commitUtils.d.ts +4 -1
  61. package/dist/utils/constants.d.ts +10 -0
  62. package/dist/utils/constants.js +13 -1
  63. package/dist/utils/diResolver.d.ts +32 -0
  64. package/dist/utils/diResolver.js +204 -0
  65. package/dist/utils/new_parts_of_migrationUtils.d.ts +0 -0
  66. package/dist/utils/new_parts_of_migrationUtils.js +164 -0
  67. package/dist/utils/typeUtils.d.ts +19 -0
  68. package/dist/utils/typeUtils.js +70 -0
  69. package/package.json +7 -3
package/dist/cli.js CHANGED
@@ -13,13 +13,14 @@ const migrateCommit_1 = require("./commands/migrateCommit");
13
13
  // import { handleMigrateUpdate } from './commands/migrateUpdate';
14
14
  function printHelp() {
15
15
  const title = colors_1.colors.bold(colors_1.colors.brightCyan('currentjs - Clean architecture CLI'));
16
+ const version = colors_1.colors.bold(colors_1.colors.brightCyan('v0.5.0'));
16
17
  const usage = colors_1.colors.bold('Usage:');
17
18
  const options = colors_1.colors.bold('Options:');
18
19
  const cmd = (s) => colors_1.colors.green(s);
19
20
  const flag = (s) => colors_1.colors.yellow(s);
20
21
  const help = `
21
22
  ${title}
22
-
23
+ ${version}
23
24
  ${usage}
24
25
  ${cmd('currentjs create app')} ${colors_1.colors.gray('[name]')}
25
26
  ${cmd('currentjs create module')} ${colors_1.colors.gray('<name>')}
@@ -38,41 +38,16 @@ const fs = __importStar(require("fs"));
38
38
  const path = __importStar(require("path"));
39
39
  const cliUtils_1 = require("../utils/cliUtils");
40
40
  const yaml_1 = require("yaml");
41
- const domainModelGenerator_1 = require("../generators/domainModelGenerator");
42
- const validationGenerator_1 = require("../generators/validationGenerator");
43
- const serviceGenerator_1 = require("../generators/serviceGenerator");
44
- const controllerGenerator_1 = require("../generators/controllerGenerator");
45
- const storeGenerator_1 = require("../generators/storeGenerator");
46
- const templateGenerator_1 = require("../generators/templateGenerator");
47
41
  const generationRegistry_1 = require("../utils/generationRegistry");
48
42
  const commitUtils_1 = require("../utils/commitUtils");
49
43
  const colors_1 = require("../utils/colors");
50
- // legacy inline diff removed in favor of hunks; kept for backward compatibility via utils/commitUtils if needed
51
- function collectFiles(dir) {
52
- if (!fs.existsSync(dir))
53
- return [];
54
- const result = [];
55
- const stack = [dir];
56
- while (stack.length) {
57
- const current = stack.pop();
58
- const entries = fs.readdirSync(current, { withFileTypes: true });
59
- entries.forEach(entry => {
60
- const abs = path.join(current, entry.name);
61
- if (entry.isDirectory())
62
- stack.push(abs);
63
- else
64
- result.push(abs);
65
- });
66
- }
67
- return result;
68
- }
44
+ const configTypes_1 = require("../types/configTypes");
45
+ const commandUtils_1 = require("../utils/commandUtils");
69
46
  function handleCommit(yamlPathArg, files) {
70
- var _a;
71
47
  const appYamlPath = (0, cliUtils_1.resolveYamlPath)(yamlPathArg);
72
48
  (0, generationRegistry_1.initGenerationRegistry)(process.cwd());
73
- const raw = fs.readFileSync(appYamlPath, 'utf8');
74
- const appConfig = (0, yaml_1.parse)(raw);
75
- const modulesList = ((_a = appConfig === null || appConfig === void 0 ? void 0 : appConfig.modules) !== null && _a !== void 0 ? _a : []).map(m => (typeof m === 'string' ? m : m.module));
49
+ const appConfig = (0, commandUtils_1.loadAppConfig)(appYamlPath);
50
+ const modulesList = (0, commandUtils_1.getModuleList)(appConfig);
76
51
  const selection = (() => {
77
52
  if (!files || files.length === 0)
78
53
  return null;
@@ -84,12 +59,7 @@ function handleCommit(yamlPathArg, files) {
84
59
  };
85
60
  return new Set(files.map(norm));
86
61
  })();
87
- const domainGen = new domainModelGenerator_1.DomainModelGenerator();
88
- const valGen = new validationGenerator_1.ValidationGenerator();
89
- const svcGen = new serviceGenerator_1.ServiceGenerator();
90
- const ctrlGen = new controllerGenerator_1.ControllerGenerator();
91
- const storeGen = new storeGenerator_1.StoreGenerator();
92
- const tplGen = new templateGenerator_1.TemplateGenerator();
62
+ const { domainGen, dtoGen, useCaseGen, serviceGen: svcGen, controllerGen: ctrlGen, storeGen, templateGen: tplGen } = (0, commandUtils_1.createGenerators)();
93
63
  const diffs = [];
94
64
  modulesList.forEach(moduleYamlRel => {
95
65
  const moduleYamlPath = path.isAbsolute(moduleYamlRel)
@@ -100,14 +70,23 @@ function handleCommit(yamlPathArg, files) {
100
70
  console.warn(colors_1.colors.yellow(`Module YAML not found: ${moduleYamlPath}`));
101
71
  return;
102
72
  }
73
+ const moduleYamlContent = fs.readFileSync(moduleYamlPath, 'utf8');
74
+ const moduleConfig = (0, yaml_1.parse)(moduleYamlContent);
75
+ if (!(0, configTypes_1.isValidModuleConfig)(moduleConfig)) {
76
+ // eslint-disable-next-line no-console
77
+ console.warn(colors_1.colors.yellow(`Skipping ${moduleYamlPath}: not in expected format (missing domain/useCases)`));
78
+ return;
79
+ }
103
80
  const moduleDir = path.dirname(moduleYamlPath);
104
- // Infer outputs
105
- const domainOut = path.join(moduleDir, 'domain', 'entities');
81
+ const domainEntitiesOut = path.join(moduleDir, 'domain', 'entities');
82
+ const domainValueObjectsOut = path.join(moduleDir, 'domain', 'valueObjects');
106
83
  const appOut = path.join(moduleDir, 'application');
107
84
  const infraOut = path.join(moduleDir, 'infrastructure');
85
+ const viewsOut = path.join(moduleDir, 'views');
108
86
  // Generate in-memory
109
87
  const nextDomain = domainGen.generateFromYamlFile(moduleYamlPath);
110
- const nextValidations = valGen.generateFromYamlFile(moduleYamlPath);
88
+ const nextDtos = dtoGen.generateFromYamlFile(moduleYamlPath);
89
+ const nextUseCases = useCaseGen.generateFromYamlFile(moduleYamlPath);
111
90
  const nextServices = svcGen.generateFromYamlFile(moduleYamlPath);
112
91
  const nextControllers = ctrlGen.generateFromYamlFile(moduleYamlPath);
113
92
  const nextStores = storeGen.generateFromYamlFile(moduleYamlPath);
@@ -141,12 +120,16 @@ function handleCommit(yamlPathArg, files) {
141
120
  hunks
142
121
  });
143
122
  };
144
- Object.entries(nextDomain).forEach(([entity, code]) => consider(path.join(domainOut, `${entity}.ts`), code));
145
- Object.entries(nextValidations).forEach(([entity, code]) => consider(path.join(appOut, 'validation', `${entity}Validation.ts`), code));
123
+ Object.entries(nextDomain).forEach(([name, { code, type }]) => {
124
+ const outDir = type === 'valueObject' ? domainValueObjectsOut : domainEntitiesOut;
125
+ consider(path.join(outDir, `${name}.ts`), code);
126
+ });
127
+ Object.entries(nextDtos).forEach(([name, code]) => consider(path.join(appOut, 'dto', `${name}.ts`), code));
128
+ Object.entries(nextUseCases).forEach(([name, code]) => consider(path.join(appOut, 'useCases', `${name}UseCase.ts`), code));
146
129
  Object.entries(nextServices).forEach(([entity, code]) => consider(path.join(appOut, 'services', `${entity}Service.ts`), code));
147
- Object.entries(nextControllers).forEach(([entity, code]) => consider(path.join(infraOut, 'controllers', `${entity}Controller.ts`), code));
130
+ Object.entries(nextControllers).forEach(([name, code]) => consider(path.join(infraOut, 'controllers', `${name}Controller.ts`), code));
148
131
  Object.entries(nextStores).forEach(([entity, code]) => consider(path.join(infraOut, 'stores', `${entity}Store.ts`), code));
149
- Object.entries(nextTemplates).forEach(([, { file, contents }]) => consider(file, contents));
132
+ Object.entries(nextTemplates).forEach(([name, code]) => consider(path.join(viewsOut, `${name}.html`), code));
150
133
  });
151
134
  const commitsDir = (0, generationRegistry_1.ensureCommitsDir)();
152
135
  const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
@@ -59,6 +59,7 @@ function handleCreateApp(rawName) {
59
59
  (0, cliUtils_1.writeFileIfMissing)(path.join(targetRoot, appTemplates_1.DEFAULT_FILES.APP_YAML), appTemplates_1.appYamlTemplate);
60
60
  (0, cliUtils_1.writeFileIfMissing)(path.join(targetRoot, appTemplates_1.DEFAULT_FILES.CURSOR_RULES), appTemplates_1.cursorRulesTemplate);
61
61
  (0, cliUtils_1.writeFileIfMissing)(path.join(srcDir, appTemplates_1.DEFAULT_FILES.APP_TS), appTemplates_1.appTsTemplate);
62
+ (0, cliUtils_1.writeFileIfMissing)(path.join(srcDir, appTemplates_1.DEFAULT_FILES.SYSTEM_TS), appTemplates_1.systemTsTemplate);
62
63
  (0, cliUtils_1.writeFileIfMissing)(path.join(templatesDir, appTemplates_1.DEFAULT_FILES.MAIN_VIEW), appTemplates_1.mainViewTemplate);
63
64
  (0, cliUtils_1.writeFileIfMissing)(path.join(templatesDir, appTemplates_1.DEFAULT_FILES.ERROR_TEMPLATE), appTemplates_1.errorTemplate);
64
65
  (0, cliUtils_1.writeFileIfMissing)(path.join(webDir, appTemplates_1.DEFAULT_FILES.FRONTEND_SCRIPT), appTemplates_1.frontendScriptTemplate);
@@ -42,57 +42,162 @@ function moduleYamlTemplate(moduleName) {
42
42
  const entityName = moduleName.charAt(0).toUpperCase() + moduleName.slice(1);
43
43
  const lower = moduleName.charAt(0).toLowerCase() + moduleName.slice(1);
44
44
  const config = {
45
- models: [
46
- {
47
- name: entityName,
48
- fields: []
45
+ domain: {
46
+ aggregates: {
47
+ [entityName]: {
48
+ root: true,
49
+ fields: {
50
+ // Add your fields here, e.g.:
51
+ // name: { type: 'string', required: true }
52
+ }
53
+ }
49
54
  }
50
- ],
51
- api: {
52
- prefix: `/api/${lower}`,
53
- model: entityName,
54
- endpoints: [
55
- { method: 'GET', path: '/', action: 'list' },
56
- { method: 'GET', path: '/:id', action: 'get' },
57
- { method: 'POST', path: '/', action: 'create' },
58
- { method: 'PUT', path: '/:id', action: 'update' },
59
- { method: 'DELETE', path: '/:id', action: 'delete' }
60
- ]
61
55
  },
62
- routes: {
63
- prefix: `/${lower}`,
64
- model: entityName,
65
- strategy: ['back', 'toast'],
66
- endpoints: [
67
- //bug: the order of the endpoints is important (to fix it in the router)
68
- { path: '/create', action: 'empty', view: `${lower}Create` },
69
- { path: '/', action: 'list', view: `${lower}List` },
70
- { path: '/:id', action: 'get', view: `${lower}Detail` },
71
- { path: '/:id/edit', action: 'get', view: `${lower}Update` },
72
- ]
56
+ useCases: {
57
+ [entityName]: {
58
+ list: {
59
+ withChild: false,
60
+ input: {
61
+ pagination: {
62
+ type: 'offset',
63
+ defaults: {
64
+ limit: 20,
65
+ maxLimit: 100
66
+ }
67
+ }
68
+ },
69
+ output: {
70
+ from: entityName,
71
+ pagination: true
72
+ },
73
+ handlers: ['default:list']
74
+ },
75
+ get: {
76
+ withChild: false,
77
+ input: {
78
+ identifier: 'id'
79
+ },
80
+ output: {
81
+ from: entityName
82
+ },
83
+ handlers: ['default:get']
84
+ },
85
+ create: {
86
+ withChild: false,
87
+ input: {
88
+ from: entityName
89
+ },
90
+ output: {
91
+ from: entityName
92
+ },
93
+ handlers: ['default:create']
94
+ },
95
+ update: {
96
+ withChild: false,
97
+ input: {
98
+ identifier: 'id',
99
+ from: entityName,
100
+ partial: true
101
+ },
102
+ output: {
103
+ from: entityName
104
+ },
105
+ handlers: ['default:update']
106
+ },
107
+ delete: {
108
+ withChild: false,
109
+ input: {
110
+ identifier: 'id'
111
+ },
112
+ output: 'void',
113
+ handlers: ['default:delete']
114
+ }
115
+ }
73
116
  },
74
- actions: {
75
- list: { handlers: [`${entityName}:default:list`] },
76
- get: { handlers: [`${entityName}:default:get`] },
77
- create: { handlers: [`${entityName}:default:create`] },
78
- update: { handlers: [`${entityName}:default:update`] },
79
- delete: { handlers: [`${entityName}:default:delete`] }
117
+ api: {
118
+ [entityName]: {
119
+ prefix: `/api/${lower}`,
120
+ endpoints: [
121
+ // Public read access
122
+ { method: 'GET', path: '/', useCase: `${entityName}:list`, auth: 'all' },
123
+ { method: 'GET', path: '/:id', useCase: `${entityName}:get`, auth: 'all' },
124
+ // Authenticated users can create
125
+ { method: 'POST', path: '/', useCase: `${entityName}:create`, auth: 'authenticated' },
126
+ // Owner or admin can update/delete
127
+ { method: 'PUT', path: '/:id', useCase: `${entityName}:update`, auth: ['owner', 'admin'] },
128
+ { method: 'DELETE', path: '/:id', useCase: `${entityName}:delete`, auth: ['owner', 'admin'] }
129
+ ]
130
+ }
80
131
  },
81
- permissions: []
132
+ web: {
133
+ [entityName]: {
134
+ prefix: `/${lower}`,
135
+ layout: 'main_view',
136
+ pages: [
137
+ // Public list and detail views
138
+ { path: '/', useCase: `${entityName}:list`, view: `${lower}List`, auth: 'all' },
139
+ { path: '/:id', useCase: `${entityName}:get`, view: `${lower}Detail`, auth: 'all' },
140
+ // Authenticated users can access create form
141
+ {
142
+ path: '/create',
143
+ method: 'GET',
144
+ view: `${lower}Create`,
145
+ auth: 'authenticated'
146
+ },
147
+ {
148
+ path: '/create',
149
+ method: 'POST',
150
+ useCase: `${entityName}:create`,
151
+ auth: 'authenticated',
152
+ onSuccess: {
153
+ redirect: `/${lower}/:id`,
154
+ toast: `${entityName} created successfully`
155
+ },
156
+ onError: {
157
+ stay: true,
158
+ toast: 'error'
159
+ }
160
+ },
161
+ // Owner or admin can edit
162
+ {
163
+ path: '/:id/edit',
164
+ method: 'GET',
165
+ useCase: `${entityName}:get`,
166
+ view: `${lower}Edit`,
167
+ auth: ['owner', 'admin']
168
+ },
169
+ {
170
+ path: '/:id/edit',
171
+ method: 'POST',
172
+ useCase: `${entityName}:update`,
173
+ auth: ['owner', 'admin'],
174
+ onSuccess: {
175
+ back: true,
176
+ toast: `${entityName} updated successfully`
177
+ }
178
+ }
179
+ ]
180
+ }
181
+ }
82
182
  };
83
183
  return (0, yaml_1.stringify)(config);
84
184
  }
85
185
  function handleCreateModule(name) {
186
+ var _a;
86
187
  if (!name) {
87
188
  throw new Error('Module name is required: currentjs create module <name>');
88
189
  }
89
190
  const modulesRoot = path.join(process.cwd(), 'src', 'modules');
90
191
  const moduleRoot = path.join(modulesRoot, name);
91
192
  (0, cliUtils_1.ensureDir)((0, cliUtils_1.toAbsolute)(moduleRoot));
92
- // Create standard subfolders
93
- (0, cliUtils_1.ensureDir)(path.join(moduleRoot, 'domain'));
94
- (0, cliUtils_1.ensureDir)(path.join(moduleRoot, 'application'));
95
- (0, cliUtils_1.ensureDir)(path.join(moduleRoot, 'infrastructure'));
193
+ // Create standard subfolders for Clean Architecture
194
+ (0, cliUtils_1.ensureDir)(path.join(moduleRoot, 'domain', 'entities'));
195
+ (0, cliUtils_1.ensureDir)(path.join(moduleRoot, 'domain', 'valueObjects'));
196
+ (0, cliUtils_1.ensureDir)(path.join(moduleRoot, 'application', 'useCases'));
197
+ (0, cliUtils_1.ensureDir)(path.join(moduleRoot, 'application', 'services'));
198
+ (0, cliUtils_1.ensureDir)(path.join(moduleRoot, 'application', 'dto'));
199
+ (0, cliUtils_1.ensureDir)(path.join(moduleRoot, 'infrastructure', 'controllers'));
200
+ (0, cliUtils_1.ensureDir)(path.join(moduleRoot, 'infrastructure', 'stores'));
96
201
  (0, cliUtils_1.ensureDir)(path.join(moduleRoot, 'views'));
97
202
  // Create module yaml
98
203
  const moduleYamlFile = path.join(moduleRoot, `${name.toLowerCase()}.yaml`);
@@ -101,23 +206,24 @@ function handleCreateModule(name) {
101
206
  }
102
207
  // Add to root app.yaml
103
208
  const appYamlPath = path.join(process.cwd(), 'app.yaml');
104
- let appConfig = { modules: [] };
209
+ let appConfig = { modules: {} };
105
210
  if (fs.existsSync(appYamlPath)) {
106
211
  try {
107
212
  const content = fs.readFileSync(appYamlPath, 'utf8');
108
- appConfig = (0, yaml_1.parse)(content) || { modules: [] };
213
+ appConfig = (0, yaml_1.parse)(content) || { modules: {} };
109
214
  }
110
215
  catch {
111
- appConfig = { modules: [] };
216
+ appConfig = { modules: {} };
112
217
  }
113
218
  }
114
- if (!Array.isArray(appConfig.modules))
115
- appConfig.modules = [];
116
- // Use posix-style path in YAML
219
+ if (!appConfig.modules || typeof appConfig.modules !== 'object' || Array.isArray(appConfig.modules)) {
220
+ appConfig.modules = {};
221
+ }
222
+ const moduleKey = name.charAt(0).toUpperCase() + name.slice(1).toLowerCase();
117
223
  const moduleYamlRel = path.posix.join('src', 'modules', name, `${name.toLowerCase()}.yaml`);
118
- const alreadyPresent = appConfig.modules.some((m) => (typeof m === 'string' ? m === moduleYamlRel : (m === null || m === void 0 ? void 0 : m.module) === moduleYamlRel));
224
+ const alreadyPresent = ((_a = appConfig.modules[moduleKey]) === null || _a === void 0 ? void 0 : _a.path) === moduleYamlRel;
119
225
  if (!alreadyPresent) {
120
- appConfig.modules.push({ module: moduleYamlRel });
226
+ appConfig.modules[moduleKey] = { path: moduleYamlRel };
121
227
  }
122
228
  fs.writeFileSync(appYamlPath, (0, yaml_1.stringify)(appConfig), 'utf8');
123
229
  }
@@ -38,51 +38,23 @@ const fs = __importStar(require("fs"));
38
38
  const path = __importStar(require("path"));
39
39
  const cliUtils_1 = require("../utils/cliUtils");
40
40
  const yaml_1 = require("yaml");
41
- const domainModelGenerator_1 = require("../generators/domainModelGenerator");
42
- const validationGenerator_1 = require("../generators/validationGenerator");
43
- const serviceGenerator_1 = require("../generators/serviceGenerator");
44
- const controllerGenerator_1 = require("../generators/controllerGenerator");
45
- const storeGenerator_1 = require("../generators/storeGenerator");
46
- const templateGenerator_1 = require("../generators/templateGenerator");
47
41
  const generationRegistry_1 = require("../utils/generationRegistry");
48
42
  const commitUtils_1 = require("../utils/commitUtils");
49
43
  const colors_1 = require("../utils/colors");
44
+ const configTypes_1 = require("../types/configTypes");
45
+ const commandUtils_1 = require("../utils/commandUtils");
50
46
  async function handleDiff(yamlPathArg, moduleName) {
51
- var _a;
52
47
  const appYamlPath = (0, cliUtils_1.resolveYamlPath)(yamlPathArg);
53
48
  (0, generationRegistry_1.initGenerationRegistry)(process.cwd());
54
- const raw = fs.readFileSync(appYamlPath, 'utf8');
55
- const appConfig = (0, yaml_1.parse)(raw);
56
- const modulesList = ((_a = appConfig === null || appConfig === void 0 ? void 0 : appConfig.modules) !== null && _a !== void 0 ? _a : []).map(m => (typeof m === 'string' ? m : m.module));
57
- const shouldIncludeModule = (moduleYamlRel) => {
58
- if (!moduleName || moduleName === '*')
59
- return true;
60
- const moduleNameLc = moduleName.toLowerCase();
61
- const relNormalized = moduleYamlRel.replace(/\\/g, '/').toLowerCase();
62
- if (relNormalized.endsWith(`/${moduleNameLc}.yaml`))
63
- return true;
64
- const moduleYamlPath = path.isAbsolute(moduleYamlRel)
65
- ? moduleYamlRel
66
- : path.resolve(process.cwd(), moduleYamlRel);
67
- const dirName = path.basename(path.dirname(moduleYamlPath)).toLowerCase();
68
- if (dirName === moduleNameLc)
69
- return true;
70
- if (relNormalized.includes(`/${moduleNameLc}/`) || relNormalized.endsWith(`/${moduleNameLc}`))
71
- return true;
72
- return false;
73
- };
74
- const filteredModules = modulesList.filter(shouldIncludeModule);
49
+ const appConfig = (0, commandUtils_1.loadAppConfig)(appYamlPath);
50
+ const modulesList = (0, commandUtils_1.getModuleList)(appConfig);
51
+ const filteredModules = modulesList.filter(rel => (0, commandUtils_1.shouldIncludeModule)(rel, moduleName));
75
52
  if (filteredModules.length === 0) {
76
53
  // eslint-disable-next-line no-console
77
54
  console.warn(colors_1.colors.yellow(`No modules matched: ${moduleName}`));
78
55
  return;
79
56
  }
80
- const domainGen = new domainModelGenerator_1.DomainModelGenerator();
81
- const valGen = new validationGenerator_1.ValidationGenerator();
82
- const svcGen = new serviceGenerator_1.ServiceGenerator();
83
- const ctrlGen = new controllerGenerator_1.ControllerGenerator();
84
- const storeGen = new storeGenerator_1.StoreGenerator();
85
- const tplGen = new templateGenerator_1.TemplateGenerator();
57
+ const { domainGen, dtoGen, useCaseGen, serviceGen: svcGen, controllerGen: ctrlGen, storeGen, templateGen: tplGen } = (0, commandUtils_1.createGenerators)();
86
58
  const results = [];
87
59
  for (const moduleYamlRel of filteredModules) {
88
60
  const moduleYamlPath = path.isAbsolute(moduleYamlRel)
@@ -90,12 +62,22 @@ async function handleDiff(yamlPathArg, moduleName) {
90
62
  : path.resolve(process.cwd(), moduleYamlRel);
91
63
  if (!fs.existsSync(moduleYamlPath))
92
64
  continue;
65
+ const moduleYamlContent = fs.readFileSync(moduleYamlPath, 'utf8');
66
+ const moduleConfig = (0, yaml_1.parse)(moduleYamlContent);
67
+ if (!(0, configTypes_1.isValidModuleConfig)(moduleConfig)) {
68
+ // eslint-disable-next-line no-console
69
+ console.warn(colors_1.colors.yellow(`Skipping ${moduleYamlPath}: not in expected format (missing domain/useCases)`));
70
+ continue;
71
+ }
93
72
  const moduleDir = path.dirname(moduleYamlPath);
94
- const domainOut = path.join(moduleDir, 'domain', 'entities');
73
+ const domainEntitiesOut = path.join(moduleDir, 'domain', 'entities');
74
+ const domainValueObjectsOut = path.join(moduleDir, 'domain', 'valueObjects');
95
75
  const appOut = path.join(moduleDir, 'application');
96
76
  const infraOut = path.join(moduleDir, 'infrastructure');
77
+ const viewsOut = path.join(moduleDir, 'views');
97
78
  const nextDomain = domainGen.generateFromYamlFile(moduleYamlPath);
98
- const nextValidations = valGen.generateFromYamlFile(moduleYamlPath);
79
+ const nextDtos = dtoGen.generateFromYamlFile(moduleYamlPath);
80
+ const nextUseCases = useCaseGen.generateFromYamlFile(moduleYamlPath);
99
81
  const nextServices = svcGen.generateFromYamlFile(moduleYamlPath);
100
82
  const nextControllers = ctrlGen.generateFromYamlFile(moduleYamlPath);
101
83
  const nextStores = storeGen.generateFromYamlFile(moduleYamlPath);
@@ -134,12 +116,17 @@ async function handleDiff(yamlPathArg, moduleName) {
134
116
  }
135
117
  results.push({ file: rel, status: 'modified', hunks, note });
136
118
  };
137
- Object.entries(nextDomain).forEach(([e, code]) => consider(path.join(domainOut, `${e}.ts`), code));
138
- Object.entries(nextValidations).forEach(([e, code]) => consider(path.join(appOut, 'validation', `${e}Validation.ts`), code));
119
+ // Domain: entities and value objects
120
+ Object.entries(nextDomain).forEach(([name, { code, type }]) => {
121
+ const outDir = type === 'valueObject' ? domainValueObjectsOut : domainEntitiesOut;
122
+ consider(path.join(outDir, `${name}.ts`), code);
123
+ });
124
+ Object.entries(nextDtos).forEach(([name, code]) => consider(path.join(appOut, 'dto', `${name}.ts`), code));
125
+ Object.entries(nextUseCases).forEach(([name, code]) => consider(path.join(appOut, 'useCases', `${name}UseCase.ts`), code));
139
126
  Object.entries(nextServices).forEach(([e, code]) => consider(path.join(appOut, 'services', `${e}Service.ts`), code));
140
- Object.entries(nextControllers).forEach(([e, code]) => consider(path.join(infraOut, 'controllers', `${e}Controller.ts`), code));
127
+ Object.entries(nextControllers).forEach(([name, code]) => consider(path.join(infraOut, 'controllers', `${name}Controller.ts`), code));
141
128
  Object.entries(nextStores).forEach(([e, code]) => consider(path.join(infraOut, 'stores', `${e}Store.ts`), code));
142
- Object.entries(nextTemplates).forEach(([, { file, contents }]) => consider(file, contents));
129
+ Object.entries(nextTemplates).forEach(([name, code]) => consider(path.join(viewsOut, `${name}.html`), code));
143
130
  }
144
131
  if (results.length === 0) {
145
132
  // eslint-disable-next-line no-console