offbyt 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/cli/index.js +2 -0
- package/cli.js +206 -0
- package/core/detector/detectAxios.js +107 -0
- package/core/detector/detectFetch.js +148 -0
- package/core/detector/detectForms.js +55 -0
- package/core/detector/detectSocket.js +341 -0
- package/core/generator/generateControllers.js +17 -0
- package/core/generator/generateModels.js +25 -0
- package/core/generator/generateRoutes.js +17 -0
- package/core/generator/generateServer.js +18 -0
- package/core/generator/generateSocket.js +160 -0
- package/core/index.js +14 -0
- package/core/ir/IRTypes.js +25 -0
- package/core/ir/buildIR.js +83 -0
- package/core/parser/parseJS.js +26 -0
- package/core/parser/parseTS.js +27 -0
- package/core/rules/relationRules.js +38 -0
- package/core/rules/resourceRules.js +32 -0
- package/core/rules/schemaInference.js +26 -0
- package/core/scanner/scanProject.js +58 -0
- package/deploy/cloudflare.js +41 -0
- package/deploy/cloudflareWorker.js +122 -0
- package/deploy/connect.js +198 -0
- package/deploy/flyio.js +51 -0
- package/deploy/index.js +322 -0
- package/deploy/netlify.js +29 -0
- package/deploy/railway.js +215 -0
- package/deploy/render.js +195 -0
- package/deploy/utils.js +383 -0
- package/deploy/vercel.js +29 -0
- package/index.js +18 -0
- package/lib/generator/advancedCrudGenerator.js +475 -0
- package/lib/generator/crudCodeGenerator.js +486 -0
- package/lib/generator/irBasedGenerator.js +360 -0
- package/lib/ir-builder/index.js +16 -0
- package/lib/ir-builder/irBuilder.js +330 -0
- package/lib/ir-builder/rulesEngine.js +353 -0
- package/lib/ir-builder/templateEngine.js +193 -0
- package/lib/ir-builder/templates/index.js +14 -0
- package/lib/ir-builder/templates/model.template.js +47 -0
- package/lib/ir-builder/templates/routes-generic.template.js +66 -0
- package/lib/ir-builder/templates/routes-user.template.js +105 -0
- package/lib/ir-builder/templates/routes.template.js +102 -0
- package/lib/ir-builder/templates/validation.template.js +15 -0
- package/lib/ir-integration.js +349 -0
- package/lib/modes/benchmark.js +162 -0
- package/lib/modes/configBasedGenerator.js +2258 -0
- package/lib/modes/connect.js +1125 -0
- package/lib/modes/doctorAi.js +172 -0
- package/lib/modes/generateApi.js +435 -0
- package/lib/modes/interactiveSetup.js +548 -0
- package/lib/modes/offline.clean.js +14 -0
- package/lib/modes/offline.enhanced.js +787 -0
- package/lib/modes/offline.js +295 -0
- package/lib/modes/offline.v2.js +13 -0
- package/lib/modes/sync.js +629 -0
- package/lib/scanner/apiEndpointExtractor.js +387 -0
- package/lib/scanner/authPatternDetector.js +54 -0
- package/lib/scanner/frontendScanner.js +642 -0
- package/lib/utils/apiClientGenerator.js +242 -0
- package/lib/utils/apiScanner.js +95 -0
- package/lib/utils/codeInjector.js +350 -0
- package/lib/utils/doctor.js +381 -0
- package/lib/utils/envGenerator.js +36 -0
- package/lib/utils/loadTester.js +61 -0
- package/lib/utils/performanceAnalyzer.js +298 -0
- package/lib/utils/resourceDetector.js +281 -0
- package/package.json +20 -0
- package/templates/.env.template +31 -0
- package/templates/advanced.model.template.js +201 -0
- package/templates/advanced.route.template.js +341 -0
- package/templates/auth.middleware.template.js +87 -0
- package/templates/auth.routes.template.js +238 -0
- package/templates/auth.user.model.template.js +78 -0
- package/templates/cache.middleware.js +34 -0
- package/templates/chat.models.template.js +260 -0
- package/templates/chat.routes.template.js +478 -0
- package/templates/compression.middleware.js +19 -0
- package/templates/database.config.js +74 -0
- package/templates/errorHandler.middleware.js +54 -0
- package/templates/express/controller.ejs +26 -0
- package/templates/express/model.ejs +9 -0
- package/templates/express/route.ejs +18 -0
- package/templates/express/server.ejs +16 -0
- package/templates/frontend.env.template +14 -0
- package/templates/model.template.js +86 -0
- package/templates/package.production.json +51 -0
- package/templates/package.template.json +41 -0
- package/templates/pagination.utility.js +110 -0
- package/templates/production.server.template.js +233 -0
- package/templates/rateLimiter.middleware.js +36 -0
- package/templates/requestLogger.middleware.js +19 -0
- package/templates/response.helper.js +179 -0
- package/templates/route.template.js +130 -0
- package/templates/security.middleware.js +78 -0
- package/templates/server.template.js +91 -0
- package/templates/socket.server.template.js +433 -0
- package/templates/utils.helper.js +157 -0
- package/templates/validation.middleware.js +63 -0
- package/templates/validation.schema.js +128 -0
- package/utils/fileWriter.js +15 -0
- package/utils/logger.js +18 -0
|
@@ -0,0 +1,548 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interactive Setup Module
|
|
3
|
+
* Guides users through configuration selection
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import inquirer from 'inquirer';
|
|
7
|
+
import chalk from 'chalk';
|
|
8
|
+
|
|
9
|
+
export async function getInteractiveSetup() {
|
|
10
|
+
console.log(chalk.cyan('\n╔════════════════════════════════════════╗'));
|
|
11
|
+
console.log(chalk.cyan('�' offbyt - Interactive Setup �''));
|
|
12
|
+
console.log(chalk.cyan('╚════════════════════════════════════════╝\n'));
|
|
13
|
+
|
|
14
|
+
const answers = await inquirer.prompt([
|
|
15
|
+
{
|
|
16
|
+
type: 'list',
|
|
17
|
+
name: 'database',
|
|
18
|
+
message: '📦 Select Database:',
|
|
19
|
+
choices: [
|
|
20
|
+
{ name: 'MongoDB (Mongoose)', value: 'mongodb' },
|
|
21
|
+
{ name: 'PostgreSQL (Sequelize)', value: 'postgresql' },
|
|
22
|
+
{ name: 'MySQL (Sequelize)', value: 'mysql' },
|
|
23
|
+
{ name: 'SQLite (Sequelize)', value: 'sqlite' }
|
|
24
|
+
],
|
|
25
|
+
default: 'mongodb'
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
type: 'list',
|
|
29
|
+
name: 'framework',
|
|
30
|
+
message: '⚙️ Select Backend Framework:',
|
|
31
|
+
choices: [
|
|
32
|
+
{ name: 'Express.js (Recommended)', value: 'express' },
|
|
33
|
+
{ name: 'Fastify (High Performance)', value: 'fastify' },
|
|
34
|
+
{ name: 'NestJS (Enterprise)', value: 'nestjs' }
|
|
35
|
+
],
|
|
36
|
+
default: 'express'
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
type: 'confirm',
|
|
40
|
+
name: 'enableSocket',
|
|
41
|
+
message: '🔌 Enable Realtime Sockets?',
|
|
42
|
+
default: true
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
type: 'confirm',
|
|
46
|
+
name: 'enableAuth',
|
|
47
|
+
message: '🔐 Generate Authentication System?',
|
|
48
|
+
default: true
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
type: 'list',
|
|
52
|
+
name: 'authType',
|
|
53
|
+
message: '🔑 Select Authentication Type:',
|
|
54
|
+
choices: [
|
|
55
|
+
{ name: 'JWT (JSON Web Token)', value: 'jwt' },
|
|
56
|
+
{ name: 'OAuth 2.0', value: 'oauth' },
|
|
57
|
+
{ name: 'Session-Based', value: 'session' }
|
|
58
|
+
],
|
|
59
|
+
when: (answers) => answers.enableAuth,
|
|
60
|
+
default: 'jwt'
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
type: 'confirm',
|
|
64
|
+
name: 'enableValidation',
|
|
65
|
+
message: '✅ Enable Request Validation (Joi)?',
|
|
66
|
+
default: true
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
type: 'confirm',
|
|
70
|
+
name: 'enableCaching',
|
|
71
|
+
message: '⚡ Enable Redis Caching?',
|
|
72
|
+
default: false
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
type: 'confirm',
|
|
76
|
+
name: 'enableLogging',
|
|
77
|
+
message: '📊 Enable Advanced Logging?',
|
|
78
|
+
default: true
|
|
79
|
+
}
|
|
80
|
+
]);
|
|
81
|
+
|
|
82
|
+
return answers;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Display configuration summary
|
|
87
|
+
*/
|
|
88
|
+
export function displaySetupSummary(config) {
|
|
89
|
+
console.log(chalk.cyan('\n✨ Configuration Summary:\n'));
|
|
90
|
+
console.log(chalk.green(` ✔ Database → ${formatDatabase(config.database)}`));
|
|
91
|
+
console.log(chalk.green(` ✔ Framework → ${formatFramework(config.framework)}`));
|
|
92
|
+
console.log(chalk.green(` ✔ Realtime Socket → ${config.enableSocket ? 'Enabled' : 'Disabled'}`));
|
|
93
|
+
console.log(chalk.green(` ✔ Authentication → ${config.enableAuth ? `Enabled (${formatAuth(config.authType)})` : 'Disabled'}`));
|
|
94
|
+
console.log(chalk.green(` ✔ Validation → ${config.enableValidation ? 'Enabled' : 'Disabled'}`));
|
|
95
|
+
console.log(chalk.green(` ✔ Caching → ${config.enableCaching ? 'Enabled (Redis)' : 'Disabled'}`));
|
|
96
|
+
console.log(chalk.green(` ✔ Logging → ${config.enableLogging ? 'Enabled' : 'Disabled'}`));
|
|
97
|
+
console.log(chalk.cyan('\n'));
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function formatDatabase(db) {
|
|
101
|
+
const map = {
|
|
102
|
+
'mongodb': 'MongoDB (Mongoose)',
|
|
103
|
+
'postgresql': 'PostgreSQL (Sequelize)',
|
|
104
|
+
'mysql': 'MySQL (Sequelize)',
|
|
105
|
+
'sqlite': 'SQLite (Sequelize)'
|
|
106
|
+
};
|
|
107
|
+
return map[db] || db;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function formatFramework(fw) {
|
|
111
|
+
const map = {
|
|
112
|
+
'express': 'Express.js',
|
|
113
|
+
'fastify': 'Fastify',
|
|
114
|
+
'nestjs': 'NestJS'
|
|
115
|
+
};
|
|
116
|
+
return map[fw] || fw;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function formatAuth(auth) {
|
|
120
|
+
const map = {
|
|
121
|
+
'jwt': 'JWT',
|
|
122
|
+
'oauth': 'OAuth 2.0',
|
|
123
|
+
'session': 'Session-Based'
|
|
124
|
+
};
|
|
125
|
+
return map[auth] || auth;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Generate dependencies based on configuration
|
|
130
|
+
*/
|
|
131
|
+
export function generateDependencies(config) {
|
|
132
|
+
const dependencies = {
|
|
133
|
+
// Shared runtime dependency
|
|
134
|
+
'dotenv': '^16.0.3'
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
// Framework-specific
|
|
138
|
+
if (config.framework === 'express') {
|
|
139
|
+
Object.assign(dependencies, {
|
|
140
|
+
'express': '^4.18.2',
|
|
141
|
+
'cors': '^2.8.5',
|
|
142
|
+
'helmet': '^7.0.0'
|
|
143
|
+
});
|
|
144
|
+
} else if (config.framework === 'fastify') {
|
|
145
|
+
Object.assign(dependencies, {
|
|
146
|
+
'fastify': '^4.21.0',
|
|
147
|
+
'@fastify/cors': '^8.4.2',
|
|
148
|
+
'@fastify/helmet': '^11.1.1'
|
|
149
|
+
});
|
|
150
|
+
} else if (config.framework === 'nestjs') {
|
|
151
|
+
Object.assign(dependencies, {
|
|
152
|
+
'@nestjs/common': '^10.2.8',
|
|
153
|
+
'@nestjs/config': '^3.2.3',
|
|
154
|
+
'@nestjs/core': '^10.2.8',
|
|
155
|
+
'@nestjs/platform-express': '^10.2.8',
|
|
156
|
+
'reflect-metadata': '^0.1.13',
|
|
157
|
+
'rxjs': '^7.8.1'
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Database
|
|
162
|
+
if (config.database === 'mongodb') {
|
|
163
|
+
Object.assign(dependencies, {
|
|
164
|
+
'mongoose': '^7.5.0'
|
|
165
|
+
});
|
|
166
|
+
if (config.framework === 'nestjs') {
|
|
167
|
+
dependencies['@nestjs/mongoose'] = '^10.0.2';
|
|
168
|
+
}
|
|
169
|
+
} else if (['postgresql', 'mysql', 'sqlite'].includes(config.database)) {
|
|
170
|
+
if (config.framework === 'nestjs') {
|
|
171
|
+
Object.assign(dependencies, {
|
|
172
|
+
'@nestjs/typeorm': '^10.0.1',
|
|
173
|
+
'typeorm': '^0.3.17'
|
|
174
|
+
});
|
|
175
|
+
} else {
|
|
176
|
+
Object.assign(dependencies, {
|
|
177
|
+
'sequelize': '^6.33.0',
|
|
178
|
+
'sequelize-cli': '^6.6.0'
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (config.database === 'postgresql') {
|
|
183
|
+
dependencies['pg'] = '^8.11.1';
|
|
184
|
+
if (config.framework !== 'nestjs') {
|
|
185
|
+
dependencies['pg-hstore'] = '^2.3.4';
|
|
186
|
+
}
|
|
187
|
+
} else if (config.database === 'mysql') {
|
|
188
|
+
dependencies['mysql2'] = '^3.6.0';
|
|
189
|
+
} else if (config.database === 'sqlite') {
|
|
190
|
+
dependencies['sqlite3'] = '^5.1.6';
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Optional features
|
|
195
|
+
if (config.enableSocket) {
|
|
196
|
+
Object.assign(dependencies, {
|
|
197
|
+
'socket.io': '^4.6.1',
|
|
198
|
+
'redis': '^4.6.10'
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
if (config.enableAuth && config.authType === 'jwt') {
|
|
203
|
+
Object.assign(dependencies, {
|
|
204
|
+
'jsonwebtoken': '^9.0.2',
|
|
205
|
+
'bcryptjs': '^2.4.3'
|
|
206
|
+
});
|
|
207
|
+
} else if (config.enableAuth && config.authType === 'oauth') {
|
|
208
|
+
Object.assign(dependencies, {
|
|
209
|
+
'passport': '^0.6.0',
|
|
210
|
+
'passport-google-oauth20': '^2.0.0',
|
|
211
|
+
'passport-facebook': '^3.0.0'
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if (config.enableValidation) {
|
|
216
|
+
if (config.framework === 'nestjs') {
|
|
217
|
+
Object.assign(dependencies, {
|
|
218
|
+
'class-validator': '^0.14.0',
|
|
219
|
+
'class-transformer': '^0.5.1'
|
|
220
|
+
});
|
|
221
|
+
} else {
|
|
222
|
+
dependencies['joi'] = '^17.10.0';
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
if (config.enableCaching) {
|
|
227
|
+
Object.assign(dependencies, {
|
|
228
|
+
'redis': '^4.6.10',
|
|
229
|
+
'ioredis': '^5.3.2'
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
if (config.enableLogging) {
|
|
234
|
+
Object.assign(dependencies, {
|
|
235
|
+
'winston': '^3.10.0',
|
|
236
|
+
'morgan': '^1.10.0'
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
return dependencies;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Get database connection template based on type
|
|
245
|
+
*/
|
|
246
|
+
export function getDatabaseConnectionTemplate(config) {
|
|
247
|
+
if (config.database === 'mongodb') {
|
|
248
|
+
return `
|
|
249
|
+
import mongoose from 'mongoose';
|
|
250
|
+
|
|
251
|
+
export async function connectDatabase() {
|
|
252
|
+
try {
|
|
253
|
+
const mongoUri = process.env.MONGODB_URI || 'mongodb://localhost:27017/offbyt';
|
|
254
|
+
|
|
255
|
+
await mongoose.connect(mongoUri, {
|
|
256
|
+
useNewUrlParser: true,
|
|
257
|
+
useUnifiedTopology: true,
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
console.log('✅ MongoDB Connected');
|
|
261
|
+
} catch (error) {
|
|
262
|
+
console.error('❌ MongoDB Connection Error:', error.message);
|
|
263
|
+
process.exit(1);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
`;
|
|
267
|
+
} else if (config.database === 'postgresql') {
|
|
268
|
+
return `
|
|
269
|
+
import { Sequelize } from 'sequelize';
|
|
270
|
+
|
|
271
|
+
export const sequelize = new Sequelize(
|
|
272
|
+
process.env.DB_NAME || 'offbyt',
|
|
273
|
+
process.env.DB_USER || 'postgres',
|
|
274
|
+
process.env.DB_PASSWORD || 'password',
|
|
275
|
+
{
|
|
276
|
+
host: process.env.DB_HOST || 'localhost',
|
|
277
|
+
port: process.env.DB_PORT || 5432,
|
|
278
|
+
dialect: 'postgres',
|
|
279
|
+
logging: false,
|
|
280
|
+
}
|
|
281
|
+
);
|
|
282
|
+
|
|
283
|
+
export async function connectDatabase() {
|
|
284
|
+
try {
|
|
285
|
+
await sequelize.authenticate();
|
|
286
|
+
console.log('✅ PostgreSQL Connected');
|
|
287
|
+
await sequelize.sync({ alter: true });
|
|
288
|
+
} catch (error) {
|
|
289
|
+
console.error('❌ PostgreSQL Connection Error:', error.message);
|
|
290
|
+
process.exit(1);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
`;
|
|
294
|
+
} else if (config.database === 'mysql') {
|
|
295
|
+
return `
|
|
296
|
+
import { Sequelize } from 'sequelize';
|
|
297
|
+
|
|
298
|
+
export const sequelize = new Sequelize(
|
|
299
|
+
process.env.DB_NAME || 'offbyt',
|
|
300
|
+
process.env.DB_USER || 'root',
|
|
301
|
+
process.env.DB_PASSWORD || 'password',
|
|
302
|
+
{
|
|
303
|
+
host: process.env.DB_HOST || 'localhost',
|
|
304
|
+
port: process.env.DB_PORT || 3306,
|
|
305
|
+
dialect: 'mysql',
|
|
306
|
+
logging: false,
|
|
307
|
+
}
|
|
308
|
+
);
|
|
309
|
+
|
|
310
|
+
export async function connectDatabase() {
|
|
311
|
+
try {
|
|
312
|
+
await sequelize.authenticate();
|
|
313
|
+
console.log('✅ MySQL Connected');
|
|
314
|
+
await sequelize.sync({ alter: true });
|
|
315
|
+
} catch (error) {
|
|
316
|
+
console.error('❌ MySQL Connection Error:', error.message);
|
|
317
|
+
process.exit(1);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
`;
|
|
321
|
+
} else if (config.database === 'sqlite') {
|
|
322
|
+
return `
|
|
323
|
+
import { Sequelize } from 'sequelize';
|
|
324
|
+
import path from 'path';
|
|
325
|
+
|
|
326
|
+
export const sequelize = new Sequelize({
|
|
327
|
+
dialect: 'sqlite',
|
|
328
|
+
storage: path.join(process.cwd(), 'database.sqlite'),
|
|
329
|
+
logging: false,
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
export async function connectDatabase() {
|
|
333
|
+
try {
|
|
334
|
+
await sequelize.authenticate();
|
|
335
|
+
console.log('✅ SQLite Connected');
|
|
336
|
+
await sequelize.sync({ alter: true });
|
|
337
|
+
} catch (error) {
|
|
338
|
+
console.error('❌ SQLite Connection Error:', error.message);
|
|
339
|
+
process.exit(1);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
`;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* Get env file template
|
|
348
|
+
*/
|
|
349
|
+
export function getEnvTemplate(config) {
|
|
350
|
+
let env = `# ========================================
|
|
351
|
+
# offbyt Production-Ready Configuration
|
|
352
|
+
# ========================================
|
|
353
|
+
# WARNING: Never commit this file to version control!
|
|
354
|
+
# Add .env to your .gitignore immediately
|
|
355
|
+
|
|
356
|
+
# ========================================
|
|
357
|
+
# Server Configuration
|
|
358
|
+
# ========================================
|
|
359
|
+
NODE_ENV=development
|
|
360
|
+
PORT=5000
|
|
361
|
+
DEBUG=true
|
|
362
|
+
|
|
363
|
+
# Server URL (Update in production)
|
|
364
|
+
SERVER_URL=http://localhost:5000
|
|
365
|
+
CLIENT_URL=http://localhost:3000
|
|
366
|
+
|
|
367
|
+
# ========================================
|
|
368
|
+
# Database Configuration
|
|
369
|
+
# ========================================
|
|
370
|
+
`;
|
|
371
|
+
|
|
372
|
+
if (config.database === 'mongodb') {
|
|
373
|
+
env += `# MongoDB
|
|
374
|
+
MONGODB_URI=mongodb://localhost:27017/offbyt
|
|
375
|
+
# For MongoDB Atlas (Production):
|
|
376
|
+
# MONGODB_URI=mongodb+srv://<username>:<password>@cluster.mongodb.net/offbyt?retryWrites=true&w=majority
|
|
377
|
+
MONGODB_OPTIONS=retryWrites=true&w=majority
|
|
378
|
+
`;
|
|
379
|
+
} else if (config.database === 'postgresql') {
|
|
380
|
+
env += `# PostgreSQL
|
|
381
|
+
DB_HOST=localhost
|
|
382
|
+
DB_PORT=5432
|
|
383
|
+
DB_NAME=offbyt
|
|
384
|
+
DB_USER=postgres
|
|
385
|
+
DB_PASSWORD=password
|
|
386
|
+
# Connection Pool Settings
|
|
387
|
+
DB_POOL_MIN=2
|
|
388
|
+
DB_POOL_MAX=10
|
|
389
|
+
DB_SSL=false
|
|
390
|
+
`;
|
|
391
|
+
} else if (config.database === 'mysql') {
|
|
392
|
+
env += `# MySQL
|
|
393
|
+
DB_HOST=localhost
|
|
394
|
+
DB_PORT=3306
|
|
395
|
+
DB_NAME=offbyt
|
|
396
|
+
DB_USER=root
|
|
397
|
+
DB_PASSWORD=password
|
|
398
|
+
# Connection Pool Settings
|
|
399
|
+
DB_POOL_MIN=2
|
|
400
|
+
DB_POOL_MAX=10
|
|
401
|
+
DB_SSL=false
|
|
402
|
+
`;
|
|
403
|
+
} else if (config.database === 'sqlite') {
|
|
404
|
+
env += `# SQLite (Auto-created)
|
|
405
|
+
SQLITE_PATH=./database.sqlite
|
|
406
|
+
`;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
if (config.enableAuth && config.authType === 'jwt') {
|
|
410
|
+
env += `
|
|
411
|
+
# ========================================
|
|
412
|
+
# JWT Authentication
|
|
413
|
+
# ========================================
|
|
414
|
+
# CRITICAL: Generate strong secret in production!
|
|
415
|
+
# Use: node -e "console.log(require('crypto').randomBytes(64).toString('hex'))"
|
|
416
|
+
JWT_SECRET=your_jwt_secret_key_here_CHANGE_IN_PRODUCTION_use_64_chars_minimum
|
|
417
|
+
JWT_EXPIRE=7d
|
|
418
|
+
JWT_REFRESH_SECRET=your_refresh_token_secret_DIFFERENT_from_access_token
|
|
419
|
+
JWT_REFRESH_EXPIRE=30d
|
|
420
|
+
|
|
421
|
+
# Token Settings
|
|
422
|
+
ACCESS_TOKEN_EXPIRE=15m
|
|
423
|
+
REFRESH_TOKEN_EXPIRE=30d
|
|
424
|
+
`;
|
|
425
|
+
} else if (config.enableAuth && config.authType === 'oauth') {
|
|
426
|
+
env += `
|
|
427
|
+
# ========================================
|
|
428
|
+
# OAuth Configuration
|
|
429
|
+
# ========================================
|
|
430
|
+
# Google OAuth
|
|
431
|
+
GOOGLE_CLIENT_ID=your_google_client_id
|
|
432
|
+
GOOGLE_CLIENT_SECRET=your_google_client_secret
|
|
433
|
+
GOOGLE_CALLBACK_URL=http://localhost:5000/auth/google/callback
|
|
434
|
+
|
|
435
|
+
# Facebook OAuth
|
|
436
|
+
FACEBOOK_APP_ID=your_facebook_app_id
|
|
437
|
+
FACEBOOK_APP_SECRET=your_facebook_app_secret
|
|
438
|
+
FACEBOOK_CALLBACK_URL=http://localhost:5000/auth/facebook/callback
|
|
439
|
+
`;
|
|
440
|
+
} else if (config.enableAuth && config.authType === 'session') {
|
|
441
|
+
env += `
|
|
442
|
+
# ========================================
|
|
443
|
+
# Session Configuration
|
|
444
|
+
# ========================================
|
|
445
|
+
SESSION_SECRET=your_session_secret_CHANGE_IN_PRODUCTION
|
|
446
|
+
SESSION_NAME=offbyt.sid
|
|
447
|
+
SESSION_MAX_AGE=86400000
|
|
448
|
+
SESSION_SECURE=false
|
|
449
|
+
`;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
if (config.enableCaching) {
|
|
453
|
+
env += `
|
|
454
|
+
# ========================================
|
|
455
|
+
# Redis Cache Configuration
|
|
456
|
+
# ========================================
|
|
457
|
+
REDIS_HOST=localhost
|
|
458
|
+
REDIS_PORT=6379
|
|
459
|
+
REDIS_PASSWORD=
|
|
460
|
+
REDIS_DB=0
|
|
461
|
+
CACHE_TTL=3600
|
|
462
|
+
`;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
// Security Settings
|
|
466
|
+
env += `
|
|
467
|
+
# ========================================
|
|
468
|
+
# Security Configuration
|
|
469
|
+
# ========================================
|
|
470
|
+
# CORS Settings
|
|
471
|
+
CORS_ORIGIN=http://localhost:3000
|
|
472
|
+
# For multiple origins: https://app.com,https://admin.app.com
|
|
473
|
+
CORS_CREDENTIALS=true
|
|
474
|
+
|
|
475
|
+
# Rate Limiting
|
|
476
|
+
RATE_LIMIT_WINDOW=15
|
|
477
|
+
RATE_LIMIT_MAX=100
|
|
478
|
+
|
|
479
|
+
# Request Size Limits
|
|
480
|
+
MAX_JSON_SIZE=10mb
|
|
481
|
+
MAX_URL_ENCODED_SIZE=10mb
|
|
482
|
+
MAX_FILE_SIZE=50mb
|
|
483
|
+
|
|
484
|
+
# Security Headers
|
|
485
|
+
HELMET_ENABLED=true
|
|
486
|
+
`;
|
|
487
|
+
|
|
488
|
+
// Email Settings (if applicable)
|
|
489
|
+
if (config.emailService) {
|
|
490
|
+
env += `
|
|
491
|
+
# ========================================
|
|
492
|
+
# Email Configuration
|
|
493
|
+
# ========================================
|
|
494
|
+
SMTP_HOST=smtp.gmail.com
|
|
495
|
+
SMTP_PORT=587
|
|
496
|
+
SMTP_USER=your-email@gmail.com
|
|
497
|
+
SMTP_PASSWORD=your-app-password
|
|
498
|
+
SMTP_FROM=noreply@yourapp.com
|
|
499
|
+
`;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
// Logging
|
|
503
|
+
env += `
|
|
504
|
+
# ========================================
|
|
505
|
+
# Logging Configuration
|
|
506
|
+
# ========================================
|
|
507
|
+
LOG_LEVEL=info
|
|
508
|
+
LOG_FILE=./logs/app.log
|
|
509
|
+
LOG_ERROR_FILE=./logs/error.log
|
|
510
|
+
`;
|
|
511
|
+
|
|
512
|
+
// API Keys & External Services
|
|
513
|
+
env += `
|
|
514
|
+
# ========================================
|
|
515
|
+
# External Services & API Keys
|
|
516
|
+
# ========================================
|
|
517
|
+
# Add your API keys here
|
|
518
|
+
# AWS_ACCESS_KEY_ID=
|
|
519
|
+
# AWS_SECRET_ACCESS_KEY=
|
|
520
|
+
# STRIPE_SECRET_KEY=
|
|
521
|
+
# SENDGRID_API_KEY=
|
|
522
|
+
# CLOUDINARY_CLOUD_NAME=
|
|
523
|
+
# CLOUDINARY_API_KEY=
|
|
524
|
+
# CLOUDINARY_API_SECRET=
|
|
525
|
+
`;
|
|
526
|
+
|
|
527
|
+
// Production Reminder
|
|
528
|
+
env += `
|
|
529
|
+
# ========================================
|
|
530
|
+
# PRODUCTION DEPLOYMENT CHECKLIST
|
|
531
|
+
# ========================================
|
|
532
|
+
# [ ] Change NODE_ENV to 'production'
|
|
533
|
+
# [ ] Generate secure JWT_SECRET (64+ characters)
|
|
534
|
+
# [ ] Update database credentials
|
|
535
|
+
# [ ] Set proper CORS_ORIGIN
|
|
536
|
+
# [ ] Enable rate limiting
|
|
537
|
+
# [ ] Configure HTTPS
|
|
538
|
+
# [ ] Set SESSION_SECURE=true (if using sessions)
|
|
539
|
+
# [ ] Review and update all API keys
|
|
540
|
+
# [ ] Setup monitoring and logging
|
|
541
|
+
# [ ] Configure backup strategy
|
|
542
|
+
# [ ] Test error handling
|
|
543
|
+
`;
|
|
544
|
+
|
|
545
|
+
return env;
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enhanced Offline Mode v2.0
|
|
3
|
+
* Production-Ready Backend Generation
|
|
4
|
+
* Auto-exports to enhanced generator
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { enhancedOfflineMode } from './offline.enhanced.js';
|
|
8
|
+
|
|
9
|
+
// Main entry point - uses enhanced production-ready generator
|
|
10
|
+
export async function offlineMode(projectPath) {
|
|
11
|
+
return enhancedOfflineMode(projectPath);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export default offlineMode;
|