micro-generate 1.0.7 → 1.2.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/README.md +38 -8
- package/dist/cli/generators/feature-generator.js +261 -34
- package/dist/cli/generators/feature-generator.js.map +1 -1
- package/dist/cli/generators/graphql-generator.d.ts +7 -2
- package/dist/cli/generators/graphql-generator.js +23 -14
- package/dist/cli/generators/graphql-generator.js.map +1 -1
- package/dist/cli/generators/init-generator.js +250 -2
- package/dist/cli/generators/init-generator.js.map +1 -1
- package/dist/cli/index.js +106 -16
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/utils/types.d.ts +6 -0
- package/dist/config/env.d.ts +2 -2
- package/dist/core/MicroserviceServer.d.ts +4 -0
- package/dist/core/MicroserviceServer.js +10 -3
- package/dist/core/MicroserviceServer.js.map +1 -1
- package/dist/database/mongo.d.ts +41 -0
- package/dist/database/mongo.js +127 -0
- package/dist/database/mongo.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/package.json +9 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# 🚀 Microservice Generator (`micro-generate`)
|
|
2
2
|
|
|
3
|
-
**`micro-generate`** es un CLI potente y ligero para crear microservicios listos para producción con **Node.js, TypeScript, GraphQL (Apollo Server), MongoDB y Redis**.
|
|
3
|
+
**`micro-generate`** es un CLI potente y ligero para crear microservicios listos para producción con **Node.js, TypeScript, GraphQL (Apollo Server), MongoDB, MySQL (Sequelize) y Redis**.
|
|
4
4
|
|
|
5
5
|
Olvídate del boilerplate. Genera infraestructuras completas, features modulares, queries y mutaciones en segundos con una arquitectura escalable y las mejores prácticas integradas.
|
|
6
6
|
|
|
@@ -24,8 +24,13 @@ Crea la estructura base del microservicio, configurando TypeScript, Docker, Vari
|
|
|
24
24
|
```bash
|
|
25
25
|
npx micro-generate init
|
|
26
26
|
```
|
|
27
|
-
* **Interactivo:** Te preguntará el nombre del proyecto y
|
|
28
|
-
* **
|
|
27
|
+
* **Interactivo:** Te preguntará el nombre del proyecto y qué tecnologias habilitar:
|
|
28
|
+
* **MongoDB**: Soporte nativo con Mongoose.
|
|
29
|
+
* **Multi-DB**: Posibilidad de añadir múltiples bases de datos MongoDB (ej: `users`, `logs`).
|
|
30
|
+
* **MySQL**: Soporte completo con **Sequelize**.
|
|
31
|
+
* **Multi-DB MySQL**: Posibilidad de añadir múltiples bases de datos MySQL.
|
|
32
|
+
* **Redis**: Cliente para caching y pub/sub.
|
|
33
|
+
* **Resultado:** Un proyecto completo con `src/core`, `src/config`, `src/db` y todo listo para correr `npm run dev`.
|
|
29
34
|
|
|
30
35
|
### 2. Crear una Nueva Feature
|
|
31
36
|
Genera un módulo de dominio completo (Vertical Slice Architecture).
|
|
@@ -34,11 +39,15 @@ Genera un módulo de dominio completo (Vertical Slice Architecture).
|
|
|
34
39
|
npx micro-generate feature
|
|
35
40
|
```
|
|
36
41
|
* **Te pedirá:** Nombre del feature (ej: `users`, `orders`).
|
|
42
|
+
* **Tecnologías:** Puedes seleccionar si la feature usa MongoDB, MySQL o Redis.
|
|
43
|
+
* **Multi-DB:** Si tienes múltiples bases de datos:
|
|
44
|
+
* **MongoDB**: Te preguntará a cuál colección conectar (ej: `users`).
|
|
45
|
+
* **MySQL**: Te preguntará por separado a cuál base de datos conectar (ej: `archive`).
|
|
37
46
|
* **Genera:** Carpeta en `src/features/<nombre>` con:
|
|
38
47
|
* `typeDefs.ts`: Esquemas GraphQL.
|
|
39
48
|
* `resolvers.ts`: Controladores.
|
|
40
|
-
* `service.ts`: Lógica de negocio.
|
|
41
|
-
* `model.ts`: Modelo Mongoose
|
|
49
|
+
* `service.ts`: Lógica de negocio (con inyección del modelo correcto).
|
|
50
|
+
* `model.ts`: Modelo Mongoose o Sequelize (según selección).
|
|
42
51
|
* **Automático:** Registra la feature en el `index.ts` principal.
|
|
43
52
|
|
|
44
53
|
### 3. Agregar una Query (Consulta)
|
|
@@ -58,16 +67,33 @@ npx micro-generate mutation
|
|
|
58
67
|
```
|
|
59
68
|
* Similar a `query`, ideal para operaciones de creación, actualización o eliminación (CRUD).
|
|
60
69
|
|
|
70
|
+
### 5. 🤖 Modo Automatizado (Headless / CI/CD)
|
|
71
|
+
Todos los comandos soportan ejecución no interactiva mediante flags, ideal para scripts o Agentes de IA.
|
|
72
|
+
|
|
73
|
+
**Ejemplos:**
|
|
74
|
+
```bash
|
|
75
|
+
# Crear feature con MySQL y Redis conectada a DB 'logs'
|
|
76
|
+
npx micro-generate feature --name "notifications" --mysql --redis --mysql-connection "logs"
|
|
77
|
+
|
|
78
|
+
# Agregar Query a feature existente
|
|
79
|
+
npx micro-generate query --feature "users" --name "getUserByEmail" --return-type "User"
|
|
80
|
+
```
|
|
81
|
+
|
|
61
82
|
---
|
|
62
83
|
|
|
84
|
+
## 🧠 IA & Agent Ready
|
|
85
|
+
Cada proyecto generado incluye automáticamente una **Skill de Antigravity** en `.agent/skills/micro-generate`.
|
|
86
|
+
Esto permite que agentes de IA (como Antigravity o Cline) puedan leer las instrucciones y **manipular el proyecto por ti** usando los comandos del CLI.
|
|
87
|
+
|
|
63
88
|
## 🔥 Características Principales
|
|
64
89
|
|
|
65
90
|
* **⚡ Stack Moderno**: Node.js 20+, TypeScript 5, Apollo Server 4.
|
|
66
91
|
* **🧠 GraphQL Modular**: Arquitectura basada en features autotencidos.
|
|
67
92
|
* **🛡️ Type-Safety**: Validación de variables de entorno con `Zod`.
|
|
68
93
|
* **🗄️ Bases de Datos**:
|
|
69
|
-
* **MongoDB** (Mongoose)
|
|
70
|
-
* **
|
|
94
|
+
* **MongoDB** (Mongoose): Conexiones primarias y secundarias automáticas.
|
|
95
|
+
* **MySQL** (Sequelize): Integración completa ORM con soporte multi-schema/multi-db.
|
|
96
|
+
* **Redis** (ioredis): Patrón Repository incluido para manejo de caché.
|
|
71
97
|
* **📝 Logging**: Implementación de alto rendimiento con **Pino** (JSON logs).
|
|
72
98
|
* **🛑 Graceful Shutdown**: Manejo correcto de señales SIGINT/SIGTERM para evitar conexiones colgadas.
|
|
73
99
|
* **🎮 Playground Control**: Habilita/deshabilita el Apollo Sandbox vía variables de entorno.
|
|
@@ -79,6 +105,10 @@ my-service/
|
|
|
79
105
|
├── src/
|
|
80
106
|
│ ├── config/ # Configuración de entorno y DBs
|
|
81
107
|
│ ├── core/ # Servidor central (MicroserviceServer)
|
|
108
|
+
│ ├── db/ # Clientes de base de datos
|
|
109
|
+
│ │ ├── mongo/ # Cliente y modelos MongoDB
|
|
110
|
+
│ │ ├── mysql/ # Cliente y modelos Sequelize
|
|
111
|
+
│ │ └── redis/ # Cliente y repositorio Redis
|
|
82
112
|
│ ├── features/ # Tu lógica de negocio aquí
|
|
83
113
|
│ │ ├── users/ # Ejemplo de Feature
|
|
84
114
|
│ │ │ ├── typeDefs.ts
|
|
@@ -101,4 +131,4 @@ my-service/
|
|
|
101
131
|
5. Abre un Pull Request.
|
|
102
132
|
|
|
103
133
|
---
|
|
104
|
-
Generado con ❤️ por `
|
|
134
|
+
Generado con ❤️ por `Jesus Leiva`.
|
|
@@ -1,8 +1,159 @@
|
|
|
1
1
|
import fs from 'fs-extra';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import chalk from 'chalk';
|
|
4
|
+
// Helper for generating Mongo model content
|
|
5
|
+
async function generateModel(options) {
|
|
6
|
+
const { entityName, featurePath, dbConnectionName } = options;
|
|
7
|
+
const projectRoot = path.resolve(featurePath, '../../..'); // Up from src/features/[featureName] to root
|
|
8
|
+
const modelsPath = path.join(projectRoot, 'src', 'db', 'mongo', 'models');
|
|
9
|
+
// Ensure models folder exists
|
|
10
|
+
await fs.ensureDir(modelsPath);
|
|
11
|
+
const toPascalCase = (s) => s.charAt(0).toUpperCase() + s.slice(1);
|
|
12
|
+
const toKebabCase = (s) => s.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();
|
|
13
|
+
// Simple pluralizer fallback
|
|
14
|
+
const pluralize = (s) => s.endsWith('s') ? s : s + 's';
|
|
15
|
+
const modelName = toPascalCase(entityName);
|
|
16
|
+
const fileName = `${toKebabCase(entityName)}.model.ts`;
|
|
17
|
+
const collectionName = pluralize(entityName).toLowerCase();
|
|
18
|
+
let modelContent = '';
|
|
19
|
+
if (dbConnectionName) {
|
|
20
|
+
// SECONDARY CONNECTION: Export function to get model (lazy loading)
|
|
21
|
+
modelContent = `import { Schema, Document, Model } from 'mongoose';
|
|
22
|
+
import { getSecondaryConnection } from '../../../db/mongo/client.js';
|
|
23
|
+
|
|
24
|
+
export interface I${modelName} extends Document {
|
|
25
|
+
createdAt: Date;
|
|
26
|
+
updatedAt: Date;
|
|
27
|
+
// TODO: Add your custom fields here
|
|
28
|
+
[key: string]: any;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const ${modelName}Schema: Schema = new Schema({
|
|
32
|
+
// TODO: Define your schema fields
|
|
33
|
+
}, {
|
|
34
|
+
timestamps: true,
|
|
35
|
+
collection: '${collectionName}'
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
let ${modelName}Model: Model<I${modelName}>;
|
|
39
|
+
|
|
40
|
+
export function get${modelName}Model(): Model<I${modelName}> {
|
|
41
|
+
if (${modelName}Model) return ${modelName}Model;
|
|
42
|
+
|
|
43
|
+
const connection = getSecondaryConnection('${dbConnectionName}');
|
|
44
|
+
if (!connection) {
|
|
45
|
+
throw new Error('Database connection "${dbConnectionName}" not found');
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
${modelName}Model = connection.model<I${modelName}>('${modelName}', ${modelName}Schema);
|
|
49
|
+
return ${modelName}Model;
|
|
50
|
+
}
|
|
51
|
+
`;
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
// DEFAULT CONNECTION: Export model directly
|
|
55
|
+
modelContent = `import mongoose, { Schema, Document } from 'mongoose';
|
|
56
|
+
|
|
57
|
+
export interface I${modelName} extends Document {
|
|
58
|
+
createdAt: Date;
|
|
59
|
+
updatedAt: Date;
|
|
60
|
+
// TODO: Add your custom fields here
|
|
61
|
+
[key: string]: any;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const ${modelName}Schema: Schema = new Schema({
|
|
65
|
+
// TODO: Define your schema fields
|
|
66
|
+
}, {
|
|
67
|
+
timestamps: true,
|
|
68
|
+
collection: '${collectionName}'
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
export const ${modelName}Model = mongoose.model<I${modelName}>('${modelName}', ${modelName}Schema);
|
|
72
|
+
`;
|
|
73
|
+
}
|
|
74
|
+
const filePath = path.join(modelsPath, fileName);
|
|
75
|
+
await fs.writeFile(filePath, modelContent);
|
|
76
|
+
return fileName; // Return filename to use in service import
|
|
77
|
+
}
|
|
78
|
+
// Helper for generating MySQL (Sequelize) model content
|
|
79
|
+
async function generateMySQLModel(options) {
|
|
80
|
+
const { entityName, featurePath, dbConnectionName } = options;
|
|
81
|
+
const projectRoot = path.resolve(featurePath, '../../..'); // Up from src/features/[featureName] to root
|
|
82
|
+
const modelsPath = path.join(projectRoot, 'src', 'db', 'mysql', 'models');
|
|
83
|
+
// Ensure models folder exists
|
|
84
|
+
await fs.ensureDir(modelsPath);
|
|
85
|
+
const toPascalCase = (s) => s.charAt(0).toUpperCase() + s.slice(1);
|
|
86
|
+
const toKebabCase = (s) => s.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();
|
|
87
|
+
// Simple pluralizer fallback
|
|
88
|
+
const pluralize = (s) => s.endsWith('s') ? s : s + 's';
|
|
89
|
+
const modelName = toPascalCase(entityName);
|
|
90
|
+
const fileName = `${toKebabCase(entityName)}.model.ts`;
|
|
91
|
+
const tableName = pluralize(entityName).toLowerCase();
|
|
92
|
+
// Import correct connection getter
|
|
93
|
+
const importStatement = dbConnectionName
|
|
94
|
+
? `import { getSecondaryMySQLConnection } from '../client.js';`
|
|
95
|
+
: `import getDefaultMySQLConnection from '../client.js';`;
|
|
96
|
+
const connectionLogic = dbConnectionName
|
|
97
|
+
? `const sequelize = getSecondaryMySQLConnection('${dbConnectionName}');`
|
|
98
|
+
: `const sequelize = getDefaultMySQLConnection();`;
|
|
99
|
+
const connectionNameLog = dbConnectionName || 'default';
|
|
100
|
+
const modelContent = `import { DataTypes, Model, Optional } from 'sequelize';
|
|
101
|
+
${importStatement}
|
|
102
|
+
|
|
103
|
+
interface ${modelName}Attributes {
|
|
104
|
+
id: number;
|
|
105
|
+
name: string;
|
|
106
|
+
createdAt?: Date;
|
|
107
|
+
updatedAt?: Date;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
interface ${modelName}CreationAttributes extends Optional<${modelName}Attributes, 'id'> {}
|
|
111
|
+
|
|
112
|
+
export class ${modelName} extends Model<${modelName}Attributes, ${modelName}CreationAttributes> implements ${modelName}Attributes {
|
|
113
|
+
public id!: number;
|
|
114
|
+
public name!: string;
|
|
115
|
+
public readonly createdAt!: Date;
|
|
116
|
+
public readonly updatedAt!: Date;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
let initialized = false;
|
|
120
|
+
|
|
121
|
+
export function get${modelName}Model() {
|
|
122
|
+
if (initialized) return ${modelName};
|
|
123
|
+
|
|
124
|
+
${connectionLogic}
|
|
125
|
+
if (!sequelize) {
|
|
126
|
+
throw new Error('Database connection "${connectionNameLog}" not found or not initialized');
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
${modelName}.init(
|
|
130
|
+
{
|
|
131
|
+
id: {
|
|
132
|
+
type: DataTypes.INTEGER.UNSIGNED,
|
|
133
|
+
autoIncrement: true,
|
|
134
|
+
primaryKey: true,
|
|
135
|
+
},
|
|
136
|
+
name: {
|
|
137
|
+
type: DataTypes.STRING(128),
|
|
138
|
+
allowNull: false,
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
tableName: '${tableName}',
|
|
143
|
+
sequelize,
|
|
144
|
+
}
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
initialized = true;
|
|
148
|
+
return ${modelName};
|
|
149
|
+
}
|
|
150
|
+
`;
|
|
151
|
+
const filePath = path.join(modelsPath, fileName);
|
|
152
|
+
await fs.writeFile(filePath, modelContent);
|
|
153
|
+
return fileName;
|
|
154
|
+
}
|
|
4
155
|
export const generateFeature = async (options) => {
|
|
5
|
-
const { name, useMongo = true, useRedis = true } = options;
|
|
156
|
+
const { name, useMongo = true, useRedis = true, useMySQL = false, dbConnectionName, mysqlDbConnectionName } = options;
|
|
6
157
|
const featurePath = path.join(process.cwd(), 'src', 'features', name);
|
|
7
158
|
if (await fs.pathExists(featurePath)) {
|
|
8
159
|
console.error(chalk.red(`Feature ${name} already exists.`));
|
|
@@ -10,6 +161,7 @@ export const generateFeature = async (options) => {
|
|
|
10
161
|
}
|
|
11
162
|
await fs.ensureDir(featurePath);
|
|
12
163
|
const capitalize = (s) => s.charAt(0).toUpperCase() + s.slice(1);
|
|
164
|
+
const toKebabCase = (s) => s.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();
|
|
13
165
|
const pascalName = capitalize(name);
|
|
14
166
|
// TypeDefs
|
|
15
167
|
const typeDefsContent = `export const typeDefs = \`#graphql
|
|
@@ -33,49 +185,124 @@ export const generateFeature = async (options) => {
|
|
|
33
185
|
create${pascalName}(name: String!): ${pascalName}Response
|
|
34
186
|
}
|
|
35
187
|
\`;`;
|
|
36
|
-
// Model
|
|
188
|
+
// Model Generation
|
|
189
|
+
let generatedModelFileName = '';
|
|
37
190
|
if (useMongo) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
name: { type: String, required: true },
|
|
46
|
-
}, { timestamps: true, collection: '${pascalName}' });
|
|
47
|
-
|
|
48
|
-
export const ${pascalName}Model = mongoose.model<I${pascalName}>('${pascalName}', ${pascalName}Schema);`;
|
|
49
|
-
// Save model in src/db/mongo/
|
|
50
|
-
const mongoPath = path.join(process.cwd(), 'src', 'db', 'mongo');
|
|
51
|
-
if (await fs.pathExists(mongoPath)) {
|
|
52
|
-
await fs.writeFile(path.join(mongoPath, `${name}.model.ts`), modelContent);
|
|
53
|
-
}
|
|
54
|
-
else {
|
|
55
|
-
console.warn(chalk.yellow(`Warning: src/db/mongo does not exist. Saving model in feature folder.`));
|
|
56
|
-
await fs.writeFile(path.join(featurePath, 'model.ts'), modelContent);
|
|
57
|
-
}
|
|
191
|
+
generatedModelFileName = await generateModel({ ...options, entityName: name, featurePath });
|
|
192
|
+
generatedModelFileName = generatedModelFileName.replace('.ts', '.js');
|
|
193
|
+
}
|
|
194
|
+
if (useMySQL) {
|
|
195
|
+
// Use mysqlDbConnectionName specifically for MySQL
|
|
196
|
+
generatedModelFileName = await generateMySQLModel({ ...options, dbConnectionName: mysqlDbConnectionName, entityName: name, featurePath });
|
|
197
|
+
generatedModelFileName = generatedModelFileName.replace('.ts', '.js');
|
|
58
198
|
}
|
|
59
199
|
// Service
|
|
60
200
|
let serviceImports = '';
|
|
61
201
|
let serviceClassBody = '';
|
|
62
202
|
if (useMongo) {
|
|
63
|
-
// Import from centralized location: ../../db/mongo/NAME.model.js
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
serviceImports += `import { ${pascalName}Model, I${pascalName} } from '../../db/mongo/${name}.model.js';\n`;
|
|
68
|
-
}
|
|
69
|
-
else {
|
|
70
|
-
serviceImports += `import { ${pascalName}Model, I${pascalName} } from './model.js';\n`;
|
|
71
|
-
}
|
|
203
|
+
// Import from centralized location: ../../db/mongo/models/NAME.model.js
|
|
204
|
+
serviceImports += `import { ${dbConnectionName ? `get${pascalName}Model` : `${pascalName}Model`}, I${pascalName} } from '../../db/mongo/models/${generatedModelFileName}';\n`;
|
|
205
|
+
// Define how to access the model
|
|
206
|
+
const modelAccess = dbConnectionName ? `get${pascalName}Model()` : `${pascalName}Model`;
|
|
72
207
|
serviceClassBody += `
|
|
73
208
|
async getAll(): Promise<I${pascalName}[]> {
|
|
74
|
-
return ${
|
|
209
|
+
return ${modelAccess}.find();
|
|
75
210
|
}
|
|
76
211
|
|
|
77
212
|
async create(name: string): Promise<I${pascalName}> {
|
|
78
|
-
return ${
|
|
213
|
+
return ${modelAccess}.create({ name });
|
|
214
|
+
}
|
|
215
|
+
`;
|
|
216
|
+
}
|
|
217
|
+
else if (useMySQL) {
|
|
218
|
+
// Ensure MySQL Client exists
|
|
219
|
+
const clientPath = path.join(process.cwd(), 'src', 'db', 'mysql', 'client.ts');
|
|
220
|
+
if (!await fs.pathExists(clientPath)) {
|
|
221
|
+
console.log(chalk.yellow('MySQL client not found. Creating default client...'));
|
|
222
|
+
await fs.ensureDir(path.dirname(clientPath));
|
|
223
|
+
const mysqlClientContent = `import { Sequelize } from 'sequelize';
|
|
224
|
+
|
|
225
|
+
export interface MySQLConfig {
|
|
226
|
+
name?: string; // 'default' or others
|
|
227
|
+
database: string;
|
|
228
|
+
user: string;
|
|
229
|
+
password?: string;
|
|
230
|
+
host: string;
|
|
231
|
+
port: number;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
export class MySQLConnector {
|
|
235
|
+
private connections: Map<string, Sequelize> = new Map();
|
|
236
|
+
private configs: MySQLConfig[];
|
|
237
|
+
|
|
238
|
+
constructor(configs: MySQLConfig[]) {
|
|
239
|
+
this.configs = configs;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
public async connect(): Promise<void> {
|
|
243
|
+
for (const config of this.configs) {
|
|
244
|
+
const sequelize = new Sequelize(config.database, config.user, config.password, {
|
|
245
|
+
host: config.host,
|
|
246
|
+
port: config.port,
|
|
247
|
+
dialect: 'mysql',
|
|
248
|
+
logging: process.env.NODE_ENV === 'development' ? console.log : false,
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
try {
|
|
252
|
+
await sequelize.authenticate();
|
|
253
|
+
console.log(\`MySQL Connection (\${config.name || 'default'}) established successfully.\`);
|
|
254
|
+
this.connections.set(config.name || 'default', sequelize);
|
|
255
|
+
} catch (error) {
|
|
256
|
+
console.error(\`Unable to connect to the MySQL database (\${config.name || 'default'}):\`, error);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
public getConnection(name: string = 'default'): Sequelize | undefined {
|
|
262
|
+
return this.connections.get(name);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
public getSecondaryConnection(name: string): Sequelize | undefined {
|
|
266
|
+
return this.connections.get(name);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
let mysqlConnector: MySQLConnector | null = null;
|
|
271
|
+
|
|
272
|
+
export const setMySQLConnector = (connector: MySQLConnector) => {
|
|
273
|
+
mysqlConnector = connector;
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
export const getMySQLConnector = (): MySQLConnector => {
|
|
277
|
+
if (!mysqlConnector) throw new Error('MySQL Connector not initialized');
|
|
278
|
+
return mysqlConnector;
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
export const getSecondaryMySQLConnection = (name: string): Sequelize | undefined => {
|
|
282
|
+
return getMySQLConnector().getSecondaryConnection(name);
|
|
283
|
+
};
|
|
284
|
+
|
|
285
|
+
export default () => {
|
|
286
|
+
try {
|
|
287
|
+
return getMySQLConnector().getConnection('default');
|
|
288
|
+
} catch (e) {
|
|
289
|
+
// Fallback for single DB scenarios or before init
|
|
290
|
+
return null;
|
|
291
|
+
}
|
|
292
|
+
};
|
|
293
|
+
`;
|
|
294
|
+
await fs.writeFile(clientPath, mysqlClientContent);
|
|
295
|
+
}
|
|
296
|
+
// Import from centralized location: ../../db/mysql/models/NAME.model.js
|
|
297
|
+
serviceImports += `import { get${pascalName}Model, ${pascalName} } from '../../db/mysql/models/${generatedModelFileName}';\n`;
|
|
298
|
+
const modelAccess = `get${pascalName}Model()`;
|
|
299
|
+
serviceClassBody += `
|
|
300
|
+
async getAll(): Promise<${pascalName}[]> {
|
|
301
|
+
return ${modelAccess}.findAll();
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
async create(name: string): Promise<${pascalName}> {
|
|
305
|
+
return ${modelAccess}.create({ name });
|
|
79
306
|
}
|
|
80
307
|
`;
|
|
81
308
|
}
|
|
@@ -83,7 +310,7 @@ export const ${pascalName}Model = mongoose.model<I${pascalName}>('${pascalName}'
|
|
|
83
310
|
// In-memory or Redis-only fallback for types
|
|
84
311
|
serviceClassBody += `
|
|
85
312
|
async getAll(): Promise<any[]> {
|
|
86
|
-
return [{ id: '1', name: 'Test (No Mongo)' }];
|
|
313
|
+
return [{ id: '1', name: 'Test (No Mongo/MySQL)' }];
|
|
87
314
|
}
|
|
88
315
|
|
|
89
316
|
async create(name: string): Promise<any> {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feature-generator.js","sourceRoot":"","sources":["../../../src/cli/generators/feature-generator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,EAAE,OAA+B,EAAE,EAAE;IACrE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,IAAI,EAAE,QAAQ,GAAG,IAAI,EAAE,GAAG,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"feature-generator.js","sourceRoot":"","sources":["../../../src/cli/generators/feature-generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,2 +1,7 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
1
|
+
export interface GenerateGraphQLOptions {
|
|
2
|
+
feature?: string;
|
|
3
|
+
name?: string;
|
|
4
|
+
returnType?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare const generateQuery: (options?: GenerateGraphQLOptions) => Promise<void>;
|
|
7
|
+
export declare const generateMutation: (options?: GenerateGraphQLOptions) => Promise<void>;
|
|
@@ -2,13 +2,13 @@ import fs from 'fs-extra';
|
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import inquirer from 'inquirer';
|
|
4
4
|
import chalk from 'chalk';
|
|
5
|
-
export const generateQuery = async () => {
|
|
6
|
-
await generateGraphQLOperation('query');
|
|
5
|
+
export const generateQuery = async (options) => {
|
|
6
|
+
await generateGraphQLOperation('query', options);
|
|
7
7
|
};
|
|
8
|
-
export const generateMutation = async () => {
|
|
9
|
-
await generateGraphQLOperation('mutation');
|
|
8
|
+
export const generateMutation = async (options) => {
|
|
9
|
+
await generateGraphQLOperation('mutation', options);
|
|
10
10
|
};
|
|
11
|
-
const generateGraphQLOperation = async (type) => {
|
|
11
|
+
const generateGraphQLOperation = async (type, options) => {
|
|
12
12
|
try {
|
|
13
13
|
// 1. Get available features
|
|
14
14
|
const featuresPath = path.join(process.cwd(), 'src', 'features');
|
|
@@ -26,27 +26,36 @@ const generateGraphQLOperation = async (type) => {
|
|
|
26
26
|
return;
|
|
27
27
|
}
|
|
28
28
|
// 2. Prompt user
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
// 2. Prompt user (only for missing fields)
|
|
30
|
+
const prompts = [];
|
|
31
|
+
if (!options?.feature) {
|
|
32
|
+
prompts.push({
|
|
31
33
|
type: 'rawlist',
|
|
32
34
|
name: 'feature',
|
|
33
35
|
message: 'Select a feature:',
|
|
34
36
|
choices: features.map(f => ({ name: f, value: f }))
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
if (!options?.name) {
|
|
40
|
+
prompts.push({
|
|
37
41
|
type: 'input',
|
|
38
42
|
name: 'name',
|
|
39
43
|
message: `${type === 'query' ? 'Query' : 'Mutation'} name:`,
|
|
40
44
|
validate: (input) => input ? true : 'Name is required'
|
|
41
|
-
}
|
|
42
|
-
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
if (!options?.returnType) {
|
|
48
|
+
prompts.push({
|
|
43
49
|
type: 'input',
|
|
44
50
|
name: 'returnType',
|
|
45
51
|
message: 'Return type:',
|
|
46
52
|
default: 'String'
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
const answers = await inquirer.prompt(prompts);
|
|
56
|
+
const feature = options?.feature || answers.feature;
|
|
57
|
+
const name = options?.name || answers.name;
|
|
58
|
+
const returnType = options?.returnType || answers.returnType;
|
|
50
59
|
if (!feature) {
|
|
51
60
|
console.error(chalk.red('❌ No feature selected.'));
|
|
52
61
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graphql-generator.js","sourceRoot":"","sources":["../../../src/cli/generators/graphql-generator.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,QAAQ,MAAM,UAAU,CAAC;AAChC,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"graphql-generator.js","sourceRoot":"","sources":["../../../src/cli/generators/graphql-generator.ts"],"names":[],"mappings":"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"}
|