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.
Files changed (103) hide show
  1. package/README.md +2 -0
  2. package/cli/index.js +2 -0
  3. package/cli.js +206 -0
  4. package/core/detector/detectAxios.js +107 -0
  5. package/core/detector/detectFetch.js +148 -0
  6. package/core/detector/detectForms.js +55 -0
  7. package/core/detector/detectSocket.js +341 -0
  8. package/core/generator/generateControllers.js +17 -0
  9. package/core/generator/generateModels.js +25 -0
  10. package/core/generator/generateRoutes.js +17 -0
  11. package/core/generator/generateServer.js +18 -0
  12. package/core/generator/generateSocket.js +160 -0
  13. package/core/index.js +14 -0
  14. package/core/ir/IRTypes.js +25 -0
  15. package/core/ir/buildIR.js +83 -0
  16. package/core/parser/parseJS.js +26 -0
  17. package/core/parser/parseTS.js +27 -0
  18. package/core/rules/relationRules.js +38 -0
  19. package/core/rules/resourceRules.js +32 -0
  20. package/core/rules/schemaInference.js +26 -0
  21. package/core/scanner/scanProject.js +58 -0
  22. package/deploy/cloudflare.js +41 -0
  23. package/deploy/cloudflareWorker.js +122 -0
  24. package/deploy/connect.js +198 -0
  25. package/deploy/flyio.js +51 -0
  26. package/deploy/index.js +322 -0
  27. package/deploy/netlify.js +29 -0
  28. package/deploy/railway.js +215 -0
  29. package/deploy/render.js +195 -0
  30. package/deploy/utils.js +383 -0
  31. package/deploy/vercel.js +29 -0
  32. package/index.js +18 -0
  33. package/lib/generator/advancedCrudGenerator.js +475 -0
  34. package/lib/generator/crudCodeGenerator.js +486 -0
  35. package/lib/generator/irBasedGenerator.js +360 -0
  36. package/lib/ir-builder/index.js +16 -0
  37. package/lib/ir-builder/irBuilder.js +330 -0
  38. package/lib/ir-builder/rulesEngine.js +353 -0
  39. package/lib/ir-builder/templateEngine.js +193 -0
  40. package/lib/ir-builder/templates/index.js +14 -0
  41. package/lib/ir-builder/templates/model.template.js +47 -0
  42. package/lib/ir-builder/templates/routes-generic.template.js +66 -0
  43. package/lib/ir-builder/templates/routes-user.template.js +105 -0
  44. package/lib/ir-builder/templates/routes.template.js +102 -0
  45. package/lib/ir-builder/templates/validation.template.js +15 -0
  46. package/lib/ir-integration.js +349 -0
  47. package/lib/modes/benchmark.js +162 -0
  48. package/lib/modes/configBasedGenerator.js +2258 -0
  49. package/lib/modes/connect.js +1125 -0
  50. package/lib/modes/doctorAi.js +172 -0
  51. package/lib/modes/generateApi.js +435 -0
  52. package/lib/modes/interactiveSetup.js +548 -0
  53. package/lib/modes/offline.clean.js +14 -0
  54. package/lib/modes/offline.enhanced.js +787 -0
  55. package/lib/modes/offline.js +295 -0
  56. package/lib/modes/offline.v2.js +13 -0
  57. package/lib/modes/sync.js +629 -0
  58. package/lib/scanner/apiEndpointExtractor.js +387 -0
  59. package/lib/scanner/authPatternDetector.js +54 -0
  60. package/lib/scanner/frontendScanner.js +642 -0
  61. package/lib/utils/apiClientGenerator.js +242 -0
  62. package/lib/utils/apiScanner.js +95 -0
  63. package/lib/utils/codeInjector.js +350 -0
  64. package/lib/utils/doctor.js +381 -0
  65. package/lib/utils/envGenerator.js +36 -0
  66. package/lib/utils/loadTester.js +61 -0
  67. package/lib/utils/performanceAnalyzer.js +298 -0
  68. package/lib/utils/resourceDetector.js +281 -0
  69. package/package.json +20 -0
  70. package/templates/.env.template +31 -0
  71. package/templates/advanced.model.template.js +201 -0
  72. package/templates/advanced.route.template.js +341 -0
  73. package/templates/auth.middleware.template.js +87 -0
  74. package/templates/auth.routes.template.js +238 -0
  75. package/templates/auth.user.model.template.js +78 -0
  76. package/templates/cache.middleware.js +34 -0
  77. package/templates/chat.models.template.js +260 -0
  78. package/templates/chat.routes.template.js +478 -0
  79. package/templates/compression.middleware.js +19 -0
  80. package/templates/database.config.js +74 -0
  81. package/templates/errorHandler.middleware.js +54 -0
  82. package/templates/express/controller.ejs +26 -0
  83. package/templates/express/model.ejs +9 -0
  84. package/templates/express/route.ejs +18 -0
  85. package/templates/express/server.ejs +16 -0
  86. package/templates/frontend.env.template +14 -0
  87. package/templates/model.template.js +86 -0
  88. package/templates/package.production.json +51 -0
  89. package/templates/package.template.json +41 -0
  90. package/templates/pagination.utility.js +110 -0
  91. package/templates/production.server.template.js +233 -0
  92. package/templates/rateLimiter.middleware.js +36 -0
  93. package/templates/requestLogger.middleware.js +19 -0
  94. package/templates/response.helper.js +179 -0
  95. package/templates/route.template.js +130 -0
  96. package/templates/security.middleware.js +78 -0
  97. package/templates/server.template.js +91 -0
  98. package/templates/socket.server.template.js +433 -0
  99. package/templates/utils.helper.js +157 -0
  100. package/templates/validation.middleware.js +63 -0
  101. package/templates/validation.schema.js +128 -0
  102. package/utils/fileWriter.js +15 -0
  103. package/utils/logger.js +18 -0
@@ -0,0 +1,295 @@
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;
15
+
16
+ async function createBackendStructure(backendPath) {
17
+ const dirs = [
18
+ 'routes',
19
+ 'models',
20
+ 'middleware',
21
+ 'config'
22
+ ];
23
+
24
+ for (const dir of dirs) {
25
+ const dirPath = path.join(backendPath, dir);
26
+ if (!fs.existsSync(dirPath)) {
27
+ fs.mkdirSync(dirPath, { recursive: true });
28
+ }
29
+ }
30
+ }
31
+
32
+ /**
33
+ * Recursively read all files in a directory
34
+ */
35
+ function readAllFilesRecursive(dirPath) {
36
+ const files = [];
37
+
38
+ if (!fs.existsSync(dirPath)) {
39
+ return files;
40
+ }
41
+
42
+ const items = fs.readdirSync(dirPath);
43
+
44
+ for (const item of items) {
45
+ const fullPath = path.join(dirPath, item);
46
+ const stat = fs.statSync(fullPath);
47
+
48
+ if (stat.isDirectory()) {
49
+ // Skip node_modules and hidden directories
50
+ if (!item.startsWith('.') && item !== 'node_modules') {
51
+ files.push(...readAllFilesRecursive(fullPath));
52
+ }
53
+ } else if (
54
+ item.endsWith('.js') ||
55
+ item.endsWith('.jsx') ||
56
+ item.endsWith('.ts') ||
57
+ item.endsWith('.tsx') ||
58
+ item.endsWith('.json')
59
+ ) {
60
+ try {
61
+ files.push(fs.readFileSync(fullPath, 'utf8'));
62
+ } catch {
63
+ // Ignore read errors
64
+ }
65
+ }
66
+ }
67
+
68
+ return files;
69
+ }
70
+
71
+ async function copyMiddlewareFiles(backendPath) {
72
+ const middlewareDir = path.join(backendPath, 'middleware');
73
+
74
+ // Copy error handler
75
+ const errorTemplate = fs.readFileSync(
76
+ path.join(TEMPLATES_DIR, 'errorHandler.middleware.js'),
77
+ 'utf8'
78
+ );
79
+ fs.writeFileSync(path.join(middlewareDir, 'errorHandler.js'), errorTemplate);
80
+
81
+ // Copy request logger
82
+ const loggerTemplate = fs.readFileSync(
83
+ path.join(TEMPLATES_DIR, 'requestLogger.middleware.js'),
84
+ 'utf8'
85
+ );
86
+ fs.writeFileSync(path.join(middlewareDir, 'requestLogger.js'), loggerTemplate);
87
+ }
88
+
89
+
90
+
91
+ async function installDependencies(backendPath) {
92
+ const packageTemplate = fs.readFileSync(
93
+ path.join(TEMPLATES_DIR, 'package.template.json'),
94
+ 'utf8'
95
+ );
96
+
97
+ fs.writeFileSync(
98
+ path.join(backendPath, 'package.json'),
99
+ packageTemplate
100
+ );
101
+
102
+ // Install npm packages
103
+ try {
104
+ await execAsync('npm install', { cwd: backendPath });
105
+ } catch (error) {
106
+ console.warn('⚠️ npm install had issues, but backend is ready');
107
+ }
108
+ }
109
+
110
+ /**
111
+ * Generate Auth Setup (User Model + Auth Middleware + Auth Routes)
112
+ */
113
+ async function generateAuthSetup(backendPath) {
114
+ const middlewareDir = path.join(backendPath, 'middleware');
115
+ const modelsDir = path.join(backendPath, 'models');
116
+ const routesDir = path.join(backendPath, 'routes');
117
+
118
+ // Generate standard middleware (error handler, request logger)
119
+ await copyMiddlewareFiles(backendPath);
120
+
121
+ // Generate auth middleware
122
+ const authMiddlewareTemplate = fs.readFileSync(
123
+ path.join(TEMPLATES_DIR, 'auth.middleware.template.js'),
124
+ 'utf8'
125
+ );
126
+ fs.writeFileSync(path.join(middlewareDir, 'auth.js'), authMiddlewareTemplate);
127
+
128
+ // Generate User model
129
+ const userModelTemplate = fs.readFileSync(
130
+ path.join(TEMPLATES_DIR, 'auth.user.model.template.js'),
131
+ 'utf8'
132
+ );
133
+ fs.writeFileSync(path.join(modelsDir, 'User.js'), userModelTemplate);
134
+
135
+ // Generate auth routes
136
+ const authRoutesTemplate = fs.readFileSync(
137
+ path.join(TEMPLATES_DIR, 'auth.routes.template.js'),
138
+ 'utf8'
139
+ );
140
+ fs.writeFileSync(path.join(routesDir, 'auth.routes.js'), authRoutesTemplate);
141
+ }
142
+
143
+ /**
144
+ * Generate .env file with JWT secret
145
+ */
146
+ async function generateEnvFile(backendPath, hasAuth = false) {
147
+ const envContent = hasAuth
148
+ ? generateAuthEnv()
149
+ : fs.readFileSync(path.join(TEMPLATES_DIR, '.env.template'), 'utf8');
150
+
151
+ fs.writeFileSync(path.join(backendPath, '.env'), envContent);
152
+ }
153
+
154
+ /**
155
+ * Generate package.json with proper dependencies
156
+ */
157
+ async function generatePackageJson(backendPath, hasAuth = false) {
158
+ let packageJson = JSON.parse(
159
+ fs.readFileSync(path.join(TEMPLATES_DIR, 'package.template.json'), 'utf8')
160
+ );
161
+
162
+ if (hasAuth) {
163
+ // Ensure auth dependencies are present
164
+ packageJson.dependencies = packageJson.dependencies || {};
165
+ packageJson.dependencies['bcryptjs'] = '^2.4.3';
166
+ packageJson.dependencies['jsonwebtoken'] = '^9.1.0';
167
+ }
168
+
169
+ fs.writeFileSync(
170
+ path.join(backendPath, 'package.json'),
171
+ JSON.stringify(packageJson, null, 2)
172
+ );
173
+ }
174
+
175
+ /**
176
+ * Generate server.js with all routes (auth + CRUD)
177
+ */
178
+ async function generateServerFile(backendPath, hasAuth = false, nonAuthResources = {}) {
179
+ const serverTemplate = fs.readFileSync(
180
+ path.join(TEMPLATES_DIR, 'server.template.js'),
181
+ 'utf8'
182
+ );
183
+
184
+ let routeImports = '';
185
+ let routeRegistrations = '';
186
+
187
+ // Add auth routes if auth is enabled
188
+ if (hasAuth) {
189
+ routeImports += `import authRoutes from './routes/auth.routes.js';\n`;
190
+ routeRegistrations += `app.use('/api/auth', authRoutes);\n\n`;
191
+ }
192
+
193
+ // Add CRUD routes for all resources
194
+ for (const [resourceName] of Object.entries(nonAuthResources)) {
195
+ if (resourceName === 'api') continue;
196
+
197
+ const routesFile = `${resourceName}.routes.js`;
198
+ routeImports += `import ${resourceName}Routes from './routes/${routesFile}';\n`;
199
+ routeRegistrations += `app.use('/api/${resourceName}', ${resourceName}Routes);\n`;
200
+ }
201
+
202
+ const serverContent = serverTemplate.replace(
203
+ /\/\/\s*__ROUTES__|<ROUTES>/,
204
+ (routeImports + routeRegistrations).trim()
205
+ );
206
+
207
+ fs.writeFileSync(path.join(backendPath, 'server.js'), serverContent);
208
+ }
209
+
210
+ function printCompletionInfo(backendPath, hasAuth = false, generatedResources = [], allResources = {}) {
211
+ console.log(chalk.cyan('📦 Generated Backend Structure:\n'));
212
+ console.log(` 📁 ${chalk.bold('backend/')}`);
213
+ console.log(` ├── server.js (Main Express server)`);
214
+ console.log(` ├── .env (Environment config with JWT)`);
215
+ console.log(` ├── package.json (Dependencies)`);
216
+ console.log(` ├── 📁 routes/ (API endpoints)`);
217
+ console.log(` │ ${hasAuth ? '├── auth.routes.js' : ''} (Auth: signup, login, profile, logout)`.replace('├── (', '├── auth.routes.js (').trim());
218
+
219
+ for (const resource of generatedResources) {
220
+ const isLast = resource === generatedResources[generatedResources.length - 1];
221
+ console.log(` │ ${isLast ? '└' : '├'}── ${resource}.routes.js (CRUD: List, Create, Read, Update, Delete)`);
222
+ }
223
+
224
+ console.log(` ├── 📁 models/ (MongoDB schemas)`);
225
+ console.log(` │ ${hasAuth ? '├── User.js' : ''} (User with bcryptjs)`.replace('├──', hasAuth ? '├──' : '└──').trim());
226
+
227
+ for (const resource of generatedResources) {
228
+ const isLast = resource === generatedResources[generatedResources.length - 1];
229
+ const modelName = resource.charAt(0).toUpperCase() + resource.slice(1).replace(/s$/, '');
230
+ console.log(` │ ${isLast && !hasAuth ? '└' : '├'}── ${modelName}.js`);
231
+ }
232
+
233
+ console.log(` ├── 📁 middleware/ (Error handling + Logging${hasAuth ? ' + Auth' : ''})`);
234
+ console.log(` │ ├── errorHandler.js`);
235
+ console.log(` │ ├── requestLogger.js`);
236
+ if (hasAuth) {
237
+ console.log(` │ └── auth.js (JWT verification)`);
238
+ }
239
+ console.log(` └── 📁 config/ (Configuration files)\n`);
240
+
241
+ console.log(chalk.cyan('🚀 Quick Start:\n'));
242
+ console.log(` ${chalk.gray('$')} cd backend`);
243
+ console.log(` ${chalk.gray('$')} npm install # If needed`);
244
+ console.log(` ${chalk.gray('$')} npm start\n`);
245
+
246
+ console.log(chalk.cyan('📝 Generated Features:\n'));
247
+ console.log(` ✅ Express.js server with middleware`);
248
+ console.log(` ✅ MongoDB + Mongoose integration`);
249
+ console.log(` ✅ Auto-generated REST API routes`);
250
+ console.log(` ✅ Complete CRUD operations for all resources`);
251
+ console.log(` ✅ Error handling & request logging`);
252
+ console.log(` ✅ CORS enabled by default`);
253
+ console.log(` ✅ Environment variable support`);
254
+
255
+ if (hasAuth) {
256
+ console.log(` ✅ JWT Authentication (7-day expiry)`);
257
+ console.log(` ✅ Bcrypt password hashing (10 rounds)`);
258
+ console.log(` ✅ User model with validation`);
259
+ console.log(` ✅ Auth middleware for protected routes`);
260
+ }
261
+
262
+ console.log(` ✅ Production-ready structure\n`);
263
+
264
+ if (generatedResources.length > 0) {
265
+ console.log(chalk.green('📊 Generated Resources:\n'));
266
+ for (const resource of generatedResources) {
267
+ const modelName = resource.charAt(0).toUpperCase() + resource.slice(1).replace(/s$/, '');
268
+ console.log(` 📦 ${modelName}`);
269
+ console.log(` Routes: GET /api/${resource}, POST /api/${resource}, GET /api/${resource}/:id`);
270
+ console.log(` PUT /api/${resource}/:id, DELETE /api/${resource}/:id`);
271
+ }
272
+ console.log();
273
+ }
274
+
275
+ if (hasAuth) {
276
+ console.log(chalk.green('🔐 Auth Endpoints:\n'));
277
+ console.log(` POST /api/auth/signup (Register new user)`);
278
+ console.log(` POST /api/auth/login (Login with email & password)`);
279
+ console.log(` GET /api/auth/profile (Get user profile - Protected)`);
280
+ console.log(` PUT /api/auth/profile (Update profile - Protected)`);
281
+ console.log(` POST /api/auth/logout (Logout - Protected)\n`);
282
+ }
283
+
284
+ console.log(chalk.yellow('⚠️ Important:\n'));
285
+ console.log(` 1. MongoDB must be running locally or use MongoDB Atlas`);
286
+ console.log(` 2. Update .env with your database URI if needed`);
287
+ console.log(` 3. Update MONGODB_URI in .env for production`);
288
+ if (hasAuth) {
289
+ console.log(` 4. JWT_SECRET is auto-generated in .env`);
290
+ }
291
+ console.log(` 5. Customize models in backend/models/`);
292
+ console.log(` 6. Update routes in backend/routes/\n`);
293
+
294
+ console.log(chalk.green.bold('🎉 Ready to Deploy!\n'));
295
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Enhanced Offline Mode
3
+ * Exports the production-ready generator
4
+ */
5
+
6
+ import { enhancedOfflineMode } from './offline.enhanced.js';
7
+
8
+ // Main export - uses enhanced production-ready version
9
+ export async function offlineMode(projectPath) {
10
+ return enhancedOfflineMode(projectPath);
11
+ }
12
+
13
+ export default offlineMode;