alexis-cli 1.0.2 → 1.0.4

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/.idea/vcs.xml ADDED
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="VcsDirectoryMappings">
4
+ <mapping directory="$PROJECT_DIR$" vcs="Git" />
5
+ </component>
6
+ </project>
@@ -1,6 +1,18 @@
1
1
  const fs = require('fs');
2
2
  const path = require('path');
3
3
 
4
+ const projectRoot = process.cwd();
5
+ const srcDir = path.join(projectRoot, 'src');
6
+
7
+ const writeIfNotExists = (filePath, content) => {
8
+ if (fs.existsSync(filePath)) {
9
+ console.log(`↩️ Skipped ${path.basename(filePath)} (already exists)`);
10
+ return;
11
+ }
12
+ fs.writeFileSync(filePath, content + '\n');
13
+ console.log(`➕ Created ${path.basename(filePath)}`);
14
+ };
15
+
4
16
  module.exports = (entityName) => {
5
17
  if (!entityName) {
6
18
  console.error('❌ Usage: alexis make crud <Entity>');
@@ -11,36 +23,35 @@ module.exports = (entityName) => {
11
23
  const EntityName =
12
24
  entityName.charAt(0).toUpperCase() + entityName.slice(1);
13
25
 
14
- // 🔎 Vérifier l'Entity
15
- const entityPath = path.join(
16
- __dirname,
17
- '../../src/entities',
18
- `${EntityName}.entity.js`
19
- );
26
+ /* ======================
27
+ ENTITY CHECK
28
+ ====================== */
29
+
30
+ const entityPath = path.join(srcDir, 'entities', `${EntityName}.entity.js`);
20
31
 
21
32
  if (!fs.existsSync(entityPath)) {
22
33
  console.error(`❌ Entity "${EntityName}" not found`);
23
34
  process.exit(1);
24
35
  }
25
36
 
26
- // 📁 Module
27
- const moduleDir = path.join(
28
- __dirname,
29
- '../../src/modules/v1',
30
- moduleName
31
- );
37
+ /* ======================
38
+ MODULE DIR
39
+ ====================== */
32
40
 
33
- if (fs.existsSync(moduleDir)) {
34
- console.error(`❌ Module "${moduleName}" already exists`);
35
- process.exit(1);
36
- }
41
+ const moduleDir = path.join(srcDir, 'modules/v1', moduleName);
37
42
 
38
- fs.mkdirSync(moduleDir, { recursive: true });
43
+ if (!fs.existsSync(moduleDir)) {
44
+ fs.mkdirSync(moduleDir, { recursive: true });
45
+ console.log(`📁 Module "${moduleName}" created`);
46
+ } else {
47
+ console.log(`📁 Module "${moduleName}" already exists → completing`);
48
+ }
39
49
 
40
50
  /* ======================
41
51
  SERVICE
42
52
  ====================== */
43
- fs.writeFileSync(
53
+
54
+ writeIfNotExists(
44
55
  path.join(moduleDir, `${moduleName}.service.js`),
45
56
  `
46
57
  const AppDataSource = require('../../../config/orm');
@@ -62,13 +73,14 @@ exports.update = async (id, data) => {
62
73
 
63
74
  exports.remove = (id) =>
64
75
  repo().delete(id);
65
- `.trim() + '\n'
76
+ `.trim()
66
77
  );
67
78
 
68
79
  /* ======================
69
80
  CONTROLLER
70
81
  ====================== */
71
- fs.writeFileSync(
82
+
83
+ writeIfNotExists(
72
84
  path.join(moduleDir, `${moduleName}.controller.js`),
73
85
  `
74
86
  const service = require('./${moduleName}.service');
@@ -113,13 +125,14 @@ exports.remove = async (req, res, next) => {
113
125
  next(e);
114
126
  }
115
127
  };
116
- `.trim() + '\n'
128
+ `.trim()
117
129
  );
118
130
 
119
131
  /* ======================
120
132
  ROUTES + SWAGGER
121
133
  ====================== */
122
- fs.writeFileSync(
134
+
135
+ writeIfNotExists(
123
136
  path.join(moduleDir, `${moduleName}.routes.js`),
124
137
  `
125
138
  /**
@@ -133,126 +146,31 @@ const express = require('express');
133
146
  const router = express.Router();
134
147
  const controller = require('./${moduleName}.controller');
135
148
 
136
- /**
137
- * @swagger
138
- * /${moduleName}:
139
- * get:
140
- * summary: Get all ${EntityName}
141
- * tags: [${EntityName}]
142
- * security:
143
- * - bearerAuth: []
144
- * responses:
145
- * 200:
146
- * description: List of ${EntityName}
147
- */
148
149
  router.get('/', controller.findAll);
149
-
150
- /**
151
- * @swagger
152
- * /${moduleName}/{id}:
153
- * get:
154
- * summary: Get a ${EntityName} by id
155
- * tags: [${EntityName}]
156
- * security:
157
- * - bearerAuth: []
158
- * parameters:
159
- * - in: path
160
- * name: id
161
- * required: true
162
- * schema:
163
- * type: integer
164
- * responses:
165
- * 200:
166
- * description: ${EntityName} found
167
- * 404:
168
- * description: ${EntityName} not found
169
- */
170
150
  router.get('/:id', controller.findOne);
171
-
172
- /**
173
- * @swagger
174
- * /${moduleName}:
175
- * post:
176
- * summary: Create a ${EntityName}
177
- * tags: [${EntityName}]
178
- * security:
179
- * - bearerAuth: []
180
- * requestBody:
181
- * required: true
182
- * content:
183
- * application/json:
184
- * schema:
185
- * type: object
186
- * responses:
187
- * 201:
188
- * description: ${EntityName} created
189
- */
190
151
  router.post('/', controller.create);
191
-
192
- /**
193
- * @swagger
194
- * /${moduleName}/{id}:
195
- * put:
196
- * summary: Update a ${EntityName}
197
- * tags: [${EntityName}]
198
- * security:
199
- * - bearerAuth: []
200
- * parameters:
201
- * - in: path
202
- * name: id
203
- * required: true
204
- * schema:
205
- * type: integer
206
- * requestBody:
207
- * required: true
208
- * content:
209
- * application/json:
210
- * schema:
211
- * type: object
212
- * responses:
213
- * 200:
214
- * description: ${EntityName} updated
215
- */
216
152
  router.put('/:id', controller.update);
217
-
218
- /**
219
- * @swagger
220
- * /${moduleName}/{id}:
221
- * delete:
222
- * summary: Delete a ${EntityName}
223
- * tags: [${EntityName}]
224
- * security:
225
- * - bearerAuth: []
226
- * parameters:
227
- * - in: path
228
- * name: id
229
- * required: true
230
- * schema:
231
- * type: integer
232
- * responses:
233
- * 204:
234
- * description: ${EntityName} deleted
235
- */
236
153
  router.delete('/:id', controller.remove);
237
154
 
238
155
  module.exports = router;
239
- `.trim() + '\n'
156
+ `.trim()
240
157
  );
241
158
 
242
- console.log(`✅ CRUD module "${moduleName}" created`);
243
-
244
159
  /* ======================
245
160
  AUTO-REGISTER ROUTE
246
161
  ====================== */
247
- const routesIndexPath = path.join(
248
- __dirname,
249
- '../../src/routes/v1/index.js'
250
- );
162
+
163
+ const routesIndexPath = path.join(srcDir, 'routes/v1/index.js');
164
+
165
+ if (!fs.existsSync(routesIndexPath)) {
166
+ console.warn('⚠️ routes/v1/index.js not found, skipping route registration');
167
+ return;
168
+ }
251
169
 
252
170
  let index = fs.readFileSync(routesIndexPath, 'utf8');
253
171
 
254
172
  const importLine =
255
- `const ${moduleName}Routes = require('../../../src/modules/v1/${moduleName}/${moduleName}.routes');`;
173
+ `const ${moduleName}Routes = require('../../modules/v1/${moduleName}/${moduleName}.routes');`;
256
174
  const routeLine =
257
175
  `router.use('/${moduleName}', ${moduleName}Routes);`;
258
176
 
@@ -273,4 +191,5 @@ module.exports = router;
273
191
  fs.writeFileSync(routesIndexPath, index);
274
192
 
275
193
  console.log(`🔗 Route "/${moduleName}" registered`);
194
+ console.log(`✅ CRUD ready for "${EntityName}"`);
276
195
  };
@@ -2,6 +2,8 @@ const fs = require('fs');
2
2
  const path = require('path');
3
3
  const readline = require('readline');
4
4
  const entityTypes = require('../bin/cli/entity-types');
5
+ const projectRoot = process.cwd();
6
+ const srcDir = path.join(projectRoot, 'src');
5
7
 
6
8
  module.exports = async (name) => {
7
9
  if (!name) {
@@ -12,7 +14,7 @@ module.exports = async (name) => {
12
14
  const entityName = name.charAt(0).toUpperCase() + name.slice(1);
13
15
  const tableName = name.toLowerCase() + 's';
14
16
 
15
- const entityDir = path.join(__dirname, '../../src/entities');
17
+ const entityDir = path.join(srcDir, 'entities');
16
18
  const entityPath = path.join(entityDir, `${entityName}.entity.js`);
17
19
 
18
20
  if (!fs.existsSync(entityDir)) {
@@ -6,8 +6,31 @@ module.exports = (name) => {
6
6
  process.exit(1);
7
7
  }
8
8
 
9
- execSync(
10
- `npx typeorm migration:generate src/migrations/${name} -d src/config/orm.js --outputJs`,
11
- { stdio: 'inherit' }
12
- );
9
+ console.log(`📦 Generating migration "${name}"...`);
10
+
11
+ try {
12
+ execSync(
13
+ `npx typeorm migration:generate src/migrations/${name} -d src/config/orm.js --outputJs`,
14
+ { stdio: 'inherit' }
15
+ );
16
+
17
+ console.log('✅ Migration generated from schema changes');
18
+ } catch (error) {
19
+ const message = error?.message || '';
20
+
21
+ if (message.includes('No changes in database schema were found')) {
22
+ console.warn('⚠️ No schema changes detected');
23
+ console.log('➡️ Creating empty migration instead');
24
+
25
+ execSync(
26
+ `npx typeorm migration:create src/migrations/${name}`,
27
+ { stdio: 'inherit' }
28
+ );
29
+
30
+ console.log('✅ Empty migration created');
31
+ } else {
32
+ console.error('❌ Migration generation failed');
33
+ process.exit(1);
34
+ }
35
+ }
13
36
  };
@@ -1,5 +1,7 @@
1
1
  const fs = require('fs');
2
2
  const path = require('path');
3
+ const projectRoot = process.cwd();
4
+ const srcDir = path.join(projectRoot, 'src');
3
5
 
4
6
  module.exports = (moduleName) => {
5
7
  if (!moduleName) {
@@ -10,10 +12,10 @@ module.exports = (moduleName) => {
10
12
  const entityName =
11
13
  moduleName.charAt(0).toUpperCase() + moduleName.slice(1);
12
14
 
13
- // 🔎 Vérifier que l'Entity existe
15
+ // Vérifier que l'Entity existe
14
16
  const entityPath = path.join(
15
- __dirname,
16
- '../../src/entities',
17
+ srcDir,
18
+ 'entities',
17
19
  `${entityName}.entity.js`
18
20
  );
19
21
 
@@ -24,10 +26,10 @@ module.exports = (moduleName) => {
24
26
  process.exit(1);
25
27
  }
26
28
 
27
- // 📁 Création du module
29
+ // Création du module
28
30
  const basePath = path.join(
29
- __dirname,
30
- '../../src/modules/v1',
31
+ srcDir,
32
+ 'modules/v1',
31
33
  moduleName
32
34
  );
33
35
 
@@ -138,10 +140,10 @@ module.exports = router;
138
140
 
139
141
  console.log(`✅ Module v1 "${moduleName}" created and linked to entity "${entityName}"`);
140
142
 
141
- // 🔗 Auto-register route
143
+ // Auto-register route
142
144
  const routesIndexPath = path.join(
143
- __dirname,
144
- '../../src/routes/v1/index.js'
145
+ srcDir,
146
+ 'routes/v1/index.js'
145
147
  );
146
148
 
147
149
  if (!fs.existsSync(routesIndexPath)) {
@@ -151,7 +153,8 @@ module.exports = router;
151
153
 
152
154
  let indexContent = fs.readFileSync(routesIndexPath, 'utf8');
153
155
 
154
- const importLine = `const ${moduleName}Routes = require('../../../src/modules/v1/${moduleName}/${moduleName}.routes');`;
156
+ const importLine =
157
+ `const ${moduleName}Routes = require('../../modules/v1/${moduleName}/${moduleName}.routes');`;
155
158
  const routeLine = `router.use('/${moduleName}', ${moduleName}Routes);`;
156
159
 
157
160
  if (!indexContent.includes(importLine)) {
@@ -123,7 +123,7 @@ const buildExampleFromEntity = (entity) => {
123
123
  ====================================================== */
124
124
 
125
125
  module.exports = () => {
126
- const projectRoot = path.join(__dirname, '../..');
126
+ const projectRoot = process.cwd();
127
127
  const srcDir = path.join(projectRoot, 'src');
128
128
  const swaggerDir = path.join(srcDir, 'swagger');
129
129
 
@@ -155,6 +155,17 @@ module.exports = () => {
155
155
  /* ========= ENTITIES → SCHEMAS ========= */
156
156
 
157
157
  const entitiesDir = path.join(srcDir, 'entities');
158
+ if (!fs.existsSync(entitiesDir)) {
159
+ console.warn('⚠️ No entities directory found, skipping Swagger generation');
160
+ return;
161
+ }
162
+
163
+ const modulesDir = path.join(srcDir, 'modules/v1');
164
+ if (!fs.existsSync(modulesDir)) {
165
+ console.warn('⚠️ No modules directory found, skipping Swagger generation');
166
+ return;
167
+ }
168
+
158
169
 
159
170
  fs.readdirSync(entitiesDir).forEach((file) => {
160
171
  if (!file.endsWith('.entity.js')) return;
@@ -245,44 +256,11 @@ module.exports = () => {
245
256
  };
246
257
  generateAuthSwagger(swagger);
247
258
 
248
- const modulesDir = path.join(srcDir, 'modules/v1');
249
-
250
259
  fs.readdirSync(modulesDir).forEach((moduleName) => {
251
260
  if (moduleName === 'auth') return;
252
261
  const modulePath = path.join(modulesDir, moduleName);
253
262
  if (!fs.statSync(modulePath).isDirectory()) return;
254
263
 
255
- /* ----- AUTH ----- */
256
- if (moduleName === 'auth') {
257
- swagger.paths['/auth/register'] = {
258
- post: {
259
- tags: ['Auth'],
260
- summary: 'Register',
261
- description: 'Create a new user account',
262
- requestBody: {
263
- required: true,
264
- content: {
265
- 'application/json': {
266
- schema: {
267
- type: 'object',
268
- properties: {
269
- email: { type: 'string' },
270
- password: { type: 'string' }
271
- }
272
- },
273
- example: {
274
- email: 'user@example.com',
275
- password: 'password123'
276
- }
277
- }
278
- }
279
- },
280
- responses: { 201: { description: 'User created' } }
281
- }
282
- };
283
- return;
284
- }
285
-
286
264
  /* ----- CRUD ----- */
287
265
 
288
266
  const entityName =
@@ -1,15 +1,33 @@
1
1
  const { execSync } = require('child_process');
2
2
 
3
3
  exports.run = () => {
4
- execSync(
5
- `npx typeorm migration:run -d src/config/orm.js`,
6
- { stdio: 'inherit' }
7
- );
4
+ console.log('🚀 Running database migrations...');
5
+
6
+ try {
7
+ execSync(
8
+ `npx typeorm migration:run -d src/config/orm.js`,
9
+ { stdio: 'inherit' }
10
+ );
11
+
12
+ console.log('✅ Migrations executed successfully');
13
+ } catch (error) {
14
+ console.error('❌ Migration failed');
15
+ process.exit(1);
16
+ }
8
17
  };
9
18
 
10
19
  exports.rollback = () => {
11
- execSync(
12
- `npx typeorm migration:revert -d src/config/orm.js`,
13
- { stdio: 'inherit' }
14
- );
20
+ console.log('⏪ Reverting last migration...');
21
+
22
+ try {
23
+ execSync(
24
+ `npx typeorm migration:revert -d src/config/orm.js`,
25
+ { stdio: 'inherit' }
26
+ );
27
+
28
+ console.log('✅ Migration reverted successfully');
29
+ } catch (error) {
30
+ console.error('❌ Rollback failed');
31
+ process.exit(1);
32
+ }
15
33
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "alexis-cli",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "main": "index.js",
5
5
  "bin": {
6
6
  "alexis": "bin/alexis.js"