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.
Files changed (123) hide show
  1. package/.env.example +0 -0
  2. package/base.ts +1810 -0
  3. package/base2.ts +968 -0
  4. package/bin/frg.ts +5 -0
  5. package/config/fragment.lock.yaml +0 -0
  6. package/config/fragment.yaml +0 -0
  7. package/dist/app.d.ts +15 -0
  8. package/dist/app.js +90 -0
  9. package/dist/auth/auth.controller.d.ts +10 -0
  10. package/dist/auth/auth.controller.js +87 -0
  11. package/dist/auth/auth.middleware.d.ts +2 -0
  12. package/dist/auth/auth.middleware.js +24 -0
  13. package/dist/auth/auth.service.d.ts +20 -0
  14. package/dist/auth/auth.service.js +143 -0
  15. package/dist/auth/dto/login.dto.d.ts +9 -0
  16. package/dist/auth/dto/login.dto.js +2 -0
  17. package/dist/cli/cli.d.ts +12 -0
  18. package/dist/cli/cli.js +186 -0
  19. package/dist/cli/commands/build.command.d.ts +3 -0
  20. package/dist/cli/commands/build.command.js +23 -0
  21. package/dist/cli/commands/config.command.d.ts +6 -0
  22. package/dist/cli/commands/config.command.js +284 -0
  23. package/dist/cli/commands/generate.command.d.ts +8 -0
  24. package/dist/cli/commands/generate.command.js +180 -0
  25. package/dist/cli/commands/init.command.d.ts +7 -0
  26. package/dist/cli/commands/init.command.js +380 -0
  27. package/dist/cli/commands/migrate.command.d.ts +7 -0
  28. package/dist/cli/commands/migrate.command.js +116 -0
  29. package/dist/cli/commands/serve.command.d.ts +6 -0
  30. package/dist/cli/commands/serve.command.js +31 -0
  31. package/dist/cli/templates/controller.template.d.ts +1 -0
  32. package/dist/cli/templates/controller.template.js +52 -0
  33. package/dist/cli/templates/entity.template.d.ts +1 -0
  34. package/dist/cli/templates/entity.template.js +23 -0
  35. package/dist/cli/templates/repository.template.d.ts +1 -0
  36. package/dist/cli/templates/repository.template.js +43 -0
  37. package/dist/cli/templates/service.template.d.ts +1 -0
  38. package/dist/cli/templates/service.template.js +43 -0
  39. package/dist/cli/utils/file-generator.d.ts +9 -0
  40. package/dist/cli/utils/file-generator.js +67 -0
  41. package/dist/cli/utils/logger.d.ts +14 -0
  42. package/dist/cli/utils/logger.js +49 -0
  43. package/dist/controllers/health.controller.d.ts +13 -0
  44. package/dist/controllers/health.controller.js +50 -0
  45. package/dist/core/config/config-loader.d.ts +31 -0
  46. package/dist/core/config/config-loader.js +98 -0
  47. package/dist/core/container/di-container.d.ts +9 -0
  48. package/dist/core/container/di-container.js +37 -0
  49. package/dist/core/decorators/auth-guard.decorator.d.ts +3 -0
  50. package/dist/core/decorators/auth-guard.decorator.js +18 -0
  51. package/dist/core/decorators/autowire.decorator.d.ts +3 -0
  52. package/dist/core/decorators/autowire.decorator.js +17 -0
  53. package/dist/core/decorators/controller.decorator.d.ts +4 -0
  54. package/dist/core/decorators/controller.decorator.js +16 -0
  55. package/dist/core/decorators/injectable.decorator.d.ts +3 -0
  56. package/dist/core/decorators/injectable.decorator.js +14 -0
  57. package/dist/core/decorators/middleware.decorator.d.ts +3 -0
  58. package/dist/core/decorators/middleware.decorator.js +20 -0
  59. package/dist/core/decorators/repository.decorator.d.ts +1 -0
  60. package/dist/core/decorators/repository.decorator.js +7 -0
  61. package/dist/core/decorators/route.decorator.d.ts +14 -0
  62. package/dist/core/decorators/route.decorator.js +32 -0
  63. package/dist/core/decorators/service.decorator.d.ts +1 -0
  64. package/dist/core/decorators/service.decorator.js +7 -0
  65. package/dist/core/openai/openai-client.d.ts +12 -0
  66. package/dist/core/openai/openai-client.js +93 -0
  67. package/dist/database/data-source.d.ts +4 -0
  68. package/dist/database/data-source.js +26 -0
  69. package/dist/entities/session.entity.d.ts +9 -0
  70. package/dist/entities/session.entity.js +45 -0
  71. package/dist/entities/user.entity.d.ts +10 -0
  72. package/dist/entities/user.entity.js +48 -0
  73. package/dist/middlewares/logging.middleware.d.ts +2 -0
  74. package/dist/middlewares/logging.middleware.js +28 -0
  75. package/dist/repositories/session.repository.d.ts +9 -0
  76. package/dist/repositories/session.repository.js +50 -0
  77. package/dist/repositories/user.repository.d.ts +10 -0
  78. package/dist/repositories/user.repository.js +43 -0
  79. package/dist/server.d.ts +1 -0
  80. package/dist/server.js +30 -0
  81. package/dist/services/health.service.d.ts +13 -0
  82. package/dist/services/health.service.js +44 -0
  83. package/package.json +46 -0
  84. package/readme.md +120 -0
  85. package/src/app.ts +121 -0
  86. package/src/auth/auth.controller.ts +52 -0
  87. package/src/auth/auth.middleware.ts +27 -0
  88. package/src/auth/auth.service.ts +110 -0
  89. package/src/auth/dto/login.dto.ts +11 -0
  90. package/src/cli/cli.ts +212 -0
  91. package/src/cli/commands/build.command.ts +24 -0
  92. package/src/cli/commands/config.command.ts +280 -0
  93. package/src/cli/commands/generate.command.ts +170 -0
  94. package/src/cli/commands/init.command.ts +395 -0
  95. package/src/cli/commands/migrate.command.ts +118 -0
  96. package/src/cli/commands/serve.command.ts +37 -0
  97. package/src/cli/templates/controller.template.ts +51 -0
  98. package/src/cli/templates/entity.template.ts +22 -0
  99. package/src/cli/templates/repository.template.ts +42 -0
  100. package/src/cli/templates/service.template.ts +42 -0
  101. package/src/cli/utils/file-generator.ts +37 -0
  102. package/src/cli/utils/logger.ts +52 -0
  103. package/src/controllers/health.controller.ts +24 -0
  104. package/src/core/config/config-loader.ts +98 -0
  105. package/src/core/container/di-container.ts +43 -0
  106. package/src/core/decorators/auth-guard.decorator.ts +15 -0
  107. package/src/core/decorators/autowire.decorator.ts +18 -0
  108. package/src/core/decorators/controller.decorator.ts +15 -0
  109. package/src/core/decorators/injectable.decorator.ts +13 -0
  110. package/src/core/decorators/middleware.decorator.ts +18 -0
  111. package/src/core/decorators/repository.decorator.ts +6 -0
  112. package/src/core/decorators/route.decorator.ts +33 -0
  113. package/src/core/decorators/service.decorator.ts +6 -0
  114. package/src/core/openai/openai-client.ts +99 -0
  115. package/src/database/data-source.ts +29 -0
  116. package/src/entities/session.entity.ts +25 -0
  117. package/src/entities/user.entity.ts +27 -0
  118. package/src/middlewares/logging.middleware.ts +28 -0
  119. package/src/repositories/session.repository.ts +42 -0
  120. package/src/repositories/user.repository.ts +37 -0
  121. package/src/server.ts +32 -0
  122. package/src/services/health.service.ts +29 -0
  123. 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,8 @@
1
+ export declare class GenerateCommand {
2
+ execute(type: string, name?: string): Promise<void>;
3
+ private generateController;
4
+ private generateService;
5
+ private generateRepository;
6
+ private generateEntity;
7
+ private generateResource;
8
+ }
@@ -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;
@@ -0,0 +1,7 @@
1
+ export declare class InitCommand {
2
+ execute(projectName?: string): Promise<void>;
3
+ private getDatabaseConfig;
4
+ private getEnvTemplate;
5
+ private generateReadme;
6
+ private copyFrameworkCore;
7
+ }