@currentjs/gen 0.1.1

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 (55) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/LICENSE +56 -0
  3. package/README.md +686 -0
  4. package/dist/cli.d.ts +2 -0
  5. package/dist/cli.js +143 -0
  6. package/dist/commands/commit.d.ts +1 -0
  7. package/dist/commands/commit.js +153 -0
  8. package/dist/commands/createApp.d.ts +1 -0
  9. package/dist/commands/createApp.js +64 -0
  10. package/dist/commands/createModule.d.ts +1 -0
  11. package/dist/commands/createModule.js +121 -0
  12. package/dist/commands/diff.d.ts +1 -0
  13. package/dist/commands/diff.js +164 -0
  14. package/dist/commands/generateAll.d.ts +4 -0
  15. package/dist/commands/generateAll.js +305 -0
  16. package/dist/commands/infer.d.ts +1 -0
  17. package/dist/commands/infer.js +179 -0
  18. package/dist/generators/controllerGenerator.d.ts +20 -0
  19. package/dist/generators/controllerGenerator.js +280 -0
  20. package/dist/generators/domainModelGenerator.d.ts +33 -0
  21. package/dist/generators/domainModelGenerator.js +175 -0
  22. package/dist/generators/serviceGenerator.d.ts +39 -0
  23. package/dist/generators/serviceGenerator.js +379 -0
  24. package/dist/generators/storeGenerator.d.ts +31 -0
  25. package/dist/generators/storeGenerator.js +191 -0
  26. package/dist/generators/templateGenerator.d.ts +11 -0
  27. package/dist/generators/templateGenerator.js +143 -0
  28. package/dist/generators/templates/appTemplates.d.ts +27 -0
  29. package/dist/generators/templates/appTemplates.js +1621 -0
  30. package/dist/generators/templates/controllerTemplates.d.ts +43 -0
  31. package/dist/generators/templates/controllerTemplates.js +82 -0
  32. package/dist/generators/templates/index.d.ts +5 -0
  33. package/dist/generators/templates/index.js +21 -0
  34. package/dist/generators/templates/serviceTemplates.d.ts +15 -0
  35. package/dist/generators/templates/serviceTemplates.js +54 -0
  36. package/dist/generators/templates/storeTemplates.d.ts +9 -0
  37. package/dist/generators/templates/storeTemplates.js +260 -0
  38. package/dist/generators/templates/validationTemplates.d.ts +25 -0
  39. package/dist/generators/templates/validationTemplates.js +66 -0
  40. package/dist/generators/templates/viewTemplates.d.ts +16 -0
  41. package/dist/generators/templates/viewTemplates.js +359 -0
  42. package/dist/generators/validationGenerator.d.ts +24 -0
  43. package/dist/generators/validationGenerator.js +199 -0
  44. package/dist/utils/cliUtils.d.ts +6 -0
  45. package/dist/utils/cliUtils.js +71 -0
  46. package/dist/utils/colors.d.ts +26 -0
  47. package/dist/utils/colors.js +80 -0
  48. package/dist/utils/commitUtils.d.ts +46 -0
  49. package/dist/utils/commitUtils.js +377 -0
  50. package/dist/utils/constants.d.ts +52 -0
  51. package/dist/utils/constants.js +64 -0
  52. package/dist/utils/generationRegistry.d.ts +25 -0
  53. package/dist/utils/generationRegistry.js +192 -0
  54. package/howto.md +556 -0
  55. package/package.json +44 -0
package/dist/cli.js ADDED
@@ -0,0 +1,143 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const createApp_1 = require("./commands/createApp");
5
+ const createModule_1 = require("./commands/createModule");
6
+ const generateAll_1 = require("./commands/generateAll");
7
+ const commit_1 = require("./commands/commit");
8
+ const diff_1 = require("./commands/diff");
9
+ const colors_1 = require("./utils/colors");
10
+ const infer_1 = require("./commands/infer");
11
+ function printHelp() {
12
+ const title = colors_1.colors.bold(colors_1.colors.brightCyan('currentjs - Clean architecture CLI'));
13
+ const usage = colors_1.colors.bold('Usage:');
14
+ const options = colors_1.colors.bold('Options:');
15
+ const cmd = (s) => colors_1.colors.green(s);
16
+ const flag = (s) => colors_1.colors.yellow(s);
17
+ const help = `
18
+ ${title}
19
+
20
+ ${usage}
21
+ ${cmd('currentjs create app')} ${colors_1.colors.gray('[name]')}
22
+ ${cmd('currentjs create module')} ${colors_1.colors.gray('<name>')}
23
+ ${cmd('currentjs generate')} ${colors_1.colors.gray('<module|*>')} ${flag('--yaml')} ${colors_1.colors.gray('app.yaml')} ${colors_1.colors.gray('[')}${flag('--force')}${colors_1.colors.gray(']')} ${colors_1.colors.gray('[')}${flag('--skip')}${colors_1.colors.gray(']')}
24
+ ${cmd('currentjs commit')} ${colors_1.colors.gray('[<file> ...]')} ${flag('--yaml')} ${colors_1.colors.gray('app.yaml')}
25
+ ${cmd('currentjs diff')} ${colors_1.colors.gray('<module|*>')} ${flag('--yaml')} ${colors_1.colors.gray('app.yaml')}
26
+ ${cmd('currentjs infer')} ${flag('--file')} ${colors_1.colors.gray('src/modules/<Module>/domain/entities/<Entity>.ts')} ${colors_1.colors.gray('[')}${flag('--write')}${colors_1.colors.gray(']')}
27
+
28
+ ${options}
29
+ ${flag('--yaml')} <path> ${colors_1.colors.gray('Path to app.yaml (default: ./app.yaml)')}
30
+ ${flag('--force')} ${colors_1.colors.gray('Overwrite modified files without prompting')}
31
+ ${flag('--skip')} ${colors_1.colors.gray('Always skip overwriting modified files (no prompts)')}
32
+ ${flag('--out')} <dir> ${colors_1.colors.gray('[deprecated] Generators now write into each module\'s structure')}
33
+ ${flag('-h, --help')} ${colors_1.colors.gray('Show help')}
34
+ `;
35
+ // eslint-disable-next-line no-console
36
+ console.log(help);
37
+ }
38
+ function parseArgs(argv) {
39
+ const [, , ...rest] = argv;
40
+ const result = {};
41
+ if (rest.length === 0)
42
+ return { help: true };
43
+ result.command = rest.shift();
44
+ if (result.command === 'create') {
45
+ result.sub = rest.shift();
46
+ result.name = rest[0] && !rest[0].startsWith('-') ? rest.shift() : undefined;
47
+ }
48
+ else if (result.command === 'generate') {
49
+ // capture optional module name (or *) before flags
50
+ result.name = rest[0] && !rest[0].startsWith('-') ? rest.shift() : undefined;
51
+ }
52
+ else if (result.command === 'commit') {
53
+ // capture positional file paths until a flag begins
54
+ const files = [];
55
+ while (rest[0] && !rest[0].startsWith('-')) {
56
+ files.push(rest.shift());
57
+ }
58
+ // store as name for backward compatibility? better extend Args
59
+ result.files = files;
60
+ }
61
+ else if (result.command === 'diff') {
62
+ // capture optional module name (or *) before flags
63
+ result.name = rest[0] && !rest[0].startsWith('-') ? rest.shift() : undefined;
64
+ }
65
+ else if (result.command === 'infer') {
66
+ // no subcommands
67
+ }
68
+ for (let i = 0; i < rest.length; i += 1) {
69
+ const token = rest[i];
70
+ if (token === '--yaml') {
71
+ result.yaml = rest[i + 1];
72
+ i += 1;
73
+ }
74
+ else if (token === '--force') {
75
+ result.force = true;
76
+ }
77
+ else if (token === '--skip') {
78
+ result.skip = true;
79
+ }
80
+ else if (token === '--out') {
81
+ result.out = rest[i + 1];
82
+ i += 1;
83
+ }
84
+ else if (token === '-h' || token === '--help') {
85
+ result.help = true;
86
+ }
87
+ }
88
+ return result;
89
+ }
90
+ async function run() {
91
+ try {
92
+ const args = parseArgs(process.argv);
93
+ if (args.help || !args.command) {
94
+ printHelp();
95
+ return;
96
+ }
97
+ switch (args.command) {
98
+ case 'create': {
99
+ if (args.sub === 'app') {
100
+ (0, createApp_1.handleCreateApp)(args.name);
101
+ return;
102
+ }
103
+ if (args.sub === 'module') {
104
+ (0, createModule_1.handleCreateModule)(args.name);
105
+ return;
106
+ }
107
+ printHelp();
108
+ process.exitCode = 1;
109
+ return;
110
+ }
111
+ case 'generate': {
112
+ await (0, generateAll_1.handleGenerateAll)(args.yaml, args.out, args.name, { force: !!args.force, skip: !!args.skip });
113
+ return;
114
+ }
115
+ case 'commit': {
116
+ (0, commit_1.handleCommit)(args.yaml, args.files);
117
+ return;
118
+ }
119
+ case 'diff': {
120
+ await (0, diff_1.handleDiff)(args.yaml, args.name);
121
+ return;
122
+ }
123
+ case 'infer': {
124
+ const fileFlagIndex = process.argv.findIndex(a => a === '--file');
125
+ const fileArg = fileFlagIndex !== -1 ? process.argv[fileFlagIndex + 1] : undefined;
126
+ const write = process.argv.includes('--write');
127
+ (0, infer_1.handleInfer)(fileArg, write);
128
+ return;
129
+ }
130
+ default: {
131
+ printHelp();
132
+ process.exitCode = 1;
133
+ return;
134
+ }
135
+ }
136
+ }
137
+ catch (err) {
138
+ // eslint-disable-next-line no-console
139
+ console.error(colors_1.colors.red(err instanceof Error ? err.message : String(err)));
140
+ process.exitCode = 1;
141
+ }
142
+ }
143
+ run();
@@ -0,0 +1 @@
1
+ export declare function handleCommit(yamlPathArg?: string, files?: string[]): void;
@@ -0,0 +1,153 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.handleCommit = handleCommit;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ const cliUtils_1 = require("../utils/cliUtils");
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 generationRegistry_1 = require("../utils/generationRegistry");
47
+ const commitUtils_1 = require("../utils/commitUtils");
48
+ const colors_1 = require("../utils/colors");
49
+ // legacy inline diff removed in favor of hunks; kept for backward compatibility via utils/commitUtils if needed
50
+ function collectFiles(dir) {
51
+ if (!fs.existsSync(dir))
52
+ return [];
53
+ const result = [];
54
+ const stack = [dir];
55
+ while (stack.length) {
56
+ const current = stack.pop();
57
+ const entries = fs.readdirSync(current, { withFileTypes: true });
58
+ entries.forEach(entry => {
59
+ const abs = path.join(current, entry.name);
60
+ if (entry.isDirectory())
61
+ stack.push(abs);
62
+ else
63
+ result.push(abs);
64
+ });
65
+ }
66
+ return result;
67
+ }
68
+ function handleCommit(yamlPathArg, files) {
69
+ var _a;
70
+ const appYamlPath = (0, cliUtils_1.resolveYamlPath)(yamlPathArg);
71
+ (0, generationRegistry_1.initGenerationRegistry)(process.cwd());
72
+ const raw = fs.readFileSync(appYamlPath, 'utf8');
73
+ const appConfig = (0, yaml_1.parse)(raw);
74
+ 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));
75
+ const selection = (() => {
76
+ if (!files || files.length === 0)
77
+ return null;
78
+ const cwd = process.cwd();
79
+ const norm = (p) => {
80
+ const abs = path.isAbsolute(p) ? p : path.resolve(cwd, p);
81
+ const rel = path.relative(cwd, abs);
82
+ return rel.split(path.sep).join('/');
83
+ };
84
+ return new Set(files.map(norm));
85
+ })();
86
+ const domainGen = new domainModelGenerator_1.DomainModelGenerator();
87
+ const valGen = new validationGenerator_1.ValidationGenerator();
88
+ const svcGen = new serviceGenerator_1.ServiceGenerator();
89
+ const ctrlGen = new controllerGenerator_1.ControllerGenerator();
90
+ const storeGen = new storeGenerator_1.StoreGenerator();
91
+ const diffs = [];
92
+ modulesList.forEach(moduleYamlRel => {
93
+ const moduleYamlPath = path.isAbsolute(moduleYamlRel)
94
+ ? moduleYamlRel
95
+ : path.resolve(process.cwd(), moduleYamlRel);
96
+ if (!fs.existsSync(moduleYamlPath)) {
97
+ // eslint-disable-next-line no-console
98
+ console.warn(colors_1.colors.yellow(`Module YAML not found: ${moduleYamlPath}`));
99
+ return;
100
+ }
101
+ const moduleDir = path.dirname(moduleYamlPath);
102
+ // Infer outputs
103
+ const domainOut = path.join(moduleDir, 'domain', 'entities');
104
+ const appOut = path.join(moduleDir, 'application');
105
+ const infraOut = path.join(moduleDir, 'infrastructure');
106
+ // Generate in-memory
107
+ const nextDomain = domainGen.generateFromYamlFile(moduleYamlPath);
108
+ const nextValidations = valGen.generateFromYamlFile(moduleYamlPath);
109
+ const nextServices = svcGen.generateFromYamlFile(moduleYamlPath);
110
+ const nextControllers = ctrlGen.generateFromYamlFile(moduleYamlPath);
111
+ const nextStores = storeGen.generateFromYamlFile(moduleYamlPath);
112
+ // Helper to evaluate only user-changed files and compute diff vs freshly generated code
113
+ const consider = (target, generated) => {
114
+ if (!fs.existsSync(target))
115
+ return; // nothing to commit for missing files
116
+ const currentContent = fs.readFileSync(target, 'utf8');
117
+ const currentHash = (0, generationRegistry_1.computeContentHash)(currentContent);
118
+ const storedHash = (0, generationRegistry_1.getStoredHash)(target);
119
+ if (storedHash && storedHash === currentHash)
120
+ return; // not changed by user
121
+ const newHash = (0, generationRegistry_1.computeContentHash)(generated);
122
+ if (newHash === currentHash)
123
+ return; // no diff vs generation
124
+ const rel = path.relative(process.cwd(), target).split(path.sep).join('/');
125
+ if (selection && !selection.has(rel))
126
+ return; // not selected
127
+ const hunks = (0, commitUtils_1.computeHunks)(generated, currentContent); // base: generated, new: current
128
+ // Store hunk snapshot into registry for quick inspection
129
+ (0, generationRegistry_1.updateStoredHunks)(target, hunks, newHash, currentHash);
130
+ diffs.push({
131
+ file: rel,
132
+ status: 'modified',
133
+ oldHash: currentHash,
134
+ newHash,
135
+ format: 'hunks-v1',
136
+ baseHash: newHash,
137
+ resultHash: currentHash,
138
+ hunks
139
+ });
140
+ };
141
+ Object.entries(nextDomain).forEach(([entity, code]) => consider(path.join(domainOut, `${entity}.ts`), code));
142
+ Object.entries(nextValidations).forEach(([entity, code]) => consider(path.join(appOut, 'validation', `${entity}Validation.ts`), code));
143
+ Object.entries(nextServices).forEach(([entity, code]) => consider(path.join(appOut, 'services', `${entity}Service.ts`), code));
144
+ Object.entries(nextControllers).forEach(([entity, code]) => consider(path.join(infraOut, 'controllers', `${entity}Controller.ts`), code));
145
+ Object.entries(nextStores).forEach(([entity, code]) => consider(path.join(infraOut, 'stores', `${entity}Store.ts`), code));
146
+ });
147
+ const commitsDir = (0, generationRegistry_1.ensureCommitsDir)();
148
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
149
+ const commitFile = path.join(commitsDir, `commit-${timestamp}.json`);
150
+ fs.writeFileSync(commitFile, JSON.stringify({ createdAt: new Date().toISOString(), files: diffs }, null, 2));
151
+ // eslint-disable-next-line no-console
152
+ console.log(colors_1.colors.green(`Saved diff summary with ${diffs.length} modified file(s) to ${path.relative(process.cwd(), commitFile)}`));
153
+ }
@@ -0,0 +1 @@
1
+ export declare function handleCreateApp(rawName?: string): void;
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.handleCreateApp = handleCreateApp;
37
+ const path = __importStar(require("path"));
38
+ const cliUtils_1 = require("../utils/cliUtils");
39
+ const appTemplates_1 = require("../generators/templates/appTemplates");
40
+ function handleCreateApp(rawName) {
41
+ const targetRoot = rawName ? (0, cliUtils_1.toAbsolute)(rawName) : process.cwd();
42
+ (0, cliUtils_1.ensureDir)(targetRoot);
43
+ // Basic structure using constants
44
+ const srcDir = path.join(targetRoot, appTemplates_1.DEFAULT_DIRECTORIES.SRC);
45
+ const distDir = path.join(targetRoot, appTemplates_1.DEFAULT_DIRECTORIES.DIST);
46
+ const webDir = path.join(targetRoot, appTemplates_1.DEFAULT_DIRECTORIES.WEB);
47
+ const templatesDir = path.join(targetRoot, appTemplates_1.DEFAULT_DIRECTORIES.TEMPLATES);
48
+ const servicesDir = path.join(targetRoot, appTemplates_1.DEFAULT_DIRECTORIES.SERVICES);
49
+ (0, cliUtils_1.ensureDir)(srcDir);
50
+ (0, cliUtils_1.ensureDir)(distDir);
51
+ (0, cliUtils_1.ensureDir)(webDir);
52
+ (0, cliUtils_1.ensureDir)(templatesDir);
53
+ (0, cliUtils_1.ensureDir)(servicesDir);
54
+ // Files using imported templates
55
+ (0, cliUtils_1.writeFileIfMissing)(path.join(targetRoot, appTemplates_1.DEFAULT_FILES.PACKAGE_JSON), (0, appTemplates_1.packageJsonTemplate)(path.basename(targetRoot)));
56
+ (0, cliUtils_1.writeFileIfMissing)(path.join(targetRoot, appTemplates_1.DEFAULT_FILES.TSCONFIG), appTemplates_1.tsconfigTemplate);
57
+ (0, cliUtils_1.writeFileIfMissing)(path.join(targetRoot, appTemplates_1.DEFAULT_FILES.APP_YAML), appTemplates_1.appYamlTemplate);
58
+ (0, cliUtils_1.writeFileIfMissing)(path.join(targetRoot, appTemplates_1.DEFAULT_FILES.CURSOR_RULES), appTemplates_1.cursorRulesTemplate);
59
+ (0, cliUtils_1.writeFileIfMissing)(path.join(srcDir, appTemplates_1.DEFAULT_FILES.APP_TS), appTemplates_1.appTsTemplate);
60
+ (0, cliUtils_1.writeFileIfMissing)(path.join(templatesDir, appTemplates_1.DEFAULT_FILES.MAIN_VIEW), appTemplates_1.mainViewTemplate);
61
+ (0, cliUtils_1.writeFileIfMissing)(path.join(templatesDir, appTemplates_1.DEFAULT_FILES.ERROR_TEMPLATE), appTemplates_1.errorTemplate);
62
+ (0, cliUtils_1.writeFileIfMissing)(path.join(webDir, appTemplates_1.DEFAULT_FILES.FRONTEND_SCRIPT), appTemplates_1.frontendScriptTemplate);
63
+ (0, cliUtils_1.writeFileIfMissing)(path.join(webDir, appTemplates_1.DEFAULT_FILES.TRANSLATIONS), appTemplates_1.translationsTemplate);
64
+ }
@@ -0,0 +1 @@
1
+ export declare function handleCreateModule(name?: string): void;
@@ -0,0 +1,121 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.handleCreateModule = handleCreateModule;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ const cliUtils_1 = require("../utils/cliUtils");
40
+ const yaml_1 = require("yaml");
41
+ function moduleYamlTemplate(moduleName) {
42
+ const entityName = moduleName.charAt(0).toUpperCase() + moduleName.slice(1);
43
+ const lower = moduleName.charAt(0).toLowerCase() + moduleName.slice(1);
44
+ const config = {
45
+ models: [
46
+ {
47
+ name: entityName,
48
+ fields: []
49
+ }
50
+ ],
51
+ api: {
52
+ prefix: `/api/${lower}`,
53
+ endpoints: [
54
+ { method: 'GET', path: '/', action: 'list' },
55
+ { method: 'GET', path: '/:id', action: 'get' },
56
+ { method: 'POST', path: '/', action: 'create' },
57
+ { method: 'PUT', path: '/:id', action: 'update' },
58
+ { method: 'DELETE', path: '/:id', action: 'delete' }
59
+ ]
60
+ },
61
+ routes: {
62
+ prefix: `/${lower}`,
63
+ strategy: ['back', 'toast'],
64
+ endpoints: [
65
+ //bug: the order of the endpoints is important (to fix it in the router)
66
+ { path: '/create', action: 'empty', view: `${lower}Create` },
67
+ { path: '/', action: 'list', view: `${lower}List` },
68
+ { path: '/:id', action: 'get', view: `${lower}Detail` },
69
+ { path: '/:id/edit', action: 'get', view: `${lower}Update` },
70
+ ]
71
+ },
72
+ actions: {
73
+ list: { handlers: ['default:list'] },
74
+ get: { handlers: ['default:getById'] },
75
+ create: { handlers: ['default:create'] },
76
+ update: { handlers: ['default:update'] },
77
+ delete: { handlers: ['default:delete'] }
78
+ },
79
+ permissions: []
80
+ };
81
+ return (0, yaml_1.stringify)(config);
82
+ }
83
+ function handleCreateModule(name) {
84
+ if (!name) {
85
+ throw new Error('Module name is required: currentjs create module <name>');
86
+ }
87
+ const modulesRoot = path.join(process.cwd(), 'src', 'modules');
88
+ const moduleRoot = path.join(modulesRoot, name);
89
+ (0, cliUtils_1.ensureDir)((0, cliUtils_1.toAbsolute)(moduleRoot));
90
+ // Create standard subfolders
91
+ (0, cliUtils_1.ensureDir)(path.join(moduleRoot, 'domain'));
92
+ (0, cliUtils_1.ensureDir)(path.join(moduleRoot, 'application'));
93
+ (0, cliUtils_1.ensureDir)(path.join(moduleRoot, 'infrastructure'));
94
+ (0, cliUtils_1.ensureDir)(path.join(moduleRoot, 'views'));
95
+ // Create module yaml
96
+ const moduleYamlFile = path.join(moduleRoot, `${name.toLowerCase()}.yaml`);
97
+ if (!fs.existsSync(moduleYamlFile)) {
98
+ fs.writeFileSync(moduleYamlFile, moduleYamlTemplate(name), 'utf8');
99
+ }
100
+ // Add to root app.yaml
101
+ const appYamlPath = path.join(process.cwd(), 'app.yaml');
102
+ let appConfig = { modules: [] };
103
+ if (fs.existsSync(appYamlPath)) {
104
+ try {
105
+ const content = fs.readFileSync(appYamlPath, 'utf8');
106
+ appConfig = (0, yaml_1.parse)(content) || { modules: [] };
107
+ }
108
+ catch {
109
+ appConfig = { modules: [] };
110
+ }
111
+ }
112
+ if (!Array.isArray(appConfig.modules))
113
+ appConfig.modules = [];
114
+ // Use posix-style path in YAML
115
+ const moduleYamlRel = path.posix.join('src', 'modules', name, `${name.toLowerCase()}.yaml`);
116
+ const alreadyPresent = appConfig.modules.some((m) => (typeof m === 'string' ? m === moduleYamlRel : (m === null || m === void 0 ? void 0 : m.module) === moduleYamlRel));
117
+ if (!alreadyPresent) {
118
+ appConfig.modules.push({ module: moduleYamlRel });
119
+ }
120
+ fs.writeFileSync(appYamlPath, (0, yaml_1.stringify)(appConfig), 'utf8');
121
+ }
@@ -0,0 +1 @@
1
+ export declare function handleDiff(yamlPathArg?: string, moduleName?: string): Promise<void>;
@@ -0,0 +1,164 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.handleDiff = handleDiff;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ const cliUtils_1 = require("../utils/cliUtils");
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 generationRegistry_1 = require("../utils/generationRegistry");
47
+ const commitUtils_1 = require("../utils/commitUtils");
48
+ const colors_1 = require("../utils/colors");
49
+ async function handleDiff(yamlPathArg, moduleName) {
50
+ var _a;
51
+ const appYamlPath = (0, cliUtils_1.resolveYamlPath)(yamlPathArg);
52
+ (0, generationRegistry_1.initGenerationRegistry)(process.cwd());
53
+ const raw = fs.readFileSync(appYamlPath, 'utf8');
54
+ const appConfig = (0, yaml_1.parse)(raw);
55
+ 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));
56
+ const shouldIncludeModule = (moduleYamlRel) => {
57
+ if (!moduleName || moduleName === '*')
58
+ return true;
59
+ const moduleNameLc = moduleName.toLowerCase();
60
+ const relNormalized = moduleYamlRel.replace(/\\/g, '/').toLowerCase();
61
+ if (relNormalized.endsWith(`/${moduleNameLc}.yaml`))
62
+ return true;
63
+ const moduleYamlPath = path.isAbsolute(moduleYamlRel)
64
+ ? moduleYamlRel
65
+ : path.resolve(process.cwd(), moduleYamlRel);
66
+ const dirName = path.basename(path.dirname(moduleYamlPath)).toLowerCase();
67
+ if (dirName === moduleNameLc)
68
+ return true;
69
+ if (relNormalized.includes(`/${moduleNameLc}/`) || relNormalized.endsWith(`/${moduleNameLc}`))
70
+ return true;
71
+ return false;
72
+ };
73
+ const filteredModules = modulesList.filter(shouldIncludeModule);
74
+ if (filteredModules.length === 0) {
75
+ // eslint-disable-next-line no-console
76
+ console.warn(colors_1.colors.yellow(`No modules matched: ${moduleName}`));
77
+ return;
78
+ }
79
+ const domainGen = new domainModelGenerator_1.DomainModelGenerator();
80
+ const valGen = new validationGenerator_1.ValidationGenerator();
81
+ const svcGen = new serviceGenerator_1.ServiceGenerator();
82
+ const ctrlGen = new controllerGenerator_1.ControllerGenerator();
83
+ const storeGen = new storeGenerator_1.StoreGenerator();
84
+ const results = [];
85
+ for (const moduleYamlRel of filteredModules) {
86
+ const moduleYamlPath = path.isAbsolute(moduleYamlRel)
87
+ ? moduleYamlRel
88
+ : path.resolve(process.cwd(), moduleYamlRel);
89
+ if (!fs.existsSync(moduleYamlPath))
90
+ continue;
91
+ const moduleDir = path.dirname(moduleYamlPath);
92
+ const domainOut = path.join(moduleDir, 'domain', 'entities');
93
+ const appOut = path.join(moduleDir, 'application');
94
+ const infraOut = path.join(moduleDir, 'infrastructure');
95
+ const nextDomain = domainGen.generateFromYamlFile(moduleYamlPath);
96
+ const nextValidations = valGen.generateFromYamlFile(moduleYamlPath);
97
+ const nextServices = svcGen.generateFromYamlFile(moduleYamlPath);
98
+ const nextControllers = ctrlGen.generateFromYamlFile(moduleYamlPath);
99
+ const nextStores = storeGen.generateFromYamlFile(moduleYamlPath);
100
+ const consider = (target, generated) => {
101
+ const rel = path.relative(process.cwd(), target);
102
+ if (!fs.existsSync(target)) {
103
+ results.push({ file: rel, status: 'missing' });
104
+ return;
105
+ }
106
+ const content = fs.readFileSync(target, 'utf8');
107
+ const currentHash = (0, generationRegistry_1.computeContentHash)(content);
108
+ const stored = (0, generationRegistry_1.getStoredHash)(target);
109
+ // Try using registry hunks to establish expected content after applying commits
110
+ const registry = (0, generationRegistry_1.loadRegistry)();
111
+ const entry = registry[rel];
112
+ const genHash = (0, generationRegistry_1.computeContentHash)(generated);
113
+ let baseForDiff = generated;
114
+ let note;
115
+ if (entry && entry.diffFormat === 'hunks-v1' && entry.diffBaseHash === genHash && entry.diffHunks) {
116
+ const applied = (0, commitUtils_1.applyHunksToBase)(generated, entry.diffHunks);
117
+ if (applied != null) {
118
+ baseForDiff = applied;
119
+ note = 'committed changes applied';
120
+ }
121
+ }
122
+ const baseHash = (0, generationRegistry_1.computeContentHash)(baseForDiff);
123
+ if (stored && stored === currentHash && baseHash === currentHash) {
124
+ results.push({ file: rel, status: 'clean', note });
125
+ return;
126
+ }
127
+ const hunks = (0, commitUtils_1.computeHunks)(baseForDiff, content); // base: expected after commits, new: current
128
+ if (hunks.length === 0) {
129
+ results.push({ file: rel, status: 'clean', note });
130
+ return;
131
+ }
132
+ results.push({ file: rel, status: 'modified', hunks, note });
133
+ };
134
+ Object.entries(nextDomain).forEach(([e, code]) => consider(path.join(domainOut, `${e}.ts`), code));
135
+ Object.entries(nextValidations).forEach(([e, code]) => consider(path.join(appOut, 'validation', `${e}Validation.ts`), code));
136
+ Object.entries(nextServices).forEach(([e, code]) => consider(path.join(appOut, 'services', `${e}Service.ts`), code));
137
+ Object.entries(nextControllers).forEach(([e, code]) => consider(path.join(infraOut, 'controllers', `${e}Controller.ts`), code));
138
+ Object.entries(nextStores).forEach(([e, code]) => consider(path.join(infraOut, 'stores', `${e}Store.ts`), code));
139
+ }
140
+ if (results.length === 0) {
141
+ // eslint-disable-next-line no-console
142
+ console.log(colors_1.colors.dim('No files to compare.'));
143
+ return;
144
+ }
145
+ // eslint-disable-next-line no-console
146
+ console.log('\n' + colors_1.colors.bold('Current diffs (compared to generated):'));
147
+ results.forEach(r => {
148
+ var _a;
149
+ if (r.status === 'clean') {
150
+ console.log(`\n${colors_1.colors.green('[clean]')} ${colors_1.colors.dim(r.file)}`);
151
+ }
152
+ else if (r.status === 'missing') {
153
+ console.log(`\n${colors_1.colors.red('[missing]')} ${colors_1.colors.dim(r.file)}`);
154
+ }
155
+ else {
156
+ console.log(`\n${colors_1.colors.yellow('[modified]')} ${colors_1.colors.dim(r.file)}`);
157
+ (_a = r.hunks) === null || _a === void 0 ? void 0 : _a.forEach(h => {
158
+ console.log(colors_1.colors.cyan(`@@ -${h.oldStart + 1},${h.oldLines} +${h.newStart + 1},${h.newLines} @@`));
159
+ h.oldContent.forEach(line => console.log(colors_1.colors.red(`- ${line}`)));
160
+ h.newContent.forEach(line => console.log(colors_1.colors.green(`+ ${line}`)));
161
+ });
162
+ }
163
+ });
164
+ }
@@ -0,0 +1,4 @@
1
+ export declare function handleGenerateAll(yamlPathArg?: string, _outArg?: string, moduleName?: string, opts?: {
2
+ force?: boolean;
3
+ skip?: boolean;
4
+ }): Promise<void>;