@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.
- package/CHANGELOG.md +8 -289
- package/README.md +623 -427
- package/dist/cli.js +2 -1
- package/dist/commands/commit.js +25 -42
- package/dist/commands/createApp.js +1 -0
- package/dist/commands/createModule.js +151 -45
- package/dist/commands/diff.js +27 -40
- package/dist/commands/generateAll.js +141 -291
- package/dist/commands/migrateCommit.js +6 -18
- package/dist/commands/migratePush.d.ts +1 -0
- package/dist/commands/migratePush.js +135 -0
- package/dist/commands/migrateUpdate.d.ts +1 -0
- package/dist/commands/migrateUpdate.js +147 -0
- package/dist/commands/newGenerateAll.d.ts +4 -0
- package/dist/commands/newGenerateAll.js +336 -0
- package/dist/generators/controllerGenerator.d.ts +43 -19
- package/dist/generators/controllerGenerator.js +547 -329
- package/dist/generators/domainLayerGenerator.d.ts +21 -0
- package/dist/generators/domainLayerGenerator.js +276 -0
- package/dist/generators/dtoGenerator.d.ts +21 -0
- package/dist/generators/dtoGenerator.js +518 -0
- package/dist/generators/newControllerGenerator.d.ts +55 -0
- package/dist/generators/newControllerGenerator.js +644 -0
- package/dist/generators/newServiceGenerator.d.ts +19 -0
- package/dist/generators/newServiceGenerator.js +266 -0
- package/dist/generators/newStoreGenerator.d.ts +39 -0
- package/dist/generators/newStoreGenerator.js +408 -0
- package/dist/generators/newTemplateGenerator.d.ts +29 -0
- package/dist/generators/newTemplateGenerator.js +510 -0
- package/dist/generators/serviceGenerator.d.ts +16 -51
- package/dist/generators/serviceGenerator.js +167 -586
- package/dist/generators/storeGenerator.d.ts +35 -32
- package/dist/generators/storeGenerator.js +291 -238
- package/dist/generators/storeGeneratorV2.d.ts +31 -0
- package/dist/generators/storeGeneratorV2.js +190 -0
- package/dist/generators/templateGenerator.d.ts +21 -21
- package/dist/generators/templateGenerator.js +393 -268
- package/dist/generators/templates/appTemplates.d.ts +3 -1
- package/dist/generators/templates/appTemplates.js +15 -10
- package/dist/generators/templates/data/appYamlTemplate +5 -2
- package/dist/generators/templates/data/cursorRulesTemplate +315 -221
- package/dist/generators/templates/data/frontendScriptTemplate +76 -47
- package/dist/generators/templates/data/mainViewTemplate +1 -1
- package/dist/generators/templates/data/systemTsTemplate +5 -0
- package/dist/generators/templates/index.d.ts +0 -3
- package/dist/generators/templates/index.js +0 -3
- package/dist/generators/templates/newStoreTemplates.d.ts +5 -0
- package/dist/generators/templates/newStoreTemplates.js +141 -0
- package/dist/generators/templates/storeTemplates.d.ts +1 -5
- package/dist/generators/templates/storeTemplates.js +102 -219
- package/dist/generators/templates/viewTemplates.js +1 -1
- package/dist/generators/useCaseGenerator.d.ts +13 -0
- package/dist/generators/useCaseGenerator.js +188 -0
- package/dist/types/configTypes.d.ts +148 -0
- package/dist/types/configTypes.js +10 -0
- package/dist/utils/childEntityUtils.d.ts +18 -0
- package/dist/utils/childEntityUtils.js +78 -0
- package/dist/utils/commandUtils.d.ts +43 -0
- package/dist/utils/commandUtils.js +124 -0
- package/dist/utils/commitUtils.d.ts +4 -1
- package/dist/utils/constants.d.ts +10 -0
- package/dist/utils/constants.js +13 -1
- package/dist/utils/diResolver.d.ts +32 -0
- package/dist/utils/diResolver.js +204 -0
- package/dist/utils/new_parts_of_migrationUtils.d.ts +0 -0
- package/dist/utils/new_parts_of_migrationUtils.js +164 -0
- package/dist/utils/typeUtils.d.ts +19 -0
- package/dist/utils/typeUtils.js +70 -0
- package/package.json +7 -3
|
@@ -0,0 +1,135 @@
|
|
|
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.handleMigratePush = handleMigratePush;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const colors_1 = require("../utils/colors");
|
|
40
|
+
const cliUtils_1 = require("../utils/cliUtils");
|
|
41
|
+
const migrationUtils_1 = require("../utils/migrationUtils");
|
|
42
|
+
async function handleMigratePush(yamlPath) {
|
|
43
|
+
let connection;
|
|
44
|
+
try {
|
|
45
|
+
const resolvedYamlPath = (0, cliUtils_1.resolveYamlPath)(yamlPath);
|
|
46
|
+
const projectRoot = path.dirname(resolvedYamlPath);
|
|
47
|
+
const migrationsDir = path.join(projectRoot, 'migrations');
|
|
48
|
+
// Check if migrations directory exists
|
|
49
|
+
if (!fs.existsSync(migrationsDir)) {
|
|
50
|
+
// eslint-disable-next-line no-console
|
|
51
|
+
console.log(colors_1.colors.yellow('⚠️ No migrations directory found. Run "currentjs migrate commit" first.'));
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
// Get all migration files
|
|
55
|
+
const migrationFiles = fs.readdirSync(migrationsDir)
|
|
56
|
+
.filter(f => f.endsWith('.sql'))
|
|
57
|
+
.sort();
|
|
58
|
+
if (migrationFiles.length === 0) {
|
|
59
|
+
// eslint-disable-next-line no-console
|
|
60
|
+
console.log(colors_1.colors.yellow('⚠️ No migration files found. Run "currentjs migrate commit" first.'));
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
// eslint-disable-next-line no-console
|
|
64
|
+
console.log(colors_1.colors.cyan('\n🔌 Connecting to database...'));
|
|
65
|
+
// Verify environment variables
|
|
66
|
+
if (!process.env.DB_HOST || !process.env.DB_USER || !process.env.DB_NAME) {
|
|
67
|
+
// eslint-disable-next-line no-console
|
|
68
|
+
console.log(colors_1.colors.yellow('\n💡 Database configuration:'));
|
|
69
|
+
// eslint-disable-next-line no-console
|
|
70
|
+
console.log(colors_1.colors.gray(` Host: ${process.env.DB_HOST || 'localhost (default)'}`));
|
|
71
|
+
// eslint-disable-next-line no-console
|
|
72
|
+
console.log(colors_1.colors.gray(` Port: ${process.env.DB_PORT || '3306 (default)'}`));
|
|
73
|
+
// eslint-disable-next-line no-console
|
|
74
|
+
console.log(colors_1.colors.gray(` User: ${process.env.DB_USER || 'root (default)'}`));
|
|
75
|
+
// eslint-disable-next-line no-console
|
|
76
|
+
console.log(colors_1.colors.gray(` Database: ${process.env.DB_NAME || 'test (default)'}`));
|
|
77
|
+
if (!process.env.DB_HOST || !process.env.DB_USER || !process.env.DB_NAME) {
|
|
78
|
+
// eslint-disable-next-line no-console
|
|
79
|
+
console.log(colors_1.colors.yellow('\n⚠️ Environment variables not set. Using defaults.'));
|
|
80
|
+
// eslint-disable-next-line no-console
|
|
81
|
+
console.log(colors_1.colors.cyan(' Set DB_HOST, DB_PORT, DB_USER, DB_PASSWORD, DB_NAME to configure.'));
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
connection = await (0, migrationUtils_1.connectToDatabase)();
|
|
85
|
+
// eslint-disable-next-line no-console
|
|
86
|
+
console.log(colors_1.colors.green('✓ Connected to database'));
|
|
87
|
+
// Get already applied migrations
|
|
88
|
+
// eslint-disable-next-line no-console
|
|
89
|
+
console.log(colors_1.colors.cyan('\n📖 Checking applied migrations...'));
|
|
90
|
+
const appliedMigrations = await (0, migrationUtils_1.getAppliedMigrations)(connection);
|
|
91
|
+
// eslint-disable-next-line no-console
|
|
92
|
+
console.log(colors_1.colors.gray(` Applied: ${appliedMigrations.length} migration(s)`));
|
|
93
|
+
// Find pending migrations
|
|
94
|
+
const pendingMigrations = migrationFiles.filter(f => !appliedMigrations.includes(f));
|
|
95
|
+
if (pendingMigrations.length === 0) {
|
|
96
|
+
// eslint-disable-next-line no-console
|
|
97
|
+
console.log(colors_1.colors.green('\n✅ Database is up to date. No pending migrations.'));
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
// eslint-disable-next-line no-console
|
|
101
|
+
console.log(colors_1.colors.cyan(`\n🚀 Applying ${pendingMigrations.length} migration(s)...`));
|
|
102
|
+
// Apply pending migrations
|
|
103
|
+
for (const migrationFile of pendingMigrations) {
|
|
104
|
+
const migrationPath = path.join(migrationsDir, migrationFile);
|
|
105
|
+
const migrationSQL = fs.readFileSync(migrationPath, 'utf8');
|
|
106
|
+
// eslint-disable-next-line no-console
|
|
107
|
+
console.log(colors_1.colors.gray(` → ${migrationFile}...`));
|
|
108
|
+
try {
|
|
109
|
+
await (0, migrationUtils_1.executeMigration)(connection, migrationSQL);
|
|
110
|
+
await (0, migrationUtils_1.recordMigration)(connection, migrationFile);
|
|
111
|
+
// eslint-disable-next-line no-console
|
|
112
|
+
console.log(colors_1.colors.green(` ✓ ${migrationFile} applied`));
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
// eslint-disable-next-line no-console
|
|
116
|
+
console.error(colors_1.colors.red(` ✗ Failed to apply ${migrationFile}:`));
|
|
117
|
+
// eslint-disable-next-line no-console
|
|
118
|
+
console.error(colors_1.colors.red(` ${error instanceof Error ? error.message : String(error)}`));
|
|
119
|
+
throw error;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
// eslint-disable-next-line no-console
|
|
123
|
+
console.log(colors_1.colors.green('\n✅ All migrations applied successfully!'));
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
// eslint-disable-next-line no-console
|
|
127
|
+
console.error(colors_1.colors.red('\n❌ Error applying migrations:'), error instanceof Error ? error.message : String(error));
|
|
128
|
+
process.exitCode = 1;
|
|
129
|
+
}
|
|
130
|
+
finally {
|
|
131
|
+
if (connection) {
|
|
132
|
+
await connection.end();
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function handleMigrateUpdate(yamlPath?: string): Promise<void>;
|
|
@@ -0,0 +1,147 @@
|
|
|
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.handleMigrateUpdate = handleMigrateUpdate;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const colors_1 = require("../utils/colors");
|
|
40
|
+
const cliUtils_1 = require("../utils/cliUtils");
|
|
41
|
+
const migrationUtils_1 = require("../utils/migrationUtils");
|
|
42
|
+
async function handleMigrateUpdate(yamlPath) {
|
|
43
|
+
let connection;
|
|
44
|
+
try {
|
|
45
|
+
const resolvedYamlPath = (0, cliUtils_1.resolveYamlPath)(yamlPath);
|
|
46
|
+
const projectRoot = path.dirname(resolvedYamlPath);
|
|
47
|
+
const migrationsDir = path.join(projectRoot, 'migrations');
|
|
48
|
+
const stateFilePath = path.join(migrationsDir, 'schema_state.yaml');
|
|
49
|
+
// Ensure migrations directory exists
|
|
50
|
+
if (!fs.existsSync(migrationsDir)) {
|
|
51
|
+
fs.mkdirSync(migrationsDir, { recursive: true });
|
|
52
|
+
}
|
|
53
|
+
// eslint-disable-next-line no-console
|
|
54
|
+
console.log(colors_1.colors.cyan('\n🔌 Connecting to database...'));
|
|
55
|
+
// Verify environment variables
|
|
56
|
+
if (!process.env.DB_HOST || !process.env.DB_USER || !process.env.DB_NAME) {
|
|
57
|
+
// eslint-disable-next-line no-console
|
|
58
|
+
console.log(colors_1.colors.yellow('\n💡 Database configuration:'));
|
|
59
|
+
// eslint-disable-next-line no-console
|
|
60
|
+
console.log(colors_1.colors.gray(` Host: ${process.env.DB_HOST || 'localhost (default)'}`));
|
|
61
|
+
// eslint-disable-next-line no-console
|
|
62
|
+
console.log(colors_1.colors.gray(` Port: ${process.env.DB_PORT || '3306 (default)'}`));
|
|
63
|
+
// eslint-disable-next-line no-console
|
|
64
|
+
console.log(colors_1.colors.gray(` User: ${process.env.DB_USER || 'root (default)'}`));
|
|
65
|
+
// eslint-disable-next-line no-console
|
|
66
|
+
console.log(colors_1.colors.gray(` Database: ${process.env.DB_NAME || 'test (default)'}`));
|
|
67
|
+
if (!process.env.DB_HOST || !process.env.DB_USER || !process.env.DB_NAME) {
|
|
68
|
+
// eslint-disable-next-line no-console
|
|
69
|
+
console.log(colors_1.colors.yellow('\n⚠️ Environment variables not set. Using defaults.'));
|
|
70
|
+
// eslint-disable-next-line no-console
|
|
71
|
+
console.log(colors_1.colors.cyan(' Set DB_HOST, DB_PORT, DB_USER, DB_PASSWORD, DB_NAME to configure.'));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
connection = await (0, migrationUtils_1.connectToDatabase)();
|
|
75
|
+
// eslint-disable-next-line no-console
|
|
76
|
+
console.log(colors_1.colors.green('✓ Connected to database'));
|
|
77
|
+
// Extract schema from database
|
|
78
|
+
// eslint-disable-next-line no-console
|
|
79
|
+
console.log(colors_1.colors.cyan('\n🔍 Extracting schema from database...'));
|
|
80
|
+
const dbModels = await (0, migrationUtils_1.extractSchemaFromDatabase)(connection);
|
|
81
|
+
if (dbModels.length === 0) {
|
|
82
|
+
// eslint-disable-next-line no-console
|
|
83
|
+
console.log(colors_1.colors.yellow('⚠️ No tables found in database.'));
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
// eslint-disable-next-line no-console
|
|
87
|
+
console.log(colors_1.colors.green(`✓ Found ${dbModels.length} table(s): ${dbModels.map(m => m.name).join(', ')}`));
|
|
88
|
+
// Load current state
|
|
89
|
+
const currentState = (0, migrationUtils_1.loadSchemaState)(stateFilePath);
|
|
90
|
+
if (currentState) {
|
|
91
|
+
// eslint-disable-next-line no-console
|
|
92
|
+
console.log(colors_1.colors.cyan(`📖 Current schema state loaded (version: ${currentState.version})`));
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
// eslint-disable-next-line no-console
|
|
96
|
+
console.log(colors_1.colors.cyan('📖 No current schema state found'));
|
|
97
|
+
}
|
|
98
|
+
// Compare database schema with current state
|
|
99
|
+
// eslint-disable-next-line no-console
|
|
100
|
+
console.log(colors_1.colors.cyan('\n🔍 Comparing database schema with current state...'));
|
|
101
|
+
const sqlStatements = (0, migrationUtils_1.compareSchemas)(currentState, dbModels);
|
|
102
|
+
if (sqlStatements.length === 0 || sqlStatements.every(s => s.trim() === '' || s.startsWith('--'))) {
|
|
103
|
+
// eslint-disable-next-line no-console
|
|
104
|
+
console.log(colors_1.colors.green('✅ Database schema matches current state. No changes to record.'));
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
// Generate migration file
|
|
108
|
+
const timestamp = (0, migrationUtils_1.generateTimestamp)();
|
|
109
|
+
const migrationFileName = (0, migrationUtils_1.getMigrationFileName)(timestamp);
|
|
110
|
+
const migrationFilePath = path.join(migrationsDir, migrationFileName);
|
|
111
|
+
const migrationHeader = `-- Migration: Database schema sync
|
|
112
|
+
-- Created: ${new Date().toISOString().split('T')[0]}
|
|
113
|
+
-- Timestamp: ${timestamp}
|
|
114
|
+
-- Source: Database schema extraction
|
|
115
|
+
|
|
116
|
+
`;
|
|
117
|
+
const migrationContent = migrationHeader + sqlStatements.join('\n');
|
|
118
|
+
fs.writeFileSync(migrationFilePath, migrationContent);
|
|
119
|
+
// Update state file
|
|
120
|
+
const newState = {
|
|
121
|
+
models: dbModels,
|
|
122
|
+
version: timestamp,
|
|
123
|
+
timestamp: new Date().toISOString()
|
|
124
|
+
};
|
|
125
|
+
(0, migrationUtils_1.saveSchemaState)(stateFilePath, newState);
|
|
126
|
+
// eslint-disable-next-line no-console
|
|
127
|
+
console.log(colors_1.colors.green('\n✅ Migration created from database schema!'));
|
|
128
|
+
// eslint-disable-next-line no-console
|
|
129
|
+
console.log(colors_1.colors.gray(` File: ${migrationFileName}`));
|
|
130
|
+
// eslint-disable-next-line no-console
|
|
131
|
+
console.log(colors_1.colors.gray(` Path: ${migrationFilePath}`));
|
|
132
|
+
// eslint-disable-next-line no-console
|
|
133
|
+
console.log(colors_1.colors.cyan('\n💡 Schema state updated to match database.'));
|
|
134
|
+
// eslint-disable-next-line no-console
|
|
135
|
+
console.log(colors_1.colors.cyan(' You can now modify your YAML files and run "currentjs migrate commit" to create new migrations.'));
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
// eslint-disable-next-line no-console
|
|
139
|
+
console.error(colors_1.colors.red('\n❌ Error updating migration from database:'), error instanceof Error ? error.message : String(error));
|
|
140
|
+
process.exitCode = 1;
|
|
141
|
+
}
|
|
142
|
+
finally {
|
|
143
|
+
if (connection) {
|
|
144
|
+
await connection.end();
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
@@ -0,0 +1,336 @@
|
|
|
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.handleNewGenerateAll = handleNewGenerateAll;
|
|
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 domainLayerGenerator_1 = require("../generators/domainLayerGenerator");
|
|
42
|
+
const dtoGenerator_1 = require("../generators/dtoGenerator");
|
|
43
|
+
const useCaseGenerator_1 = require("../generators/useCaseGenerator");
|
|
44
|
+
const newServiceGenerator_1 = require("../generators/newServiceGenerator");
|
|
45
|
+
const newControllerGenerator_1 = require("../generators/newControllerGenerator");
|
|
46
|
+
const newTemplateGenerator_1 = require("../generators/newTemplateGenerator");
|
|
47
|
+
const newStoreGenerator_1 = require("../generators/newStoreGenerator");
|
|
48
|
+
const generationRegistry_1 = require("../utils/generationRegistry");
|
|
49
|
+
const colors_1 = require("../utils/colors");
|
|
50
|
+
const constants_1 = require("../utils/constants");
|
|
51
|
+
const configTypes_1 = require("../types/configTypes");
|
|
52
|
+
const childEntityUtils_1 = require("../utils/childEntityUtils");
|
|
53
|
+
async function handleNewGenerateAll(yamlPathArg, _outArg, moduleName, opts) {
|
|
54
|
+
var _a, _b;
|
|
55
|
+
const appYamlPath = (0, cliUtils_1.resolveYamlPath)(yamlPathArg);
|
|
56
|
+
(0, generationRegistry_1.initGenerationRegistry)(process.cwd());
|
|
57
|
+
const raw = fs.readFileSync(appYamlPath, 'utf8');
|
|
58
|
+
const appConfig = (0, yaml_1.parse)(raw);
|
|
59
|
+
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));
|
|
60
|
+
const providersConfig = appConfig === null || appConfig === void 0 ? void 0 : appConfig.providers;
|
|
61
|
+
const databaseProviderName = appConfig === null || appConfig === void 0 ? void 0 : appConfig.database;
|
|
62
|
+
const shouldIncludeModule = (moduleYamlRel) => {
|
|
63
|
+
if (!moduleName || moduleName === '*')
|
|
64
|
+
return true;
|
|
65
|
+
const moduleNameLc = moduleName.toLowerCase();
|
|
66
|
+
const relNormalized = moduleYamlRel.replace(/\\/g, '/').toLowerCase();
|
|
67
|
+
if (relNormalized.endsWith(`/${moduleNameLc}.yaml`))
|
|
68
|
+
return true;
|
|
69
|
+
const moduleYamlPath = path.isAbsolute(moduleYamlRel)
|
|
70
|
+
? moduleYamlRel
|
|
71
|
+
: path.resolve(process.cwd(), moduleYamlRel);
|
|
72
|
+
const dirName = path.basename(path.dirname(moduleYamlPath)).toLowerCase();
|
|
73
|
+
if (dirName === moduleNameLc)
|
|
74
|
+
return true;
|
|
75
|
+
if (relNormalized.includes(`/${moduleNameLc}/`) || relNormalized.endsWith(`/${moduleNameLc}`))
|
|
76
|
+
return true;
|
|
77
|
+
return false;
|
|
78
|
+
};
|
|
79
|
+
const filteredModules = modulesList.filter(shouldIncludeModule);
|
|
80
|
+
if (filteredModules.length === 0) {
|
|
81
|
+
// eslint-disable-next-line no-console
|
|
82
|
+
console.warn(colors_1.colors.yellow(`No modules matched: ${moduleName}`));
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
// Initialize generators
|
|
86
|
+
const domainGen = new domainLayerGenerator_1.DomainLayerGenerator();
|
|
87
|
+
const dtoGen = new dtoGenerator_1.DtoGenerator();
|
|
88
|
+
const useCaseGen = new useCaseGenerator_1.UseCaseGenerator();
|
|
89
|
+
const serviceGen = new newServiceGenerator_1.NewServiceGenerator();
|
|
90
|
+
const controllerGen = new newControllerGenerator_1.NewControllerGenerator();
|
|
91
|
+
const templateGen = new newTemplateGenerator_1.NewTemplateGenerator();
|
|
92
|
+
const storeGen = new newStoreGenerator_1.NewStoreGenerator();
|
|
93
|
+
const initsBySrcDir = new Map();
|
|
94
|
+
// Process each module
|
|
95
|
+
for (const moduleYamlRel of filteredModules) {
|
|
96
|
+
const moduleYamlPath = path.isAbsolute(moduleYamlRel)
|
|
97
|
+
? moduleYamlRel
|
|
98
|
+
: path.resolve(process.cwd(), moduleYamlRel);
|
|
99
|
+
if (!fs.existsSync(moduleYamlPath)) {
|
|
100
|
+
// eslint-disable-next-line no-console
|
|
101
|
+
console.warn(colors_1.colors.yellow(`Module YAML not found: ${moduleYamlPath}`));
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
// Check if this is a new format config
|
|
105
|
+
const moduleYamlContent = fs.readFileSync(moduleYamlPath, 'utf8');
|
|
106
|
+
const moduleConfig = (0, yaml_1.parse)(moduleYamlContent);
|
|
107
|
+
if (!(0, configTypes_1.isNewModuleConfig)(moduleConfig)) {
|
|
108
|
+
// eslint-disable-next-line no-console
|
|
109
|
+
console.warn(colors_1.colors.yellow(`Skipping ${moduleYamlPath}: not in new format (missing domain/useCases)`));
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
const moduleDir = path.dirname(moduleYamlPath);
|
|
113
|
+
// eslint-disable-next-line no-console
|
|
114
|
+
console.log(colors_1.colors.blue(`\nGenerating module: ${path.basename(moduleDir)}`));
|
|
115
|
+
// 1. Generate domain layer (entities + value objects)
|
|
116
|
+
// eslint-disable-next-line no-await-in-loop
|
|
117
|
+
await domainGen.generateAndSaveFiles(moduleYamlPath, moduleDir, opts);
|
|
118
|
+
// 2. Generate DTOs
|
|
119
|
+
// eslint-disable-next-line no-await-in-loop
|
|
120
|
+
await dtoGen.generateAndSaveFiles(moduleYamlPath, moduleDir, opts);
|
|
121
|
+
// 3. Generate Use Cases
|
|
122
|
+
// eslint-disable-next-line no-await-in-loop
|
|
123
|
+
await useCaseGen.generateAndSaveFiles(moduleYamlPath, moduleDir, opts);
|
|
124
|
+
// 4. Generate Services
|
|
125
|
+
// eslint-disable-next-line no-await-in-loop
|
|
126
|
+
await serviceGen.generateAndSaveFiles(moduleYamlPath, moduleDir, opts);
|
|
127
|
+
// 5. Generate Stores
|
|
128
|
+
// eslint-disable-next-line no-await-in-loop
|
|
129
|
+
await storeGen.generateAndSaveFiles(moduleYamlPath, moduleDir, opts);
|
|
130
|
+
// 6. Generate Controllers
|
|
131
|
+
// eslint-disable-next-line no-await-in-loop
|
|
132
|
+
const controllerPaths = await controllerGen.generateAndSaveFiles(moduleYamlPath, moduleDir, opts);
|
|
133
|
+
// 7. Generate Templates
|
|
134
|
+
// eslint-disable-next-line no-await-in-loop
|
|
135
|
+
await templateGen.generateAndSaveFiles(moduleYamlPath, moduleDir, opts);
|
|
136
|
+
// Collect wiring information for app.ts
|
|
137
|
+
let probeDir = moduleDir;
|
|
138
|
+
let srcDir = null;
|
|
139
|
+
for (let i = 0; i < 6; i += 1) {
|
|
140
|
+
const candidate = path.join(probeDir, 'src', constants_1.COMMON_FILES.APP_TS);
|
|
141
|
+
if (fs.existsSync(candidate)) {
|
|
142
|
+
srcDir = path.join(probeDir, 'src');
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
145
|
+
const parent = path.dirname(probeDir);
|
|
146
|
+
if (parent === probeDir)
|
|
147
|
+
break;
|
|
148
|
+
probeDir = parent;
|
|
149
|
+
}
|
|
150
|
+
if (!srcDir)
|
|
151
|
+
continue;
|
|
152
|
+
// Build wiring for each model in the module
|
|
153
|
+
const list = (_b = initsBySrcDir.get(srcDir)) !== null && _b !== void 0 ? _b : [];
|
|
154
|
+
Object.keys(moduleConfig.useCases).forEach(modelName => {
|
|
155
|
+
const entityVar = modelName.charAt(0).toLowerCase() + modelName.slice(1);
|
|
156
|
+
const moduleFolderName = path.basename(moduleDir);
|
|
157
|
+
const init = {
|
|
158
|
+
entityName: modelName,
|
|
159
|
+
entityVar,
|
|
160
|
+
importStore: `import { ${modelName}Store } from './modules/${moduleFolderName}/infrastructure/stores/${modelName}Store';`,
|
|
161
|
+
importService: `import { ${modelName}Service } from './modules/${moduleFolderName}/application/services/${modelName}Service';`,
|
|
162
|
+
importUseCase: `import { ${modelName}UseCase } from './modules/${moduleFolderName}/application/useCases/${modelName}UseCase';`,
|
|
163
|
+
importController: '',
|
|
164
|
+
wiring: [],
|
|
165
|
+
registration: ''
|
|
166
|
+
};
|
|
167
|
+
// Check if this root entity's web controller needs child services (withChild: true)
|
|
168
|
+
const childEntityMap = (0, childEntityUtils_1.buildChildEntityMap)(moduleConfig);
|
|
169
|
+
const isRootEntity = !childEntityMap.has(modelName);
|
|
170
|
+
const withChildChildren = isRootEntity ? (0, childEntityUtils_1.getChildrenOfParent)(moduleConfig, modelName) : [];
|
|
171
|
+
const webUseCases = moduleConfig.useCases[modelName];
|
|
172
|
+
const needsChildServices = withChildChildren.length > 0 && webUseCases && Object.entries(webUseCases).some(([action, uc]) => action === 'get' && uc.withChild === true);
|
|
173
|
+
// Add controller imports if they exist
|
|
174
|
+
controllerPaths.forEach(ctrlPath => {
|
|
175
|
+
const ctrlName = path.basename(ctrlPath, '.ts');
|
|
176
|
+
const ctrlModelName = ctrlName.replace(/(Api|Web)Controller$/, '');
|
|
177
|
+
if (ctrlModelName === modelName) {
|
|
178
|
+
const rel = path.relative(srcDir, ctrlPath).replace(/\\/g, '/').replace(/\.ts$/, '');
|
|
179
|
+
const importPath = rel.startsWith('.') ? rel : `./${rel}`;
|
|
180
|
+
init.importController += `import { ${ctrlName} } from '${importPath}';\n`;
|
|
181
|
+
// Web controllers may need child services when withChild is true
|
|
182
|
+
const isWebCtrl = ctrlName.endsWith('WebController');
|
|
183
|
+
if (isWebCtrl && needsChildServices) {
|
|
184
|
+
const childServiceArgs = withChildChildren
|
|
185
|
+
.map(c => c.childEntityName.charAt(0).toLowerCase() + c.childEntityName.slice(1) + 'Service')
|
|
186
|
+
.join(', ');
|
|
187
|
+
init.registration += `new ${ctrlName}(${entityVar}UseCase, ${childServiceArgs}),\n `;
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
init.registration += `new ${ctrlName}(${entityVar}UseCase),\n `;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
list.push(init);
|
|
195
|
+
});
|
|
196
|
+
initsBySrcDir.set(srcDir, list);
|
|
197
|
+
}
|
|
198
|
+
// Update app.ts files with wiring
|
|
199
|
+
for (const [srcDir, controllerInits] of initsBySrcDir.entries()) {
|
|
200
|
+
try {
|
|
201
|
+
const appTsPath = path.join(srcDir, constants_1.COMMON_FILES.APP_TS);
|
|
202
|
+
if (!fs.existsSync(appTsPath))
|
|
203
|
+
continue;
|
|
204
|
+
let appTs = fs.readFileSync(appTsPath, 'utf8');
|
|
205
|
+
// Build providers import and initialization from app.yaml providers section
|
|
206
|
+
const importLines = [];
|
|
207
|
+
const providerInitLines = [];
|
|
208
|
+
const providersArrayEntries = [];
|
|
209
|
+
let isIProviderImported = false;
|
|
210
|
+
if (providersConfig && Object.keys(providersConfig).length > 0) {
|
|
211
|
+
for (const [provName, mod] of Object.entries(providersConfig)) {
|
|
212
|
+
if (!mod)
|
|
213
|
+
continue;
|
|
214
|
+
// Assume default import name from module spec after last '/'
|
|
215
|
+
const baseName = mod.split('/').pop() || 'provider';
|
|
216
|
+
const className = baseName
|
|
217
|
+
.replace(/^[^a-zA-Z_]*/g, '')
|
|
218
|
+
.split(/[-_]/)
|
|
219
|
+
.map(s => s.charAt(0).toUpperCase() + s.slice(1))
|
|
220
|
+
.join('');
|
|
221
|
+
// Only add import if the module path isn't already imported
|
|
222
|
+
if (!appTs.includes(`from '${mod}'`)) {
|
|
223
|
+
importLines.push(`import { ${className}${!isIProviderImported ? ', IProvider, ISqlProvider' : ''} } from '${mod}';`);
|
|
224
|
+
}
|
|
225
|
+
if (!isIProviderImported)
|
|
226
|
+
isIProviderImported = true;
|
|
227
|
+
// Read provider configuration from env by name, parse JSON if possible, pass as is
|
|
228
|
+
providerInitLines.push(` ${provName}: new ${className}((() => {
|
|
229
|
+
const raw = process.env.${provName.toUpperCase()} || '';
|
|
230
|
+
try { return raw ? JSON.parse(raw) : undefined; } catch { return raw; }
|
|
231
|
+
})())`);
|
|
232
|
+
providersArrayEntries.push(provName);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
// Fallback to MySQL provider if no providers configured
|
|
237
|
+
if (!appTs.includes("from '@currentjs/provider-mysql'")) {
|
|
238
|
+
importLines.push(`import { ProviderMysql, IProvider, ISqlProvider } from '@currentjs/provider-mysql';`);
|
|
239
|
+
}
|
|
240
|
+
providerInitLines.push(` mysql: new ProviderMysql((() => {
|
|
241
|
+
const raw = process.env.MYSQL || '';
|
|
242
|
+
try { return raw ? JSON.parse(raw) : undefined; } catch { return raw; }
|
|
243
|
+
})())`);
|
|
244
|
+
providersArrayEntries.push('mysql');
|
|
245
|
+
}
|
|
246
|
+
const dbProviderKey = databaseProviderName || providersArrayEntries[0];
|
|
247
|
+
const ensureDbLine = `const providers: Record<string, IProvider> = {\n${providerInitLines.join(',\n')}\n};\nconst db = providers['${dbProviderKey}'] as ISqlProvider;`;
|
|
248
|
+
// Ensure router imports
|
|
249
|
+
if (!appTs.includes("from '@currentjs/router'")) {
|
|
250
|
+
importLines.push(`import { createWebServer } from '@currentjs/router';`);
|
|
251
|
+
}
|
|
252
|
+
// Add entity imports
|
|
253
|
+
for (const init of controllerInits) {
|
|
254
|
+
const lines = [
|
|
255
|
+
init.importStore,
|
|
256
|
+
init.importService,
|
|
257
|
+
init.importUseCase,
|
|
258
|
+
init.importController
|
|
259
|
+
].filter(line => line && line.trim() !== '');
|
|
260
|
+
for (const line of lines) {
|
|
261
|
+
if (!appTs.includes(line) && !importLines.includes(line)) {
|
|
262
|
+
importLines.push(line);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
if (importLines.length) {
|
|
267
|
+
// Filter out duplicates before prepending
|
|
268
|
+
const existingImports = new Set();
|
|
269
|
+
const importRegex = /^import[^;]+;$/gm;
|
|
270
|
+
const currentImports = appTs.match(importRegex) || [];
|
|
271
|
+
currentImports.forEach(line => existingImports.add(line.trim()));
|
|
272
|
+
const toAdd = importLines.filter(line => !existingImports.has(line.trim()));
|
|
273
|
+
if (toAdd.length)
|
|
274
|
+
appTs = toAdd.join('\n') + '\n' + appTs;
|
|
275
|
+
}
|
|
276
|
+
// Build wiring block
|
|
277
|
+
const wiringLines = [];
|
|
278
|
+
// Providers + DB initialization
|
|
279
|
+
wiringLines.push(ensureDbLine);
|
|
280
|
+
// Store -> Service -> UseCase wiring
|
|
281
|
+
for (const init of controllerInits) {
|
|
282
|
+
const { entityName, entityVar } = init;
|
|
283
|
+
wiringLines.push(`const ${entityVar}Store = new ${entityName}Store(db);`);
|
|
284
|
+
wiringLines.push(`const ${entityVar}Service = new ${entityName}Service(${entityVar}Store);`);
|
|
285
|
+
wiringLines.push(`const ${entityVar}UseCase = new ${entityName}UseCase(${entityVar}Service);`);
|
|
286
|
+
}
|
|
287
|
+
// Controller registrations
|
|
288
|
+
const registrations = controllerInits
|
|
289
|
+
.map(i => i.registration)
|
|
290
|
+
.filter(r => r && r.trim() !== '')
|
|
291
|
+
.join('');
|
|
292
|
+
wiringLines.push('const controllers = [');
|
|
293
|
+
if (registrations) {
|
|
294
|
+
wiringLines.push(` ${registrations.trim()}`);
|
|
295
|
+
}
|
|
296
|
+
wiringLines.push('];');
|
|
297
|
+
// Replace content between markers
|
|
298
|
+
const startMarker = constants_1.GENERATOR_MARKERS.CONTROLLERS_START;
|
|
299
|
+
const endMarker = constants_1.GENERATOR_MARKERS.CONTROLLERS_END;
|
|
300
|
+
const startIdx = appTs.indexOf(startMarker);
|
|
301
|
+
const endIdx = appTs.indexOf(endMarker);
|
|
302
|
+
if (startIdx !== -1 && endIdx !== -1 && endIdx > startIdx) {
|
|
303
|
+
const before = appTs.slice(0, startIdx + startMarker.length);
|
|
304
|
+
const after = appTs.slice(endIdx);
|
|
305
|
+
const block = '\n' + wiringLines.join('\n') + '\n';
|
|
306
|
+
appTs = before + block + after;
|
|
307
|
+
}
|
|
308
|
+
// Deduplicate import lines across the entire file
|
|
309
|
+
const lines = appTs.split('\n');
|
|
310
|
+
const seenImports = new Set();
|
|
311
|
+
const deduped = lines.filter(line => {
|
|
312
|
+
const trimmed = line.trim();
|
|
313
|
+
if (/^import\s+/.test(trimmed) && trimmed.endsWith(';')) {
|
|
314
|
+
if (seenImports.has(trimmed))
|
|
315
|
+
return false;
|
|
316
|
+
seenImports.add(trimmed);
|
|
317
|
+
}
|
|
318
|
+
return true;
|
|
319
|
+
});
|
|
320
|
+
appTs = deduped.join('\n');
|
|
321
|
+
fs.writeFileSync(appTsPath, appTs, 'utf8');
|
|
322
|
+
// eslint-disable-next-line no-console
|
|
323
|
+
console.log(colors_1.colors.green(`Updated ${appTsPath}`));
|
|
324
|
+
}
|
|
325
|
+
catch (e) {
|
|
326
|
+
// eslint-disable-next-line no-console
|
|
327
|
+
console.warn(colors_1.colors.yellow(`Could not update app.ts: ${e instanceof Error ? e.message : String(e)}`));
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
// Run build
|
|
331
|
+
(0, cliUtils_1.runCommand)('npm run build', {
|
|
332
|
+
infoMessage: '\nBuilding...',
|
|
333
|
+
successMessage: '[v] Build completed successfully',
|
|
334
|
+
errorMessage: '[x] Build failed:'
|
|
335
|
+
});
|
|
336
|
+
}
|