@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.
- package/CHANGELOG.md +7 -0
- package/LICENSE +56 -0
- package/README.md +686 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +143 -0
- package/dist/commands/commit.d.ts +1 -0
- package/dist/commands/commit.js +153 -0
- package/dist/commands/createApp.d.ts +1 -0
- package/dist/commands/createApp.js +64 -0
- package/dist/commands/createModule.d.ts +1 -0
- package/dist/commands/createModule.js +121 -0
- package/dist/commands/diff.d.ts +1 -0
- package/dist/commands/diff.js +164 -0
- package/dist/commands/generateAll.d.ts +4 -0
- package/dist/commands/generateAll.js +305 -0
- package/dist/commands/infer.d.ts +1 -0
- package/dist/commands/infer.js +179 -0
- package/dist/generators/controllerGenerator.d.ts +20 -0
- package/dist/generators/controllerGenerator.js +280 -0
- package/dist/generators/domainModelGenerator.d.ts +33 -0
- package/dist/generators/domainModelGenerator.js +175 -0
- package/dist/generators/serviceGenerator.d.ts +39 -0
- package/dist/generators/serviceGenerator.js +379 -0
- package/dist/generators/storeGenerator.d.ts +31 -0
- package/dist/generators/storeGenerator.js +191 -0
- package/dist/generators/templateGenerator.d.ts +11 -0
- package/dist/generators/templateGenerator.js +143 -0
- package/dist/generators/templates/appTemplates.d.ts +27 -0
- package/dist/generators/templates/appTemplates.js +1621 -0
- package/dist/generators/templates/controllerTemplates.d.ts +43 -0
- package/dist/generators/templates/controllerTemplates.js +82 -0
- package/dist/generators/templates/index.d.ts +5 -0
- package/dist/generators/templates/index.js +21 -0
- package/dist/generators/templates/serviceTemplates.d.ts +15 -0
- package/dist/generators/templates/serviceTemplates.js +54 -0
- package/dist/generators/templates/storeTemplates.d.ts +9 -0
- package/dist/generators/templates/storeTemplates.js +260 -0
- package/dist/generators/templates/validationTemplates.d.ts +25 -0
- package/dist/generators/templates/validationTemplates.js +66 -0
- package/dist/generators/templates/viewTemplates.d.ts +16 -0
- package/dist/generators/templates/viewTemplates.js +359 -0
- package/dist/generators/validationGenerator.d.ts +24 -0
- package/dist/generators/validationGenerator.js +199 -0
- package/dist/utils/cliUtils.d.ts +6 -0
- package/dist/utils/cliUtils.js +71 -0
- package/dist/utils/colors.d.ts +26 -0
- package/dist/utils/colors.js +80 -0
- package/dist/utils/commitUtils.d.ts +46 -0
- package/dist/utils/commitUtils.js +377 -0
- package/dist/utils/constants.d.ts +52 -0
- package/dist/utils/constants.js +64 -0
- package/dist/utils/generationRegistry.d.ts +25 -0
- package/dist/utils/generationRegistry.js +192 -0
- package/howto.md +556 -0
- 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
|
+
}
|