fragment-ts 1.0.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/.env.example +0 -0
- package/base.ts +1810 -0
- package/base2.ts +968 -0
- package/bin/frg.ts +5 -0
- package/config/fragment.lock.yaml +0 -0
- package/config/fragment.yaml +0 -0
- package/dist/app.d.ts +15 -0
- package/dist/app.js +90 -0
- package/dist/auth/auth.controller.d.ts +10 -0
- package/dist/auth/auth.controller.js +87 -0
- package/dist/auth/auth.middleware.d.ts +2 -0
- package/dist/auth/auth.middleware.js +24 -0
- package/dist/auth/auth.service.d.ts +20 -0
- package/dist/auth/auth.service.js +143 -0
- package/dist/auth/dto/login.dto.d.ts +9 -0
- package/dist/auth/dto/login.dto.js +2 -0
- package/dist/cli/cli.d.ts +12 -0
- package/dist/cli/cli.js +186 -0
- package/dist/cli/commands/build.command.d.ts +3 -0
- package/dist/cli/commands/build.command.js +23 -0
- package/dist/cli/commands/config.command.d.ts +6 -0
- package/dist/cli/commands/config.command.js +284 -0
- package/dist/cli/commands/generate.command.d.ts +8 -0
- package/dist/cli/commands/generate.command.js +180 -0
- package/dist/cli/commands/init.command.d.ts +7 -0
- package/dist/cli/commands/init.command.js +380 -0
- package/dist/cli/commands/migrate.command.d.ts +7 -0
- package/dist/cli/commands/migrate.command.js +116 -0
- package/dist/cli/commands/serve.command.d.ts +6 -0
- package/dist/cli/commands/serve.command.js +31 -0
- package/dist/cli/templates/controller.template.d.ts +1 -0
- package/dist/cli/templates/controller.template.js +52 -0
- package/dist/cli/templates/entity.template.d.ts +1 -0
- package/dist/cli/templates/entity.template.js +23 -0
- package/dist/cli/templates/repository.template.d.ts +1 -0
- package/dist/cli/templates/repository.template.js +43 -0
- package/dist/cli/templates/service.template.d.ts +1 -0
- package/dist/cli/templates/service.template.js +43 -0
- package/dist/cli/utils/file-generator.d.ts +9 -0
- package/dist/cli/utils/file-generator.js +67 -0
- package/dist/cli/utils/logger.d.ts +14 -0
- package/dist/cli/utils/logger.js +49 -0
- package/dist/controllers/health.controller.d.ts +13 -0
- package/dist/controllers/health.controller.js +50 -0
- package/dist/core/config/config-loader.d.ts +31 -0
- package/dist/core/config/config-loader.js +98 -0
- package/dist/core/container/di-container.d.ts +9 -0
- package/dist/core/container/di-container.js +37 -0
- package/dist/core/decorators/auth-guard.decorator.d.ts +3 -0
- package/dist/core/decorators/auth-guard.decorator.js +18 -0
- package/dist/core/decorators/autowire.decorator.d.ts +3 -0
- package/dist/core/decorators/autowire.decorator.js +17 -0
- package/dist/core/decorators/controller.decorator.d.ts +4 -0
- package/dist/core/decorators/controller.decorator.js +16 -0
- package/dist/core/decorators/injectable.decorator.d.ts +3 -0
- package/dist/core/decorators/injectable.decorator.js +14 -0
- package/dist/core/decorators/middleware.decorator.d.ts +3 -0
- package/dist/core/decorators/middleware.decorator.js +20 -0
- package/dist/core/decorators/repository.decorator.d.ts +1 -0
- package/dist/core/decorators/repository.decorator.js +7 -0
- package/dist/core/decorators/route.decorator.d.ts +14 -0
- package/dist/core/decorators/route.decorator.js +32 -0
- package/dist/core/decorators/service.decorator.d.ts +1 -0
- package/dist/core/decorators/service.decorator.js +7 -0
- package/dist/core/openai/openai-client.d.ts +12 -0
- package/dist/core/openai/openai-client.js +93 -0
- package/dist/database/data-source.d.ts +4 -0
- package/dist/database/data-source.js +26 -0
- package/dist/entities/session.entity.d.ts +9 -0
- package/dist/entities/session.entity.js +45 -0
- package/dist/entities/user.entity.d.ts +10 -0
- package/dist/entities/user.entity.js +48 -0
- package/dist/middlewares/logging.middleware.d.ts +2 -0
- package/dist/middlewares/logging.middleware.js +28 -0
- package/dist/repositories/session.repository.d.ts +9 -0
- package/dist/repositories/session.repository.js +50 -0
- package/dist/repositories/user.repository.d.ts +10 -0
- package/dist/repositories/user.repository.js +43 -0
- package/dist/server.d.ts +1 -0
- package/dist/server.js +30 -0
- package/dist/services/health.service.d.ts +13 -0
- package/dist/services/health.service.js +44 -0
- package/package.json +46 -0
- package/readme.md +120 -0
- package/src/app.ts +121 -0
- package/src/auth/auth.controller.ts +52 -0
- package/src/auth/auth.middleware.ts +27 -0
- package/src/auth/auth.service.ts +110 -0
- package/src/auth/dto/login.dto.ts +11 -0
- package/src/cli/cli.ts +212 -0
- package/src/cli/commands/build.command.ts +24 -0
- package/src/cli/commands/config.command.ts +280 -0
- package/src/cli/commands/generate.command.ts +170 -0
- package/src/cli/commands/init.command.ts +395 -0
- package/src/cli/commands/migrate.command.ts +118 -0
- package/src/cli/commands/serve.command.ts +37 -0
- package/src/cli/templates/controller.template.ts +51 -0
- package/src/cli/templates/entity.template.ts +22 -0
- package/src/cli/templates/repository.template.ts +42 -0
- package/src/cli/templates/service.template.ts +42 -0
- package/src/cli/utils/file-generator.ts +37 -0
- package/src/cli/utils/logger.ts +52 -0
- package/src/controllers/health.controller.ts +24 -0
- package/src/core/config/config-loader.ts +98 -0
- package/src/core/container/di-container.ts +43 -0
- package/src/core/decorators/auth-guard.decorator.ts +15 -0
- package/src/core/decorators/autowire.decorator.ts +18 -0
- package/src/core/decorators/controller.decorator.ts +15 -0
- package/src/core/decorators/injectable.decorator.ts +13 -0
- package/src/core/decorators/middleware.decorator.ts +18 -0
- package/src/core/decorators/repository.decorator.ts +6 -0
- package/src/core/decorators/route.decorator.ts +33 -0
- package/src/core/decorators/service.decorator.ts +6 -0
- package/src/core/openai/openai-client.ts +99 -0
- package/src/database/data-source.ts +29 -0
- package/src/entities/session.entity.ts +25 -0
- package/src/entities/user.entity.ts +27 -0
- package/src/middlewares/logging.middleware.ts +28 -0
- package/src/repositories/session.repository.ts +42 -0
- package/src/repositories/user.repository.ts +37 -0
- package/src/server.ts +32 -0
- package/src/services/health.service.ts +29 -0
- package/tsconfig.json +20 -0
|
@@ -0,0 +1,284 @@
|
|
|
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
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.ConfigCommand = void 0;
|
|
40
|
+
const path = __importStar(require("path"));
|
|
41
|
+
const yaml = __importStar(require("js-yaml"));
|
|
42
|
+
const logger_1 = require("../utils/logger");
|
|
43
|
+
const file_generator_1 = require("../utils/file-generator");
|
|
44
|
+
const inquirer_1 = __importDefault(require("inquirer"));
|
|
45
|
+
class ConfigCommand {
|
|
46
|
+
async execute(target) {
|
|
47
|
+
switch (target) {
|
|
48
|
+
case 'ai':
|
|
49
|
+
await this.configureAI();
|
|
50
|
+
break;
|
|
51
|
+
case 'db':
|
|
52
|
+
case 'database':
|
|
53
|
+
await this.configureDatabase();
|
|
54
|
+
break;
|
|
55
|
+
case 'show':
|
|
56
|
+
await this.showConfig();
|
|
57
|
+
break;
|
|
58
|
+
default:
|
|
59
|
+
logger_1.CLILogger.error(`Unknown config target: ${target}`);
|
|
60
|
+
logger_1.CLILogger.info('Available targets: ai, db, show');
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
async configureAI() {
|
|
64
|
+
logger_1.CLILogger.title('🤖 OpenAI Configuration');
|
|
65
|
+
const answers = await inquirer_1.default.prompt([
|
|
66
|
+
{
|
|
67
|
+
type: 'password',
|
|
68
|
+
name: 'apiKey',
|
|
69
|
+
message: 'OpenAI API Key:',
|
|
70
|
+
mask: '*',
|
|
71
|
+
validate: (input) => {
|
|
72
|
+
if (!input || !input.startsWith('sk-')) {
|
|
73
|
+
return 'Please enter a valid OpenAI API key (starts with sk-)';
|
|
74
|
+
}
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
type: 'list',
|
|
80
|
+
name: 'model',
|
|
81
|
+
message: 'Default model:',
|
|
82
|
+
choices: [
|
|
83
|
+
'gpt-4-turbo',
|
|
84
|
+
'gpt-4',
|
|
85
|
+
'gpt-3.5-turbo',
|
|
86
|
+
'claude-sonnet-4-5-20250929',
|
|
87
|
+
'claude-opus-4-1-20250514'
|
|
88
|
+
],
|
|
89
|
+
default: 'gpt-4'
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
type: 'confirm',
|
|
93
|
+
name: 'saveToEnv',
|
|
94
|
+
message: 'Save API key to .env file?',
|
|
95
|
+
default: true
|
|
96
|
+
}
|
|
97
|
+
]);
|
|
98
|
+
const configPath = path.join(process.cwd(), 'config/fragment.yaml');
|
|
99
|
+
if (!file_generator_1.FileGenerator.fileExists(configPath)) {
|
|
100
|
+
logger_1.CLILogger.error('fragment.yaml not found. Are you in a Fragment project?');
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
try {
|
|
104
|
+
const configContent = file_generator_1.FileGenerator.readFile(configPath);
|
|
105
|
+
const config = yaml.load(configContent);
|
|
106
|
+
if (!config.openai) {
|
|
107
|
+
config.openai = {};
|
|
108
|
+
}
|
|
109
|
+
config.openai.apiKey = answers.saveToEnv ? '${OPENAI_API_KEY}' : answers.apiKey;
|
|
110
|
+
config.openai.model = answers.model;
|
|
111
|
+
file_generator_1.FileGenerator.writeFile(configPath, yaml.dump(config));
|
|
112
|
+
if (answers.saveToEnv) {
|
|
113
|
+
const envPath = path.join(process.cwd(), '.env');
|
|
114
|
+
let envContent = '';
|
|
115
|
+
if (file_generator_1.FileGenerator.fileExists(envPath)) {
|
|
116
|
+
envContent = file_generator_1.FileGenerator.readFile(envPath);
|
|
117
|
+
}
|
|
118
|
+
// Update or add OPENAI_API_KEY
|
|
119
|
+
if (envContent.includes('OPENAI_API_KEY=')) {
|
|
120
|
+
envContent = envContent.replace(/OPENAI_API_KEY=.*/, `OPENAI_API_KEY=${answers.apiKey}`);
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
envContent += `\nOPENAI_API_KEY=${answers.apiKey}`;
|
|
124
|
+
}
|
|
125
|
+
file_generator_1.FileGenerator.writeFile(envPath, envContent);
|
|
126
|
+
logger_1.CLILogger.success('API key saved to .env file');
|
|
127
|
+
}
|
|
128
|
+
logger_1.CLILogger.success('OpenAI configuration updated');
|
|
129
|
+
logger_1.CLILogger.table({
|
|
130
|
+
'Model': answers.model,
|
|
131
|
+
'API Key': answers.saveToEnv ? 'Stored in .env' : 'Stored in config'
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
logger_1.CLILogger.error(`Failed to update configuration: ${error.message}`);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
async configureDatabase() {
|
|
139
|
+
logger_1.CLILogger.title('🗄️ Database Configuration');
|
|
140
|
+
const answers = await inquirer_1.default.prompt([
|
|
141
|
+
{
|
|
142
|
+
type: 'list',
|
|
143
|
+
name: 'type',
|
|
144
|
+
message: 'Database type:',
|
|
145
|
+
choices: ['postgres', 'mysql', 'sqlite', 'mongodb']
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
type: 'input',
|
|
149
|
+
name: 'host',
|
|
150
|
+
message: 'Host:',
|
|
151
|
+
default: 'localhost',
|
|
152
|
+
when: (answers) => answers.type !== 'sqlite'
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
type: 'input',
|
|
156
|
+
name: 'port',
|
|
157
|
+
message: 'Port:',
|
|
158
|
+
default: (answers) => {
|
|
159
|
+
const ports = { postgres: 5432, mysql: 3306, mongodb: 27017 };
|
|
160
|
+
return ports[answers.type] || 5432;
|
|
161
|
+
},
|
|
162
|
+
when: (answers) => answers.type !== 'sqlite'
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
type: 'input',
|
|
166
|
+
name: 'username',
|
|
167
|
+
message: 'Username:',
|
|
168
|
+
default: (answers) => answers.type === 'postgres' ? 'postgres' : 'root',
|
|
169
|
+
when: (answers) => answers.type !== 'sqlite'
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
type: 'password',
|
|
173
|
+
name: 'password',
|
|
174
|
+
message: 'Password:',
|
|
175
|
+
mask: '*',
|
|
176
|
+
when: (answers) => answers.type !== 'sqlite'
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
type: 'input',
|
|
180
|
+
name: 'database',
|
|
181
|
+
message: 'Database name:',
|
|
182
|
+
default: 'fragment_db'
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
type: 'confirm',
|
|
186
|
+
name: 'synchronize',
|
|
187
|
+
message: 'Auto-synchronize schema? (not recommended for production)',
|
|
188
|
+
default: true
|
|
189
|
+
}
|
|
190
|
+
]);
|
|
191
|
+
const configPath = path.join(process.cwd(), 'config/fragment.yaml');
|
|
192
|
+
try {
|
|
193
|
+
const configContent = file_generator_1.FileGenerator.readFile(configPath);
|
|
194
|
+
const config = yaml.load(configContent);
|
|
195
|
+
config.database = {
|
|
196
|
+
type: answers.type,
|
|
197
|
+
...(answers.type !== 'sqlite' && {
|
|
198
|
+
host: '${DB_HOST:' + answers.host + '}',
|
|
199
|
+
port: '${DB_PORT:' + answers.port + '}',
|
|
200
|
+
username: '${DB_USERNAME:' + answers.username + '}',
|
|
201
|
+
password: '${DB_PASSWORD}'
|
|
202
|
+
}),
|
|
203
|
+
database: '${DB_DATABASE:' + answers.database + '}',
|
|
204
|
+
synchronize: answers.synchronize,
|
|
205
|
+
logging: false
|
|
206
|
+
};
|
|
207
|
+
file_generator_1.FileGenerator.writeFile(configPath, yaml.dump(config));
|
|
208
|
+
// Update .env
|
|
209
|
+
const envPath = path.join(process.cwd(), '.env');
|
|
210
|
+
let envContent = file_generator_1.FileGenerator.fileExists(envPath) ? file_generator_1.FileGenerator.readFile(envPath) : '';
|
|
211
|
+
const envVars = {
|
|
212
|
+
DB_HOST: answers.host,
|
|
213
|
+
DB_PORT: answers.port,
|
|
214
|
+
DB_USERNAME: answers.username,
|
|
215
|
+
DB_PASSWORD: answers.password,
|
|
216
|
+
DB_DATABASE: answers.database
|
|
217
|
+
};
|
|
218
|
+
Object.entries(envVars).forEach(([key, value]) => {
|
|
219
|
+
if (value !== undefined) {
|
|
220
|
+
if (envContent.includes(`${key}=`)) {
|
|
221
|
+
envContent = envContent.replace(new RegExp(`${key}=.*`), `${key}=${value}`);
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
envContent += `\n${key}=${value}`;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
file_generator_1.FileGenerator.writeFile(envPath, envContent.trim());
|
|
229
|
+
logger_1.CLILogger.success('Database configuration updated');
|
|
230
|
+
logger_1.CLILogger.table({
|
|
231
|
+
'Type': answers.type,
|
|
232
|
+
'Host': answers.host || 'N/A',
|
|
233
|
+
'Database': answers.database,
|
|
234
|
+
'Synchronize': answers.synchronize ? 'Yes' : 'No'
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
catch (error) {
|
|
238
|
+
logger_1.CLILogger.error(`Failed to update configuration: ${error.message}`);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
async showConfig() {
|
|
242
|
+
logger_1.CLILogger.title('📋 Current Configuration');
|
|
243
|
+
const configPath = path.join(process.cwd(), 'config/fragment.yaml');
|
|
244
|
+
if (!file_generator_1.FileGenerator.fileExists(configPath)) {
|
|
245
|
+
logger_1.CLILogger.error('fragment.yaml not found');
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
try {
|
|
249
|
+
const configContent = file_generator_1.FileGenerator.readFile(configPath);
|
|
250
|
+
const config = yaml.load(configContent);
|
|
251
|
+
logger_1.CLILogger.section('Application');
|
|
252
|
+
logger_1.CLILogger.table({
|
|
253
|
+
'Name': config.app?.name || 'N/A',
|
|
254
|
+
'Port': config.app?.port || 'N/A',
|
|
255
|
+
'Environment': config.app?.env || 'N/A'
|
|
256
|
+
});
|
|
257
|
+
logger_1.CLILogger.section('Database');
|
|
258
|
+
logger_1.CLILogger.table({
|
|
259
|
+
'Type': config.database?.type || 'N/A',
|
|
260
|
+
'Host': config.database?.host || 'N/A',
|
|
261
|
+
'Database': config.database?.database || 'N/A',
|
|
262
|
+
'Synchronize': config.database?.synchronize ? 'Yes' : 'No'
|
|
263
|
+
});
|
|
264
|
+
if (config.openai) {
|
|
265
|
+
logger_1.CLILogger.section('OpenAI');
|
|
266
|
+
logger_1.CLILogger.table({
|
|
267
|
+
'Model': config.openai.model || 'N/A',
|
|
268
|
+
'API Key': config.openai.apiKey?.includes('${') ? 'From environment' : 'Configured'
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
if (config.auth) {
|
|
272
|
+
logger_1.CLILogger.section('Authentication');
|
|
273
|
+
logger_1.CLILogger.table({
|
|
274
|
+
'Token Expiry': config.auth.tokenExpiry || 'N/A',
|
|
275
|
+
'Session Expiry': config.auth.sessionExpiry || 'N/A'
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
catch (error) {
|
|
280
|
+
logger_1.CLILogger.error(`Failed to read configuration: ${error.message}`);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
exports.ConfigCommand = ConfigCommand;
|
|
@@ -0,0 +1,180 @@
|
|
|
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
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.GenerateCommand = void 0;
|
|
40
|
+
const path = __importStar(require("path"));
|
|
41
|
+
const logger_1 = require("../utils/logger");
|
|
42
|
+
const file_generator_1 = require("../utils/file-generator");
|
|
43
|
+
const inquirer_1 = __importDefault(require("inquirer"));
|
|
44
|
+
const controller_template_1 = require("../templates/controller.template");
|
|
45
|
+
const entity_template_1 = require("../templates/entity.template");
|
|
46
|
+
const repository_template_1 = require("../templates/repository.template");
|
|
47
|
+
const service_template_1 = require("../templates/service.template");
|
|
48
|
+
class GenerateCommand {
|
|
49
|
+
async execute(type, name) {
|
|
50
|
+
if (!name) {
|
|
51
|
+
const answer = await inquirer_1.default.prompt([
|
|
52
|
+
{
|
|
53
|
+
type: 'input',
|
|
54
|
+
name: 'name',
|
|
55
|
+
message: `Enter ${type} name:`,
|
|
56
|
+
validate: (input) => {
|
|
57
|
+
if (!input)
|
|
58
|
+
return 'Name is required';
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
]);
|
|
63
|
+
name = answer.name;
|
|
64
|
+
}
|
|
65
|
+
const pascalName = file_generator_1.FileGenerator.toPascalCase(name);
|
|
66
|
+
const kebabName = file_generator_1.FileGenerator.toKebabCase(name);
|
|
67
|
+
switch (type) {
|
|
68
|
+
case 'controller':
|
|
69
|
+
await this.generateController(pascalName, kebabName);
|
|
70
|
+
break;
|
|
71
|
+
case 'service':
|
|
72
|
+
await this.generateService(pascalName, kebabName);
|
|
73
|
+
break;
|
|
74
|
+
case 'repository':
|
|
75
|
+
await this.generateRepository(pascalName, kebabName);
|
|
76
|
+
break;
|
|
77
|
+
case 'entity':
|
|
78
|
+
await this.generateEntity(pascalName, kebabName);
|
|
79
|
+
break;
|
|
80
|
+
case 'resource':
|
|
81
|
+
await this.generateResource(pascalName, kebabName);
|
|
82
|
+
break;
|
|
83
|
+
default:
|
|
84
|
+
logger_1.CLILogger.error(`Unknown type: ${type}`);
|
|
85
|
+
logger_1.CLILogger.info('Available types: controller, service, repository, entity, resource');
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
async generateController(name, fileName) {
|
|
89
|
+
const answers = await inquirer_1.default.prompt([
|
|
90
|
+
{
|
|
91
|
+
type: 'input',
|
|
92
|
+
name: 'route',
|
|
93
|
+
message: 'Route path:',
|
|
94
|
+
default: `/api/${fileName}s`
|
|
95
|
+
}
|
|
96
|
+
]);
|
|
97
|
+
const filePath = path.join(process.cwd(), 'src/controllers', `${fileName}.controller.ts`);
|
|
98
|
+
if (file_generator_1.FileGenerator.fileExists(filePath)) {
|
|
99
|
+
logger_1.CLILogger.error(`Controller ${name} already exists`);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
const content = (0, controller_template_1.controllerTemplate)(name, answers.route);
|
|
103
|
+
file_generator_1.FileGenerator.writeFile(filePath, content);
|
|
104
|
+
logger_1.CLILogger.success(`Controller created: src/controllers/${fileName}.controller.ts`);
|
|
105
|
+
logger_1.CLILogger.info(`Route: ${answers.route}`);
|
|
106
|
+
}
|
|
107
|
+
async generateService(name, fileName) {
|
|
108
|
+
const filePath = path.join(process.cwd(), 'src/services', `${fileName}.service.ts`);
|
|
109
|
+
if (file_generator_1.FileGenerator.fileExists(filePath)) {
|
|
110
|
+
logger_1.CLILogger.error(`Service ${name} already exists`);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const content = (0, service_template_1.serviceTemplate)(name);
|
|
114
|
+
file_generator_1.FileGenerator.writeFile(filePath, content);
|
|
115
|
+
logger_1.CLILogger.success(`Service created: src/services/${fileName}.service.ts`);
|
|
116
|
+
}
|
|
117
|
+
async generateRepository(name, fileName) {
|
|
118
|
+
const answers = await inquirer_1.default.prompt([
|
|
119
|
+
{
|
|
120
|
+
type: 'input',
|
|
121
|
+
name: 'entity',
|
|
122
|
+
message: 'Entity name:',
|
|
123
|
+
default: name.replace('Repository', '')
|
|
124
|
+
}
|
|
125
|
+
]);
|
|
126
|
+
const filePath = path.join(process.cwd(), 'src/repositories', `${fileName}.repository.ts`);
|
|
127
|
+
if (file_generator_1.FileGenerator.fileExists(filePath)) {
|
|
128
|
+
logger_1.CLILogger.error(`Repository ${name} already exists`);
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
const content = (0, repository_template_1.repositoryTemplate)(name, answers.entity);
|
|
132
|
+
file_generator_1.FileGenerator.writeFile(filePath, content);
|
|
133
|
+
logger_1.CLILogger.success(`Repository created: src/repositories/${fileName}.repository.ts`);
|
|
134
|
+
}
|
|
135
|
+
async generateEntity(name, fileName) {
|
|
136
|
+
const filePath = path.join(process.cwd(), 'src/entities', `${fileName}.entity.ts`);
|
|
137
|
+
if (file_generator_1.FileGenerator.fileExists(filePath)) {
|
|
138
|
+
logger_1.CLILogger.error(`Entity ${name} already exists`);
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
const content = (0, entity_template_1.entityTemplate)(name);
|
|
142
|
+
file_generator_1.FileGenerator.writeFile(filePath, content);
|
|
143
|
+
logger_1.CLILogger.success(`Entity created: src/entities/${fileName}.entity.ts`);
|
|
144
|
+
}
|
|
145
|
+
async generateResource(name, fileName) {
|
|
146
|
+
logger_1.CLILogger.title(`🔷 Generating resource: ${name}`);
|
|
147
|
+
const spinner = logger_1.CLILogger.spinner('Generating files...');
|
|
148
|
+
try {
|
|
149
|
+
// Generate entity
|
|
150
|
+
const entityPath = path.join(process.cwd(), 'src/entities', `${fileName}.entity.ts`);
|
|
151
|
+
file_generator_1.FileGenerator.writeFile(entityPath, (0, entity_template_1.entityTemplate)(name));
|
|
152
|
+
spinner.text = 'Entity created...';
|
|
153
|
+
// Generate repository
|
|
154
|
+
const repoPath = path.join(process.cwd(), 'src/repositories', `${fileName}.repository.ts`);
|
|
155
|
+
file_generator_1.FileGenerator.writeFile(repoPath, (0, repository_template_1.repositoryTemplate)(name + 'Repository', name));
|
|
156
|
+
spinner.text = 'Repository created...';
|
|
157
|
+
// Generate service
|
|
158
|
+
const servicePath = path.join(process.cwd(), 'src/services', `${fileName}.service.ts`);
|
|
159
|
+
file_generator_1.FileGenerator.writeFile(servicePath, (0, service_template_1.serviceTemplate)(name + 'Service'));
|
|
160
|
+
spinner.text = 'Service created...';
|
|
161
|
+
// Generate controller
|
|
162
|
+
const controllerPath = path.join(process.cwd(), 'src/controllers', `${fileName}.controller.ts`);
|
|
163
|
+
file_generator_1.FileGenerator.writeFile(controllerPath, (0, controller_template_1.controllerTemplate)(name + 'Controller', `/api/${fileName}s`));
|
|
164
|
+
spinner.text = 'Controller created...';
|
|
165
|
+
spinner.succeed('Resource generated successfully');
|
|
166
|
+
logger_1.CLILogger.box('📦 Generated Files', [
|
|
167
|
+
`Entity: src/entities/${fileName}.entity.ts`,
|
|
168
|
+
`Repository: src/repositories/${fileName}.repository.ts`,
|
|
169
|
+
`Service: src/services/${fileName}.service.ts`,
|
|
170
|
+
`Controller: src/controllers/${fileName}.controller.ts`
|
|
171
|
+
]);
|
|
172
|
+
logger_1.CLILogger.info(`\nRoute available at: /api/${fileName}s`);
|
|
173
|
+
}
|
|
174
|
+
catch (error) {
|
|
175
|
+
spinner.fail('Failed to generate resource');
|
|
176
|
+
logger_1.CLILogger.error(error.message);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
exports.GenerateCommand = GenerateCommand;
|