@diagramers/cli 4.0.16 → 4.0.17
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 +635 -451
- package/dist/commands/admin.d.ts +1 -1
- package/dist/commands/admin.d.ts.map +1 -1
- package/dist/commands/admin.js +6 -53
- package/dist/commands/admin.js.map +1 -1
- package/dist/commands/api.d.ts +1 -1
- package/dist/commands/api.d.ts.map +1 -1
- package/dist/commands/api.js +133 -582
- package/dist/commands/api.js.map +1 -1
- package/dist/commands/deploy.d.ts +15 -0
- package/dist/commands/extend.d.ts +3 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +24 -153
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +11 -40
- package/dist/commands/update.js.map +1 -1
- package/dist/config/template-config.d.ts +21 -0
- package/dist/index.js +218 -35
- package/dist/index.js.map +1 -1
- package/dist/services/api-generator.d.ts +3 -0
- package/dist/services/naming-utils.d.ts +37 -0
- package/dist/services/project-extender.d.ts +50 -0
- package/dist/services/project-initializer.d.ts +21 -0
- package/dist/services/project-initializer.d.ts.map +1 -1
- package/dist/services/project-initializer.js +11 -12
- package/dist/services/project-initializer.js.map +1 -1
- package/dist/services/project-updater.d.ts +18 -0
- package/dist/services/relation-generator.d.ts +3 -0
- package/dist/services/table-generator.d.ts +2 -0
- package/dist/services/template-processor.d.ts +2 -0
- package/dist/services/template-updater.d.ts +24 -0
- package/package.json +3 -3
package/dist/commands/api.js
CHANGED
@@ -1,628 +1,179 @@
|
|
1
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
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
36
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
37
4
|
};
|
38
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
39
6
|
exports.apiCommand = apiCommand;
|
7
|
+
const api_generator_1 = require("../services/api-generator");
|
8
|
+
const table_generator_1 = require("../services/table-generator");
|
9
|
+
const relation_generator_1 = require("../services/relation-generator");
|
10
|
+
const template_processor_1 = require("../services/template-processor");
|
40
11
|
const chalk_1 = __importDefault(require("chalk"));
|
41
|
-
const
|
42
|
-
const path = __importStar(require("path"));
|
12
|
+
const child_process_1 = require("child_process");
|
43
13
|
function apiCommand(program) {
|
44
14
|
const api = program
|
45
15
|
.command('api')
|
46
|
-
.description('API-specific commands for
|
16
|
+
.description('API-specific commands for diagramers projects');
|
17
|
+
// Version command
|
47
18
|
api
|
48
|
-
.command('
|
49
|
-
.description('
|
50
|
-
.option('-
|
51
|
-
.
|
52
|
-
.action(async (projectName, options) => {
|
19
|
+
.command('version')
|
20
|
+
.description('Show current API template version')
|
21
|
+
.option('-c, --check <version>', 'Check if specific version exists')
|
22
|
+
.action(async (options) => {
|
53
23
|
try {
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
24
|
+
if (options.check) {
|
25
|
+
console.log(chalk_1.default.blue(`📌 Checking @diagramers/api version: ${options.check}`));
|
26
|
+
try {
|
27
|
+
const versionInfo = (0, child_process_1.execSync)(`npm view @diagramers/api@${options.check} version`, {
|
28
|
+
encoding: 'utf8',
|
29
|
+
timeout: 5000
|
30
|
+
}).trim();
|
31
|
+
console.log(chalk_1.default.green(`✅ Version ${options.check} exists: ${versionInfo}`));
|
32
|
+
}
|
33
|
+
catch (error) {
|
34
|
+
console.log(chalk_1.default.red(`❌ Version ${options.check} not found`));
|
35
|
+
// Show available versions
|
36
|
+
try {
|
37
|
+
const versionsOutput = (0, child_process_1.execSync)('npm view @diagramers/api versions --json', {
|
38
|
+
encoding: 'utf8',
|
39
|
+
timeout: 10000
|
40
|
+
});
|
41
|
+
const versions = JSON.parse(versionsOutput);
|
42
|
+
const recentVersions = Array.isArray(versions) ? versions.slice(-5) : [versions];
|
43
|
+
console.log(chalk_1.default.yellow('\n📦 Recent available versions:'));
|
44
|
+
recentVersions.forEach((version) => {
|
45
|
+
console.log(chalk_1.default.yellow(` ${version}`));
|
46
|
+
});
|
47
|
+
}
|
48
|
+
catch (versionError) {
|
49
|
+
console.log(chalk_1.default.gray('Could not fetch available versions'));
|
50
|
+
}
|
51
|
+
}
|
60
52
|
}
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
"build": "webpack --mode production",
|
74
|
-
"build:dev": "webpack --mode development",
|
75
|
-
"build:watch": "webpack --mode development --watch",
|
76
|
-
"start:nodemon": "nodemon --watch lib --exec \"node lib/main.js\"",
|
77
|
-
"start:dev": "concurrently \"npm run build:watch\" \"npm run start:nodemon\"",
|
78
|
-
"clean": "rm -rf dist lib"
|
79
|
-
},
|
80
|
-
"keywords": [],
|
81
|
-
"author": "",
|
82
|
-
"license": "ISC",
|
83
|
-
"type": "commonjs",
|
84
|
-
"dependencies": {
|
85
|
-
"@diagramers/api": "^4.0.12",
|
86
|
-
"express": "^4.19.2",
|
87
|
-
"cors": "^2.8.5",
|
88
|
-
"mongoose": "^8.16.3",
|
89
|
-
"dotenv": "^16.6.1",
|
90
|
-
"jsonwebtoken": "^9.0.2",
|
91
|
-
"bcryptjs": "^3.0.2",
|
92
|
-
"axios": "^1.6.8",
|
93
|
-
"swagger-jsdoc": "^6.2.8",
|
94
|
-
"swagger-ui-express": "^5.0.1",
|
95
|
-
"uuid": "^9.0.1",
|
96
|
-
"js-yaml": "^4.1.0",
|
97
|
-
"fs-extra": "^11.3.0",
|
98
|
-
"nodemailer": "^6.9.13",
|
99
|
-
"socket.io": "^4.7.5",
|
100
|
-
"node-cron": "^3.0.3",
|
101
|
-
"moment-timezone": "^0.5.45",
|
102
|
-
"twilio": "^4.23.0",
|
103
|
-
"aws-sdk": "^2.1692.0",
|
104
|
-
"firebase-admin": "^12.0.0",
|
105
|
-
"firebase-functions": "^4.9.0",
|
106
|
-
"exceljs": "^4.4.0",
|
107
|
-
"vm2": "^3.9.19"
|
108
|
-
},
|
109
|
-
"devDependencies": {
|
110
|
-
"@types/express": "^4.17.13",
|
111
|
-
"@types/cors": "^2.8.19",
|
112
|
-
"@types/node": "^24.1.0",
|
113
|
-
"@types/bcryptjs": "^2.4.6",
|
114
|
-
"@types/jsonwebtoken": "^9.0.10",
|
115
|
-
"@types/uuid": "^9.0.8",
|
116
|
-
"@types/body-parser": "^1.19.6",
|
117
|
-
"@types/lodash": "^4.17.20",
|
118
|
-
"@types/mime": "^3.0.4",
|
119
|
-
"@types/ms": "^2.1.0",
|
120
|
-
"@types/qs": "^6.14.0",
|
121
|
-
"@types/range-parser": "^1.2.7",
|
122
|
-
"@types/serve-static": "^1.15.8",
|
123
|
-
"@types/swagger-ui-express": "^4.1.8",
|
124
|
-
"@types/tough-cookie": "^4.0.5",
|
125
|
-
"@types/webidl-conversions": "^7.0.3",
|
126
|
-
"@types/whatwg-url": "^13.0.0",
|
127
|
-
"typescript": "^4.9.5",
|
128
|
-
"ts-loader": "^9.5.1",
|
129
|
-
"webpack": "^5.91.0",
|
130
|
-
"webpack-cli": "^5.1.4",
|
131
|
-
"webpack-node-externals": "^3.0.0",
|
132
|
-
"concurrently": "^8.2.2",
|
133
|
-
"nodemon": "^3.1.10",
|
134
|
-
"ts-node": "^10.9.2",
|
135
|
-
"base-64": "^1.0.0",
|
136
|
-
"bson": "^6.6.0",
|
137
|
-
"express-http-to-https": "^1.1.4",
|
138
|
-
"firebase": "^10.11.0",
|
139
|
-
"firebase-functions-test": "^3.2.0",
|
140
|
-
"mini-css-extract-plugin": "^2.8.1",
|
141
|
-
"node-fetch": "^3.3.2",
|
142
|
-
"sortablejs": "^1.15.2",
|
143
|
-
"uuid4": "^2.0.3",
|
144
|
-
"yup": "^1.4.0"
|
53
|
+
else {
|
54
|
+
// Show current version info
|
55
|
+
console.log(chalk_1.default.blue('📦 @diagramers/api version information:'));
|
56
|
+
try {
|
57
|
+
const latestVersion = (0, child_process_1.execSync)('npm view @diagramers/api version', {
|
58
|
+
encoding: 'utf8',
|
59
|
+
timeout: 5000
|
60
|
+
}).trim();
|
61
|
+
console.log(chalk_1.default.green(`Latest: ${latestVersion}`));
|
62
|
+
}
|
63
|
+
catch (error) {
|
64
|
+
console.log(chalk_1.default.red('Could not fetch latest version'));
|
145
65
|
}
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
"suppressImplicitAnyIndexErrors": true
|
165
|
-
},
|
166
|
-
"include": [
|
167
|
-
"src/**/*"
|
168
|
-
],
|
169
|
-
"exclude": [
|
170
|
-
"node_modules",
|
171
|
-
"lib",
|
172
|
-
"**/*.test.ts"
|
173
|
-
]
|
174
|
-
};
|
175
|
-
fs.writeFileSync('tsconfig.json', JSON.stringify(tsconfig, null, 2));
|
176
|
-
const webpackConfig = `const path = require('path');
|
177
|
-
const nodeExternals = require('webpack-node-externals');
|
178
|
-
|
179
|
-
module.exports = {
|
180
|
-
target: 'node',
|
181
|
-
entry: './src/main.ts',
|
182
|
-
output: {
|
183
|
-
path: path.resolve(__dirname, 'lib'),
|
184
|
-
filename: 'main.js',
|
185
|
-
libraryTarget: 'commonjs2'
|
186
|
-
},
|
187
|
-
module: {
|
188
|
-
rules: [
|
189
|
-
{
|
190
|
-
test: /\\.ts$/,
|
191
|
-
use: 'ts-loader',
|
192
|
-
exclude: /node_modules/
|
193
|
-
}
|
194
|
-
]
|
195
|
-
},
|
196
|
-
resolve: {
|
197
|
-
extensions: ['.ts', '.js']
|
198
|
-
},
|
199
|
-
externals: [nodeExternals()],
|
200
|
-
mode: 'development'
|
201
|
-
};`;
|
202
|
-
fs.writeFileSync('webpack.config.js', webpackConfig);
|
203
|
-
const mainTs = `import { App } from './core/app';
|
204
|
-
|
205
|
-
const app = new App();
|
206
|
-
|
207
|
-
app.initialize()
|
208
|
-
.then(() => {
|
209
|
-
console.log('🚀 API server started successfully!');
|
210
|
-
})
|
211
|
-
.catch((error) => {
|
212
|
-
console.error('❌ Failed to start API server:', error);
|
213
|
-
process.exit(1);
|
214
|
-
});`;
|
215
|
-
fs.writeFileSync('src/main.ts', mainTs);
|
216
|
-
const appTs = `import express from 'express';
|
217
|
-
import cors from 'cors';
|
218
|
-
import dotenv from 'dotenv';
|
219
|
-
|
220
|
-
export class App {
|
221
|
-
private app: express.Application;
|
222
|
-
|
223
|
-
constructor() {
|
224
|
-
this.app = express();
|
225
|
-
this.setupMiddleware();
|
226
|
-
this.setupRoutes();
|
227
|
-
}
|
228
|
-
|
229
|
-
private setupMiddleware(): void {
|
230
|
-
this.app.use(cors());
|
231
|
-
this.app.use(express.json());
|
232
|
-
this.app.use(express.urlencoded({ extended: true }));
|
233
|
-
}
|
234
|
-
|
235
|
-
private setupRoutes(): void {
|
236
|
-
this.app.get('/health', (req, res) => {
|
237
|
-
res.json({ status: 'OK', timestamp: new Date().toISOString() });
|
66
|
+
// Check local version if in a project
|
67
|
+
try {
|
68
|
+
const localVersion = (0, child_process_1.execSync)('npm list @diagramers/api --depth=0', {
|
69
|
+
encoding: 'utf8',
|
70
|
+
timeout: 5000
|
71
|
+
});
|
72
|
+
console.log(chalk_1.default.blue('Local project version:'));
|
73
|
+
console.log(localVersion);
|
74
|
+
}
|
75
|
+
catch (error) {
|
76
|
+
console.log(chalk_1.default.gray('No local @diagramers/api installation found'));
|
77
|
+
}
|
78
|
+
}
|
79
|
+
}
|
80
|
+
catch (error) {
|
81
|
+
console.error(chalk_1.default.red(`❌ Error checking version: ${error.message}`));
|
82
|
+
process.exit(1);
|
83
|
+
}
|
238
84
|
});
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
85
|
+
// Generate module command
|
86
|
+
api
|
87
|
+
.command('generate:module <name>')
|
88
|
+
.description('Generate a new module with entity, schema, service, controller, and routes')
|
89
|
+
.action(async (name) => {
|
90
|
+
try {
|
91
|
+
console.log(chalk_1.default.blue(`🚀 Generating module: ${name}`));
|
92
|
+
await (0, api_generator_1.generateModule)(name);
|
93
|
+
console.log(chalk_1.default.green(`✅ Module '${name}' generated successfully!`));
|
94
|
+
}
|
95
|
+
catch (error) {
|
96
|
+
console.error(chalk_1.default.red(`❌ Error generating module: ${error.message}`));
|
97
|
+
process.exit(1);
|
98
|
+
}
|
246
99
|
});
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
JWT_SECRET=your-jwt-secret-key
|
260
|
-
JWT_EXPIRES_IN=24h
|
261
|
-
|
262
|
-
# Email Configuration
|
263
|
-
SMTP_HOST=smtp.gmail.com
|
264
|
-
SMTP_PORT=587
|
265
|
-
SMTP_USER=your-email@gmail.com
|
266
|
-
SMTP_PASS=your-app-password
|
267
|
-
|
268
|
-
# Odoo Configuration
|
269
|
-
ODOO_ENABLED=false
|
270
|
-
ODOO_BASE_URL=http://localhost:8069
|
271
|
-
ODOO_DATABASE=odoo
|
272
|
-
ODOO_USERNAME=admin
|
273
|
-
ODOO_PASSWORD=admin
|
274
|
-
ODOO_API_KEY=
|
275
|
-
ODOO_TIMEOUT=30000
|
276
|
-
ODOO_RETRY_ATTEMPTS=3
|
277
|
-
|
278
|
-
# Logging
|
279
|
-
LOG_LEVEL=info
|
280
|
-
LOG_FILE=logs/app.log`;
|
281
|
-
fs.writeFileSync('.env.example', envExample);
|
282
|
-
const gitignore = `node_modules/
|
283
|
-
lib/
|
284
|
-
dist/
|
285
|
-
.env
|
286
|
-
logs/
|
287
|
-
*.log
|
288
|
-
.DS_Store`;
|
289
|
-
fs.writeFileSync('.gitignore', gitignore);
|
290
|
-
console.log(chalk_1.default.blue('📦 Installing dependencies...'));
|
291
|
-
execSync('npm install --legacy-peer-deps', { stdio: 'inherit' });
|
292
|
-
console.log(chalk_1.default.green(`✅ API project '${projectName}' initialized successfully!`));
|
293
|
-
console.log(chalk_1.default.blue(`📁 Project created at: ${process.cwd()}`));
|
294
|
-
console.log(chalk_1.default.blue(`🚀 To start development: npm run dev`));
|
295
|
-
console.log(chalk_1.default.yellow(`🔧 Copy .env.example to .env and configure your environment variables`));
|
296
|
-
console.log(chalk_1.default.yellow(`🔧 Available modules: auth, email, notification, odoo`));
|
100
|
+
// Generate endpoint command
|
101
|
+
api
|
102
|
+
.command('generate:endpoint <module-name> <endpoint-name>')
|
103
|
+
.description('Generate a new endpoint for an existing module')
|
104
|
+
.option('-m, --method <method>', 'HTTP method (GET, POST, PUT, DELETE)', 'GET')
|
105
|
+
.option('-p, --path <path>', 'Custom path for the endpoint (defaults to endpoint name)')
|
106
|
+
.option('-d, --description <description>', 'Description for the endpoint')
|
107
|
+
.action(async (moduleName, endpointName, options) => {
|
108
|
+
try {
|
109
|
+
console.log(chalk_1.default.blue(`🚀 Generating endpoint '${endpointName}' for module '${moduleName}'`));
|
110
|
+
await (0, api_generator_1.generateEndpoint)(moduleName, endpointName, options);
|
111
|
+
console.log(chalk_1.default.green(`✅ Endpoint '${endpointName}' generated successfully!`));
|
297
112
|
}
|
298
113
|
catch (error) {
|
299
|
-
console.error(chalk_1.default.red(`❌
|
114
|
+
console.error(chalk_1.default.red(`❌ Error generating endpoint: ${error.message}`));
|
300
115
|
process.exit(1);
|
301
116
|
}
|
302
117
|
});
|
118
|
+
// Process template command
|
303
119
|
api
|
304
|
-
.command('
|
305
|
-
.description('
|
306
|
-
.
|
307
|
-
.option('-f, --force', 'Force update even if conflicts detected')
|
308
|
-
.option('-b, --backup', 'Create backup before updating')
|
309
|
-
.option('-m, --modules <modules>', 'Comma-separated list of modules to add (e.g., odoo,notification)')
|
310
|
-
.action(async (options) => {
|
120
|
+
.command('process:template <name>')
|
121
|
+
.description('Process template files for a new project')
|
122
|
+
.action(async (name) => {
|
311
123
|
try {
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
console.error('❌ No package.json found. Please run this command from your API project directory.');
|
316
|
-
process.exit(1);
|
317
|
-
}
|
318
|
-
const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8'));
|
319
|
-
const isApiProject = packageJson.name === '@diagramers/api' ||
|
320
|
-
(packageJson.dependencies &&
|
321
|
-
(packageJson.dependencies['@diagramers/api'] ||
|
322
|
-
packageJson.devDependencies && packageJson.devDependencies['@diagramers/api']));
|
323
|
-
const isLegacyApi = packageJson.dependencies && packageJson.dependencies['@diagramers/api'];
|
324
|
-
if (!isApiProject) {
|
325
|
-
console.error('❌ This does not appear to be a Diagramers API project.');
|
326
|
-
process.exit(1);
|
327
|
-
}
|
328
|
-
console.log('🔄 Updating API project...');
|
329
|
-
if (options.backup) {
|
330
|
-
const backupDir = `backup-${new Date().toISOString().replace(/[:.]/g, '-')}`;
|
331
|
-
console.log(`📦 Creating backup in: ${backupDir}`);
|
332
|
-
require('child_process').execSync(`cp -r . ${backupDir}`, { stdio: 'inherit' });
|
333
|
-
}
|
334
|
-
if (isLegacyApi) {
|
335
|
-
let updateCommand = `npm update @diagramers/api`;
|
336
|
-
if (options.version) {
|
337
|
-
updateCommand = `npm install @diagramers/api@${options.version}`;
|
338
|
-
}
|
339
|
-
console.log(`Executing: ${updateCommand}`);
|
340
|
-
require('child_process').execSync(updateCommand, { stdio: 'inherit' });
|
341
|
-
console.log('✅ API project dependencies updated successfully!');
|
342
|
-
}
|
343
|
-
else {
|
344
|
-
console.log('ℹ️ Skipping package update (new API project structure)');
|
345
|
-
}
|
346
|
-
if (options.modules) {
|
347
|
-
const modules = options.modules.split(',').map((m) => m.trim());
|
348
|
-
console.log(`📦 Adding modules: ${modules.join(', ')}`);
|
349
|
-
for (const module of modules) {
|
350
|
-
await addModule(module, options.force);
|
351
|
-
}
|
352
|
-
}
|
353
|
-
console.log('✅ API project updated successfully!');
|
124
|
+
console.log(chalk_1.default.blue(`🔧 Processing template for project: ${name}`));
|
125
|
+
await (0, template_processor_1.processTemplate)(name);
|
126
|
+
console.log(chalk_1.default.green(`✅ Template processing completed for '${name}'!`));
|
354
127
|
}
|
355
128
|
catch (error) {
|
356
|
-
console.error(`❌
|
129
|
+
console.error(chalk_1.default.red(`❌ Error processing template: ${error.message}`));
|
357
130
|
process.exit(1);
|
358
131
|
}
|
359
132
|
});
|
133
|
+
// Generate table command
|
360
134
|
api
|
361
|
-
.command('
|
362
|
-
.description('
|
363
|
-
.action(async () => {
|
135
|
+
.command('generate:table <module:table>')
|
136
|
+
.description('Generate a new database table with entity and schema only (format: module:table)')
|
137
|
+
.action(async (name) => {
|
364
138
|
try {
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
(packageJson.dependencies && packageJson.dependencies['@diagramers/api']) ||
|
374
|
-
(packageJson.devDependencies && packageJson.devDependencies['@diagramers/api']);
|
375
|
-
if (!isApiProject) {
|
376
|
-
console.error(chalk_1.default.red('❌ This does not appear to be a Diagramers API project.'));
|
377
|
-
console.log(chalk_1.default.gray('💡 Make sure you are in a project that uses @diagramers/api'));
|
378
|
-
process.exit(1);
|
379
|
-
}
|
380
|
-
let apiVersion = 'Not installed';
|
381
|
-
if (packageJson.dependencies && packageJson.dependencies['@diagramers/api']) {
|
382
|
-
apiVersion = packageJson.dependencies['@diagramers/api'];
|
383
|
-
}
|
384
|
-
else if (packageJson.devDependencies && packageJson.devDependencies['@diagramers/api']) {
|
385
|
-
apiVersion = packageJson.devDependencies['@diagramers/api'];
|
386
|
-
}
|
387
|
-
else if (packageJson.name === '@diagramers/api') {
|
388
|
-
apiVersion = packageJson.version;
|
139
|
+
console.log(chalk_1.default.blue(`🚀 Generating table: ${name}`));
|
140
|
+
// Parse module:table format
|
141
|
+
const parts = name.split(':');
|
142
|
+
let moduleName;
|
143
|
+
let tableName;
|
144
|
+
if (parts.length === 2) {
|
145
|
+
moduleName = parts[0];
|
146
|
+
tableName = parts[1];
|
389
147
|
}
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
console.log(chalk_1.default.yellow('Installed Version:'), chalk_1.default.white(apiVersion));
|
394
|
-
console.log(chalk_1.default.yellow('Project Name:'), chalk_1.default.white(packageJson.name));
|
395
|
-
console.log(chalk_1.default.yellow('Project Version:'), chalk_1.default.white(packageJson.version));
|
396
|
-
try {
|
397
|
-
const { execSync } = require('child_process');
|
398
|
-
const latestVersion = execSync('npm view @diagramers/api version', { encoding: 'utf8' }).trim();
|
399
|
-
console.log(chalk_1.default.yellow('Latest Available:'), chalk_1.default.white(latestVersion));
|
400
|
-
if (apiVersion !== latestVersion && apiVersion !== 'Not installed') {
|
401
|
-
console.log(chalk_1.default.yellow('💡 Update Available:'), chalk_1.default.white(`Run 'diagramers api update' to update to version ${latestVersion}`));
|
402
|
-
}
|
403
|
-
}
|
404
|
-
catch (error) {
|
405
|
-
console.log(chalk_1.default.gray('💡 Could not check for latest version (network issue)'));
|
148
|
+
else {
|
149
|
+
moduleName = name;
|
150
|
+
tableName = name;
|
406
151
|
}
|
152
|
+
await (0, table_generator_1.generateTable)(moduleName, tableName);
|
153
|
+
console.log(chalk_1.default.green(`✅ Table '${tableName}' generated successfully!`));
|
407
154
|
}
|
408
155
|
catch (error) {
|
409
|
-
console.error(chalk_1.default.red(`❌
|
156
|
+
console.error(chalk_1.default.red(`❌ Error generating table: ${error.message}`));
|
410
157
|
process.exit(1);
|
411
158
|
}
|
412
159
|
});
|
160
|
+
// Generate relation command
|
413
161
|
api
|
414
|
-
.command('
|
415
|
-
.description('
|
416
|
-
.option('-
|
417
|
-
.
|
418
|
-
.action(async (moduleName, options) => {
|
162
|
+
.command('generate:relation <table1> <table2>')
|
163
|
+
.description('Generate a relationship between two existing tables')
|
164
|
+
.option('-t, --type <type>', 'Relationship type: one-to-one, one-to-many, many-to-many', 'one-to-one')
|
165
|
+
.action(async (table1, table2, options) => {
|
419
166
|
try {
|
420
|
-
|
167
|
+
const relationType = options?.type || 'one-to-one';
|
168
|
+
console.log(chalk_1.default.blue(`🔗 Creating ${relationType} relationship between ${table1} and ${table2}...`));
|
169
|
+
await (0, relation_generator_1.generateRelation)(table1, table2, relationType);
|
170
|
+
console.log(chalk_1.default.green(`✅ Relationship created successfully!`));
|
421
171
|
}
|
422
172
|
catch (error) {
|
423
|
-
console.error(chalk_1.default.red(`❌
|
173
|
+
console.error(chalk_1.default.red(`❌ Error creating relationship: ${error.message}`));
|
424
174
|
process.exit(1);
|
425
175
|
}
|
426
176
|
});
|
427
|
-
|
428
|
-
async function addModule(moduleName, force = false, version) {
|
429
|
-
console.log(chalk_1.default.blue(`📦 Adding module: ${moduleName}`));
|
430
|
-
const modulePath = path.join('src', 'modules', moduleName);
|
431
|
-
if (fs.existsSync(modulePath) && !force) {
|
432
|
-
console.error(chalk_1.default.red(`❌ Module '${moduleName}' already exists. Use --force to overwrite.`));
|
433
|
-
process.exit(1);
|
434
|
-
}
|
435
|
-
const availableModules = {
|
436
|
-
odoo: {
|
437
|
-
description: 'Odoo CRM integration module',
|
438
|
-
files: [
|
439
|
-
{
|
440
|
-
path: 'src/modules/odoo/entities/odoo-contact.entity.ts',
|
441
|
-
content: `// Odoo Contact Entity - Auto-generated by CLI
|
442
|
-
import { ObjectId } from 'mongoose';
|
443
|
-
|
444
|
-
export interface IOdooContact {
|
445
|
-
_id: ObjectId;
|
446
|
-
odooId: number;
|
447
|
-
name: string;
|
448
|
-
email?: string;
|
449
|
-
phone?: string;
|
450
|
-
type: 'contact' | 'invoice' | 'delivery' | 'private' | 'other';
|
451
|
-
isCompany: boolean;
|
452
|
-
isActive: boolean;
|
453
|
-
createDate: Date;
|
454
|
-
writeDate: Date;
|
455
|
-
createdAt: Date;
|
456
|
-
updatedAt: Date;
|
457
|
-
syncStatus: 'synced' | 'pending' | 'error';
|
458
|
-
}
|
459
|
-
|
460
|
-
export interface CreateOdooContactDto {
|
461
|
-
name: string;
|
462
|
-
email?: string;
|
463
|
-
phone?: string;
|
464
|
-
type?: 'contact' | 'invoice' | 'delivery' | 'private' | 'other';
|
465
|
-
isCompany?: boolean;
|
466
|
-
}
|
467
|
-
|
468
|
-
export interface UpdateOdooContactDto extends Partial<CreateOdooContactDto> {
|
469
|
-
isActive?: boolean;
|
470
|
-
}`
|
471
|
-
},
|
472
|
-
{
|
473
|
-
path: 'src/modules/odoo/controllers/odoo-contact.controller.ts',
|
474
|
-
content: `// Odoo Contact Controller - Auto-generated by CLI
|
475
|
-
import { Request, Response } from 'express';
|
476
|
-
import { ResponseCode } from '../../../shared/constants/enums';
|
477
|
-
|
478
|
-
export class OdooContactController {
|
479
|
-
async getAllCustomers(req: Request, res: Response): Promise<void> {
|
480
|
-
try {
|
481
|
-
res.json({
|
482
|
-
data: [],
|
483
|
-
statusCode: ResponseCode.Ok,
|
484
|
-
errors: [],
|
485
|
-
requestIdentifier: req.headers['x-request-id'] as string || null,
|
486
|
-
messages: null,
|
487
|
-
additionalInfo: null,
|
488
|
-
user: null
|
489
|
-
});
|
490
|
-
} catch (error: any) {
|
491
|
-
res.status(500).json({
|
492
|
-
data: null,
|
493
|
-
statusCode: ResponseCode.Error,
|
494
|
-
errors: [{ message: error.message }],
|
495
|
-
requestIdentifier: req.headers['x-request-id'] as string || null,
|
496
|
-
messages: null,
|
497
|
-
additionalInfo: null,
|
498
|
-
user: null
|
499
|
-
});
|
500
|
-
}
|
501
|
-
}
|
502
|
-
|
503
|
-
async getCustomerById(req: Request, res: Response): Promise<void> {
|
504
|
-
// Implementation
|
505
|
-
}
|
506
|
-
|
507
|
-
async createCustomer(req: Request, res: Response): Promise<void> {
|
508
|
-
// Implementation
|
509
|
-
}
|
510
|
-
|
511
|
-
async updateCustomer(req: Request, res: Response): Promise<void> {
|
512
|
-
// Implementation
|
513
|
-
}
|
514
|
-
|
515
|
-
async deleteCustomer(req: Request, res: Response): Promise<void> {
|
516
|
-
// Implementation
|
517
|
-
}
|
518
|
-
}`
|
519
|
-
},
|
520
|
-
{
|
521
|
-
path: 'src/modules/odoo/services/odoo-contact.service.ts',
|
522
|
-
content: `// Odoo Contact Service - Auto-generated by CLI
|
523
|
-
import { IOdooContact, CreateOdooContactDto, UpdateOdooContactDto } from '../entities/odoo-contact.entity';
|
524
|
-
|
525
|
-
export class OdooContactService {
|
526
|
-
async getAllCustomers(): Promise<{ data: IOdooContact[], total: number }> {
|
527
|
-
// Implementation
|
528
|
-
return { data: [], total: 0 };
|
529
|
-
}
|
530
|
-
|
531
|
-
async getCustomerById(customerId: string): Promise<IOdooContact | null> {
|
532
|
-
// Implementation
|
533
|
-
return null;
|
534
|
-
}
|
535
|
-
|
536
|
-
async createCustomer(customerData: CreateOdooContactDto): Promise<IOdooContact> {
|
537
|
-
// Implementation
|
538
|
-
throw new Error('Not implemented');
|
539
|
-
}
|
540
|
-
|
541
|
-
async updateCustomer(customerId: string, updateData: UpdateOdooContactDto): Promise<IOdooContact | null> {
|
542
|
-
// Implementation
|
543
|
-
return null;
|
544
|
-
}
|
545
|
-
|
546
|
-
async deleteCustomer(customerId: string): Promise<boolean> {
|
547
|
-
// Implementation
|
548
|
-
return false;
|
549
|
-
}
|
550
|
-
}`
|
551
|
-
},
|
552
|
-
{
|
553
|
-
path: 'src/modules/odoo/routes/odoo-contact.routes.ts',
|
554
|
-
content: `// Odoo Contact Routes - Auto-generated by CLI
|
555
|
-
import { Router } from 'express';
|
556
|
-
import { OdooContactController } from '../controllers/odoo-contact.controller';
|
557
|
-
|
558
|
-
const router = Router();
|
559
|
-
const odooContactController = new OdooContactController();
|
560
|
-
|
561
|
-
// Customer management routes
|
562
|
-
router.get('/', odooContactController.getAllCustomers.bind(odooContactController));
|
563
|
-
router.get('/:id', odooContactController.getCustomerById.bind(odooContactController));
|
564
|
-
router.post('/', odooContactController.createCustomer.bind(odooContactController));
|
565
|
-
router.put('/:id', odooContactController.updateCustomer.bind(odooContactController));
|
566
|
-
router.delete('/:id', odooContactController.deleteCustomer.bind(odooContactController));
|
567
|
-
|
568
|
-
export default router;`
|
569
|
-
}
|
570
|
-
]
|
571
|
-
},
|
572
|
-
notification: {
|
573
|
-
description: 'Notification system module',
|
574
|
-
files: [
|
575
|
-
{
|
576
|
-
path: 'src/modules/notification/entities/notification.entity.ts',
|
577
|
-
content: `// Notification Entity - Auto-generated by CLI
|
578
|
-
export interface INotification {
|
579
|
-
id: string;
|
580
|
-
userId: string;
|
581
|
-
type: 'email' | 'sms' | 'push';
|
582
|
-
message: string;
|
583
|
-
status: 'pending' | 'sent' | 'failed';
|
584
|
-
createdAt: Date;
|
585
|
-
}`
|
586
|
-
}
|
587
|
-
]
|
588
|
-
}
|
589
|
-
};
|
590
|
-
const module = availableModules[moduleName];
|
591
|
-
if (!module) {
|
592
|
-
console.error(chalk_1.default.red(`❌ Module '${moduleName}' is not available.`));
|
593
|
-
console.log(chalk_1.default.yellow(`Available modules: ${Object.keys(availableModules).join(', ')}`));
|
594
|
-
process.exit(1);
|
595
|
-
}
|
596
|
-
console.log(chalk_1.default.blue(`📝 Creating module: ${moduleName}`));
|
597
|
-
console.log(chalk_1.default.gray(`Description: ${module.description}`));
|
598
|
-
const moduleDir = path.join('src', 'modules', moduleName);
|
599
|
-
fs.mkdirSync(moduleDir, { recursive: true });
|
600
|
-
fs.mkdirSync(path.join(moduleDir, 'controllers'), { recursive: true });
|
601
|
-
fs.mkdirSync(path.join(moduleDir, 'services'), { recursive: true });
|
602
|
-
fs.mkdirSync(path.join(moduleDir, 'routes'), { recursive: true });
|
603
|
-
fs.mkdirSync(path.join(moduleDir, 'entities'), { recursive: true });
|
604
|
-
for (const file of module.files) {
|
605
|
-
const filePath = path.join(file.path);
|
606
|
-
const dir = path.dirname(filePath);
|
607
|
-
fs.mkdirSync(dir, { recursive: true });
|
608
|
-
fs.writeFileSync(filePath, file.content);
|
609
|
-
console.log(chalk_1.default.gray(` Created: ${filePath}`));
|
610
|
-
}
|
611
|
-
const routesIndexPath = 'src/routes/index.ts';
|
612
|
-
if (fs.existsSync(routesIndexPath)) {
|
613
|
-
let routesContent = fs.readFileSync(routesIndexPath, 'utf8');
|
614
|
-
const importStatement = `import ${moduleName}Routes from '../modules/${moduleName}/routes/${moduleName}.routes';`;
|
615
|
-
if (!routesContent.includes(importStatement)) {
|
616
|
-
routesContent = routesContent.replace(/import.*Routes.*from.*routes.*;/g, `$&\n${importStatement}`);
|
617
|
-
}
|
618
|
-
const routeRegistration = `router.use('/${moduleName}', ${moduleName}Routes);`;
|
619
|
-
if (!routesContent.includes(routeRegistration)) {
|
620
|
-
routesContent = routesContent.replace(/router\.use.*Routes.*;/g, `$&\n${routeRegistration}`);
|
621
|
-
}
|
622
|
-
fs.writeFileSync(routesIndexPath, routesContent);
|
623
|
-
console.log(chalk_1.default.gray(` Updated: ${routesIndexPath}`));
|
624
|
-
}
|
625
|
-
console.log(chalk_1.default.green(`✅ Module '${moduleName}' added successfully!`));
|
626
|
-
console.log(chalk_1.default.blue(`🚀 Module is ready to use. You may need to implement the business logic.`));
|
177
|
+
return api;
|
627
178
|
}
|
628
179
|
//# sourceMappingURL=api.js.map
|