outlet-orm 4.2.0 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1312 -1199
- package/bin/init.js +379 -221
- package/bin/migrate.js +440 -442
- package/package.json +76 -77
- package/src/Database/DatabaseConnection.js +4 -0
- package/{lib → src}/Migrations/Migration.js +48 -48
- package/{lib → src}/Migrations/MigrationManager.js +326 -326
- package/src/Model.js +1118 -1118
- package/{lib → src}/Schema/Schema.js +790 -790
- package/src/index.js +49 -31
- package/types/index.d.ts +660 -660
- package/lib/Database/DatabaseConnection.js +0 -4
package/bin/init.js
CHANGED
|
@@ -1,221 +1,379 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Script d'initialisation pour le package ORM
|
|
5
|
-
* Ce script aide à configurer rapidement un projet avec l'ORM
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
const fs = require('fs');
|
|
9
|
-
const path = require('path');
|
|
10
|
-
const readline = require('readline');
|
|
11
|
-
|
|
12
|
-
const rl = readline.createInterface({
|
|
13
|
-
input: process.stdin,
|
|
14
|
-
output: process.stdout
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
const question = (query) => new Promise((resolve) => rl.question(query, resolve));
|
|
18
|
-
|
|
19
|
-
async function init() {
|
|
20
|
-
console.log('\n🚀 Bienvenue dans l\'assistant de configuration Outlet ORM!\n');
|
|
21
|
-
|
|
22
|
-
try {
|
|
23
|
-
// Database driver
|
|
24
|
-
console.log('Quel driver de base de données souhaitez-vous utiliser?');
|
|
25
|
-
console.log('1. MySQL');
|
|
26
|
-
console.log('2. PostgreSQL');
|
|
27
|
-
console.log('3. SQLite');
|
|
28
|
-
const driverChoice = await question('\nVotre choix (1-3): ');
|
|
29
|
-
|
|
30
|
-
const drivers = {
|
|
31
|
-
'1': { name: 'mysql', package: 'mysql2', defaultPort: 3306 },
|
|
32
|
-
'2': { name: 'postgres', package: 'pg', defaultPort: 5432 },
|
|
33
|
-
'3': { name: 'sqlite', package: 'sqlite3', defaultPort: null }
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
const selectedDriver = drivers[driverChoice];
|
|
37
|
-
if (!selectedDriver) {
|
|
38
|
-
console.error('❌ Choix invalide!');
|
|
39
|
-
process.exit(1);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// Database configuration
|
|
43
|
-
let config = {
|
|
44
|
-
driver: selectedDriver.name
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
if (selectedDriver.name !== 'sqlite') {
|
|
48
|
-
config.host = await question('Host (localhost): ') || 'localhost';
|
|
49
|
-
config.port = await question(`Port (${selectedDriver.defaultPort}): `) || selectedDriver.defaultPort;
|
|
50
|
-
config.database = await question('Nom de la base de données: ');
|
|
51
|
-
config.user = await question('Utilisateur: ');
|
|
52
|
-
config.password = await question('Mot de passe: ');
|
|
53
|
-
} else {
|
|
54
|
-
config.database = await question('Chemin du fichier SQLite (./database.sqlite): ') || './database.sqlite';
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// Ask to generate a .env file
|
|
58
|
-
const generateEnv = (await question('\nSouhaitez-vous générer un fichier .env avec ces paramètres ? (oui/non) [oui]: ')).trim().toLowerCase();
|
|
59
|
-
const wantEnv = generateEnv === '' || generateEnv === 'oui' || generateEnv === 'o' || generateEnv === 'yes' || generateEnv === 'y';
|
|
60
|
-
|
|
61
|
-
if (wantEnv) {
|
|
62
|
-
const envLines = [];
|
|
63
|
-
envLines.push(`DB_DRIVER=${config.driver}`);
|
|
64
|
-
if (config.driver !== 'sqlite') {
|
|
65
|
-
envLines.push(`DB_HOST=${config.host || 'localhost'}`);
|
|
66
|
-
envLines.push(`DB_PORT=${config.port || selectedDriver.defaultPort || ''}`);
|
|
67
|
-
envLines.push(`DB_USER=${config.user || ''}`);
|
|
68
|
-
envLines.push(`DB_PASSWORD=${config.password || ''}`);
|
|
69
|
-
envLines.push(`DB_DATABASE=${config.database || ''}`);
|
|
70
|
-
} else {
|
|
71
|
-
envLines.push(`DB_FILE=${config.database}`);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
const envPath = path.join(process.cwd(), '.env');
|
|
75
|
-
if (fs.existsSync(envPath)) {
|
|
76
|
-
console.log('ℹ️ .env existe déjà, génération ignorée.');
|
|
77
|
-
} else {
|
|
78
|
-
fs.writeFileSync(envPath, envLines.join('\n') + '\n');
|
|
79
|
-
console.log(`✅ Fichier .env créé: ${envPath}`);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// Generate config file
|
|
84
|
-
const configContent = `const { DatabaseConnection } = require('outlet-orm');
|
|
85
|
-
|
|
86
|
-
// Configuration de la base de données
|
|
87
|
-
const db = new DatabaseConnection(${JSON.stringify(config, null, 2)});
|
|
88
|
-
|
|
89
|
-
module.exports = db;
|
|
90
|
-
`;
|
|
91
|
-
|
|
92
|
-
const configPath = path.join(process.cwd(), 'database.js');
|
|
93
|
-
fs.writeFileSync(configPath, configContent);
|
|
94
|
-
console.log(`\n✅ Fichier de configuration créé: ${configPath}`);
|
|
95
|
-
|
|
96
|
-
// Create project structure directories
|
|
97
|
-
const directories = [
|
|
98
|
-
'
|
|
99
|
-
'database
|
|
100
|
-
'
|
|
101
|
-
'
|
|
102
|
-
'
|
|
103
|
-
'
|
|
104
|
-
'
|
|
105
|
-
'
|
|
106
|
-
'
|
|
107
|
-
'
|
|
108
|
-
'
|
|
109
|
-
'
|
|
110
|
-
'
|
|
111
|
-
'
|
|
112
|
-
'
|
|
113
|
-
'
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
console.log(`
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Script d'initialisation pour le package ORM
|
|
5
|
+
* Ce script aide à configurer rapidement un projet avec l'ORM
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
const readline = require('readline');
|
|
11
|
+
|
|
12
|
+
const rl = readline.createInterface({
|
|
13
|
+
input: process.stdin,
|
|
14
|
+
output: process.stdout
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
const question = (query) => new Promise((resolve) => rl.question(query, resolve));
|
|
18
|
+
|
|
19
|
+
async function init() {
|
|
20
|
+
console.log('\n🚀 Bienvenue dans l\'assistant de configuration Outlet ORM!\n');
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
// Database driver
|
|
24
|
+
console.log('Quel driver de base de données souhaitez-vous utiliser?');
|
|
25
|
+
console.log('1. MySQL');
|
|
26
|
+
console.log('2. PostgreSQL');
|
|
27
|
+
console.log('3. SQLite');
|
|
28
|
+
const driverChoice = await question('\nVotre choix (1-3): ');
|
|
29
|
+
|
|
30
|
+
const drivers = {
|
|
31
|
+
'1': { name: 'mysql', package: 'mysql2', defaultPort: 3306 },
|
|
32
|
+
'2': { name: 'postgres', package: 'pg', defaultPort: 5432 },
|
|
33
|
+
'3': { name: 'sqlite', package: 'sqlite3', defaultPort: null }
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const selectedDriver = drivers[driverChoice];
|
|
37
|
+
if (!selectedDriver) {
|
|
38
|
+
console.error('❌ Choix invalide!');
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Database configuration
|
|
43
|
+
let config = {
|
|
44
|
+
driver: selectedDriver.name
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
if (selectedDriver.name !== 'sqlite') {
|
|
48
|
+
config.host = await question('Host (localhost): ') || 'localhost';
|
|
49
|
+
config.port = await question(`Port (${selectedDriver.defaultPort}): `) || selectedDriver.defaultPort;
|
|
50
|
+
config.database = await question('Nom de la base de données: ');
|
|
51
|
+
config.user = await question('Utilisateur: ');
|
|
52
|
+
config.password = await question('Mot de passe: ');
|
|
53
|
+
} else {
|
|
54
|
+
config.database = await question('Chemin du fichier SQLite (./database.sqlite): ') || './database.sqlite';
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Ask to generate a .env file
|
|
58
|
+
const generateEnv = (await question('\nSouhaitez-vous générer un fichier .env avec ces paramètres ? (oui/non) [oui]: ')).trim().toLowerCase();
|
|
59
|
+
const wantEnv = generateEnv === '' || generateEnv === 'oui' || generateEnv === 'o' || generateEnv === 'yes' || generateEnv === 'y';
|
|
60
|
+
|
|
61
|
+
if (wantEnv) {
|
|
62
|
+
const envLines = [];
|
|
63
|
+
envLines.push(`DB_DRIVER=${config.driver}`);
|
|
64
|
+
if (config.driver !== 'sqlite') {
|
|
65
|
+
envLines.push(`DB_HOST=${config.host || 'localhost'}`);
|
|
66
|
+
envLines.push(`DB_PORT=${config.port || selectedDriver.defaultPort || ''}`);
|
|
67
|
+
envLines.push(`DB_USER=${config.user || ''}`);
|
|
68
|
+
envLines.push(`DB_PASSWORD=${config.password || ''}`);
|
|
69
|
+
envLines.push(`DB_DATABASE=${config.database || ''}`);
|
|
70
|
+
} else {
|
|
71
|
+
envLines.push(`DB_FILE=${config.database}`);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const envPath = path.join(process.cwd(), '.env');
|
|
75
|
+
if (fs.existsSync(envPath)) {
|
|
76
|
+
console.log('ℹ️ .env existe déjà, génération ignorée.');
|
|
77
|
+
} else {
|
|
78
|
+
fs.writeFileSync(envPath, envLines.join('\n') + '\n');
|
|
79
|
+
console.log(`✅ Fichier .env créé: ${envPath}`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Generate config file
|
|
84
|
+
const configContent = `const { DatabaseConnection } = require('outlet-orm');
|
|
85
|
+
|
|
86
|
+
// Configuration de la base de données
|
|
87
|
+
const db = new DatabaseConnection(${JSON.stringify(config, null, 2)});
|
|
88
|
+
|
|
89
|
+
module.exports = db;
|
|
90
|
+
`;
|
|
91
|
+
|
|
92
|
+
const configPath = path.join(process.cwd(), 'database.js');
|
|
93
|
+
fs.writeFileSync(configPath, configContent);
|
|
94
|
+
console.log(`\n✅ Fichier de configuration créé: ${configPath}`);
|
|
95
|
+
|
|
96
|
+
// Create project structure directories
|
|
97
|
+
const directories = [
|
|
98
|
+
'config',
|
|
99
|
+
'database',
|
|
100
|
+
'database/migrations',
|
|
101
|
+
'models',
|
|
102
|
+
'controllers',
|
|
103
|
+
'routes',
|
|
104
|
+
'middlewares',
|
|
105
|
+
'services',
|
|
106
|
+
'utils',
|
|
107
|
+
'validators',
|
|
108
|
+
'public',
|
|
109
|
+
'public/images',
|
|
110
|
+
'public/css',
|
|
111
|
+
'public/js',
|
|
112
|
+
'uploads',
|
|
113
|
+
'logs',
|
|
114
|
+
'src',
|
|
115
|
+
'tests'
|
|
116
|
+
];
|
|
117
|
+
|
|
118
|
+
console.log('\n📁 Création de la structure de projet...');
|
|
119
|
+
for (const dir of directories) {
|
|
120
|
+
const dirPath = path.join(process.cwd(), dir);
|
|
121
|
+
if (!fs.existsSync(dirPath)) {
|
|
122
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
|
123
|
+
console.log(` ✅ ${dir}/`);
|
|
124
|
+
} else {
|
|
125
|
+
console.log(` ⏭️ ${dir}/ (existe déjà)`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Generate .gitignore
|
|
130
|
+
const gitignoreContent = `# Secrets
|
|
131
|
+
.env
|
|
132
|
+
.env.local
|
|
133
|
+
.env.production
|
|
134
|
+
|
|
135
|
+
# Logs
|
|
136
|
+
logs/
|
|
137
|
+
*.log
|
|
138
|
+
|
|
139
|
+
# Uploads
|
|
140
|
+
uploads/
|
|
141
|
+
|
|
142
|
+
# Dependencies
|
|
143
|
+
node_modules/
|
|
144
|
+
|
|
145
|
+
# Build
|
|
146
|
+
dist/
|
|
147
|
+
build/
|
|
148
|
+
|
|
149
|
+
# IDE
|
|
150
|
+
.vscode/
|
|
151
|
+
.idea/
|
|
152
|
+
`;
|
|
153
|
+
|
|
154
|
+
const gitignorePath = path.join(process.cwd(), '.gitignore');
|
|
155
|
+
if (!fs.existsSync(gitignorePath)) {
|
|
156
|
+
fs.writeFileSync(gitignorePath, gitignoreContent);
|
|
157
|
+
console.log(`\n✅ .gitignore créé`);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Generate .env.example
|
|
161
|
+
const envExampleContent = `# Base de données
|
|
162
|
+
DB_DRIVER=mysql
|
|
163
|
+
DB_HOST=localhost
|
|
164
|
+
DB_PORT=3306
|
|
165
|
+
DB_DATABASE=myapp
|
|
166
|
+
DB_USER=your_user
|
|
167
|
+
DB_PASSWORD=your_password
|
|
168
|
+
|
|
169
|
+
# Sécurité
|
|
170
|
+
JWT_SECRET=your_jwt_secret_here
|
|
171
|
+
JWT_EXPIRES_IN=15m
|
|
172
|
+
|
|
173
|
+
# Application
|
|
174
|
+
NODE_ENV=development
|
|
175
|
+
PORT=3000
|
|
176
|
+
|
|
177
|
+
# CORS
|
|
178
|
+
CORS_ORIGIN=http://localhost:3000
|
|
179
|
+
`;
|
|
180
|
+
|
|
181
|
+
const envExamplePath = path.join(process.cwd(), '.env.example');
|
|
182
|
+
if (!fs.existsSync(envExamplePath)) {
|
|
183
|
+
fs.writeFileSync(envExamplePath, envExampleContent);
|
|
184
|
+
console.log(`✅ .env.example créé`);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Generate config/security.js
|
|
188
|
+
const securityConfigContent = `/**
|
|
189
|
+
* Configuration de sécurité
|
|
190
|
+
* npm install helmet express-rate-limit xss-clean hpp
|
|
191
|
+
*/
|
|
192
|
+
|
|
193
|
+
module.exports = {
|
|
194
|
+
// Rate limiting (100 requêtes/15min par IP)
|
|
195
|
+
rateLimit: {
|
|
196
|
+
windowMs: 15 * 60 * 1000,
|
|
197
|
+
max: 100,
|
|
198
|
+
message: { error: 'Trop de requêtes, réessayez plus tard' }
|
|
199
|
+
},
|
|
200
|
+
|
|
201
|
+
// Rate limiting strict pour auth (5 tentatives/15min)
|
|
202
|
+
authRateLimit: {
|
|
203
|
+
windowMs: 15 * 60 * 1000,
|
|
204
|
+
max: 5,
|
|
205
|
+
message: { error: 'Trop de tentatives de connexion' }
|
|
206
|
+
},
|
|
207
|
+
|
|
208
|
+
// CORS
|
|
209
|
+
cors: {
|
|
210
|
+
origin: process.env.CORS_ORIGIN || 'http://localhost:3000',
|
|
211
|
+
credentials: true,
|
|
212
|
+
methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'],
|
|
213
|
+
allowedHeaders: ['Content-Type', 'Authorization']
|
|
214
|
+
},
|
|
215
|
+
|
|
216
|
+
// JWT
|
|
217
|
+
jwt: {
|
|
218
|
+
secret: process.env.JWT_SECRET,
|
|
219
|
+
expiresIn: process.env.JWT_EXPIRES_IN || '15m'
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
`;
|
|
223
|
+
|
|
224
|
+
const securityConfigPath = path.join(process.cwd(), 'config', 'security.js');
|
|
225
|
+
if (!fs.existsSync(securityConfigPath)) {
|
|
226
|
+
fs.writeFileSync(securityConfigPath, securityConfigContent);
|
|
227
|
+
console.log(`✅ config/security.js créé`);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// Generate middlewares/errorHandler.js
|
|
231
|
+
const errorHandlerContent = `/**
|
|
232
|
+
* Gestionnaire d'erreurs centralisé
|
|
233
|
+
*/
|
|
234
|
+
const errorHandler = (err, req, res, next) => {
|
|
235
|
+
console.error(\`[\${new Date().toISOString()}] Error:\`, err);
|
|
236
|
+
|
|
237
|
+
const isDev = process.env.NODE_ENV === 'development';
|
|
238
|
+
|
|
239
|
+
res.status(err.status || 500).json({
|
|
240
|
+
error: isDev ? err.message : 'Erreur serveur',
|
|
241
|
+
stack: isDev ? err.stack : undefined
|
|
242
|
+
});
|
|
243
|
+
};
|
|
244
|
+
|
|
245
|
+
module.exports = errorHandler;
|
|
246
|
+
`;
|
|
247
|
+
|
|
248
|
+
const errorHandlerPath = path.join(process.cwd(), 'middlewares', 'errorHandler.js');
|
|
249
|
+
if (!fs.existsSync(errorHandlerPath)) {
|
|
250
|
+
fs.writeFileSync(errorHandlerPath, errorHandlerContent);
|
|
251
|
+
console.log(`✅ middlewares/errorHandler.js créé`);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// Generate utils/hash.js
|
|
255
|
+
const hashUtilContent = `/**
|
|
256
|
+
* Utilitaires de hachage
|
|
257
|
+
* npm install bcrypt
|
|
258
|
+
*/
|
|
259
|
+
const bcrypt = require('bcrypt');
|
|
260
|
+
|
|
261
|
+
const SALT_ROUNDS = 12;
|
|
262
|
+
|
|
263
|
+
const hashPassword = async (password) => {
|
|
264
|
+
return bcrypt.hash(password, SALT_ROUNDS);
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
const verifyPassword = async (password, hash) => {
|
|
268
|
+
return bcrypt.compare(password, hash);
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
module.exports = { hashPassword, verifyPassword };
|
|
272
|
+
`;
|
|
273
|
+
|
|
274
|
+
const hashUtilPath = path.join(process.cwd(), 'utils', 'hash.js');
|
|
275
|
+
if (!fs.existsSync(hashUtilPath)) {
|
|
276
|
+
fs.writeFileSync(hashUtilPath, hashUtilContent);
|
|
277
|
+
console.log(`✅ utils/hash.js créé`);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// Generate example model
|
|
281
|
+
const modelContent = `const { Model } = require('outlet-orm');
|
|
282
|
+
const db = require('./database');
|
|
283
|
+
|
|
284
|
+
class User extends Model {
|
|
285
|
+
static table = 'users';
|
|
286
|
+
static fillable = ['name', 'email', 'password'];
|
|
287
|
+
static hidden = ['password', 'refresh_token']; // 🔒 Ne jamais exposer
|
|
288
|
+
static casts = {
|
|
289
|
+
id: 'int',
|
|
290
|
+
email_verified: 'boolean'
|
|
291
|
+
};
|
|
292
|
+
static rules = {
|
|
293
|
+
name: 'required|string|min:2|max:100',
|
|
294
|
+
email: 'required|email',
|
|
295
|
+
password: 'required|min:8'
|
|
296
|
+
};
|
|
297
|
+
static connection = db;
|
|
298
|
+
|
|
299
|
+
// Définissez vos relations ici
|
|
300
|
+
// posts() {
|
|
301
|
+
// return this.hasMany(Post, 'user_id');
|
|
302
|
+
// }
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
module.exports = User;
|
|
306
|
+
`;
|
|
307
|
+
|
|
308
|
+
const modelPath = path.join(process.cwd(), 'User.js');
|
|
309
|
+
fs.writeFileSync(modelPath, modelContent);
|
|
310
|
+
console.log(`✅ Modèle exemple créé: ${modelPath}`);
|
|
311
|
+
|
|
312
|
+
// Generate usage example
|
|
313
|
+
const usageContent = `const User = require('./User');
|
|
314
|
+
|
|
315
|
+
async function main() {
|
|
316
|
+
try {
|
|
317
|
+
// Exemple: Créer un utilisateur
|
|
318
|
+
const user = await User.create({
|
|
319
|
+
name: 'John Doe',
|
|
320
|
+
email: 'john@example.com',
|
|
321
|
+
password: 'secret123'
|
|
322
|
+
});
|
|
323
|
+
console.log('Utilisateur créé:', user.toJSON());
|
|
324
|
+
|
|
325
|
+
// Exemple: Rechercher des utilisateurs
|
|
326
|
+
const users = await User.all();
|
|
327
|
+
console.log('Tous les utilisateurs:', users.length);
|
|
328
|
+
|
|
329
|
+
// Exemple: Requête avec conditions
|
|
330
|
+
const activeUsers = await User
|
|
331
|
+
.where('status', 'active')
|
|
332
|
+
.orderBy('name')
|
|
333
|
+
.get();
|
|
334
|
+
console.log('Utilisateurs actifs:', activeUsers.length);
|
|
335
|
+
|
|
336
|
+
} catch (error) {
|
|
337
|
+
console.error('Erreur:', error.message);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
main();
|
|
342
|
+
`;
|
|
343
|
+
|
|
344
|
+
const usagePath = path.join(process.cwd(), 'example.js');
|
|
345
|
+
fs.writeFileSync(usagePath, usageContent);
|
|
346
|
+
console.log(`✅ Exemple d'utilisation créé: ${usagePath}`);
|
|
347
|
+
|
|
348
|
+
// Optionally skip package init/install in non-interactive or test context
|
|
349
|
+
const skipInstall = process.env.OUTLET_INIT_NO_INSTALL === '1';
|
|
350
|
+
if (!skipInstall) {
|
|
351
|
+
// Check if package needs to be installed
|
|
352
|
+
const packageJsonPath = path.join(process.cwd(), 'package.json');
|
|
353
|
+
if (!fs.existsSync(packageJsonPath)) {
|
|
354
|
+
console.log('\n⚠️ Aucun package.json trouvé. Initialisation...');
|
|
355
|
+
require('child_process').execSync('npm init -y', { stdio: 'inherit' });
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
console.log(`\n📦 Installation du driver ${selectedDriver.package}...`);
|
|
359
|
+
require('child_process').execSync(`npm install ${selectedDriver.package}`, { stdio: 'inherit' });
|
|
360
|
+
} else {
|
|
361
|
+
console.log('\n⏭️ Installation du driver ignorée (OUTLET_INIT_NO_INSTALL=1).');
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
console.log('\n✨ Configuration terminée!\n');
|
|
365
|
+
console.log('Prochaines étapes:');
|
|
366
|
+
console.log('1. Créez votre schéma de base de données');
|
|
367
|
+
console.log('2. Modifiez User.js selon vos besoins');
|
|
368
|
+
console.log('3. Exécutez example.js: node example.js');
|
|
369
|
+
console.log('\n📚 Documentation: https://github.com/yourusername/outlet-orm');
|
|
370
|
+
|
|
371
|
+
} catch (error) {
|
|
372
|
+
console.error('\n❌ Erreur:', error.message);
|
|
373
|
+
process.exit(1);
|
|
374
|
+
} finally {
|
|
375
|
+
rl.close();
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
init();
|