baraqex 1.0.47 → 1.0.49

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 (28) hide show
  1. package/dist/index.js +236 -189
  2. package/dist/index.js.map +4 -4
  3. package/dist/server.js +1282 -864
  4. package/dist/server.js.map +4 -4
  5. package/package.json +1 -1
  6. package/templates/fullstack-template/package-lock.json +931 -4
  7. package/templates/fullstack-template/package.json +7 -5
  8. package/templates/fullstack-template/server.js +548 -15
  9. package/templates/fullstack-template/src/api/hello.js +9 -11
  10. package/templates/fullstack-template/src/pages/index.js +196 -114
  11. package/templates/fullstack-app/package-lock.json +0 -3683
  12. package/templates/fullstack-app/package.json +0 -26
  13. package/templates/fullstack-app/public/client.js +0 -139
  14. package/templates/fullstack-app/public/fullstack-styles.css +0 -445
  15. package/templates/fullstack-app/server.js +0 -32
  16. package/templates/fullstack-app/src/api/auth.js +0 -48
  17. package/templates/fullstack-app/src/api/users.js +0 -85
  18. package/templates/fullstack-app/src/pages/index.js +0 -0
  19. package/templates/fullstack-app/src/pages/index.jsx +0 -181
  20. package/templates/fullstack-app/src/pages/login.js +0 -139
  21. package/templates/fullstack-app/src/pages/login.jsx +0 -150
  22. package/templates/fullstack-template/public/client.js +0 -17
  23. package/templates/fullstack-template/src/api/users/index.js +0 -43
  24. package/templates/go-wasm-app/package.json +0 -24
  25. package/templates/go-wasm-app/public/wasm-styles.css +0 -184
  26. package/templates/go-wasm-app/server.js +0 -36
  27. package/templates/go-wasm-app/src/pages/index.jsx +0 -161
  28. package/templates/go-wasm-app/src/wasm/main.go +0 -164
package/dist/server.js CHANGED
@@ -1,4 +1,7 @@
1
1
  var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
2
5
  var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
3
6
  get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
4
7
  }) : x)(function(x) {
@@ -6,524 +9,116 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
6
9
  return require.apply(this, arguments);
7
10
  throw Error('Dynamic require of "' + x + '" is not supported');
8
11
  });
12
+ var __esm = (fn, res) => function __init() {
13
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
14
+ };
9
15
  var __export = (target, all) => {
10
16
  for (var name in all)
11
17
  __defProp(target, name, { get: all[name], enumerable: true });
12
18
  };
13
-
14
- // src/server/index.ts
15
- import path4 from "path";
16
- import fs4 from "fs";
17
- import { renderToString } from "frontend-hamroun";
18
-
19
- // src/server/database.ts
20
- var Database = class {
21
- constructor(config) {
22
- this.mongoClient = null;
23
- this.mongoDb = null;
24
- this.mysqlPool = null;
25
- this.pgPool = null;
26
- this.config = config;
27
- }
28
- async connect() {
29
- switch (this.config.type) {
30
- case "mongodb":
31
- await this.connectMongo();
32
- break;
33
- case "mysql":
34
- await this.connectMysql();
35
- break;
36
- case "postgres":
37
- await this.connectPostgres();
38
- break;
39
- default:
40
- throw new Error(`Unsupported database type: ${this.config.type}`);
41
- }
42
- }
43
- async connectMongo() {
44
- try {
45
- const { MongoClient } = await import("mongodb");
46
- this.mongoClient = new MongoClient(this.config.url);
47
- await this.mongoClient.connect();
48
- this.mongoDb = this.mongoClient.db();
49
- console.log("Connected to MongoDB");
50
- } catch (error) {
51
- if (error.code === "MODULE_NOT_FOUND") {
52
- throw new Error("MongoDB driver not installed. Run: npm install mongodb");
53
- }
54
- console.error("MongoDB connection error:", error);
55
- throw error;
56
- }
57
- }
58
- async connectMysql() {
59
- try {
60
- const mysql = await import("mysql2/promise");
61
- this.mysqlPool = mysql.createPool(this.config.url);
62
- await this.mysqlPool.getConnection();
63
- console.log("Connected to MySQL");
64
- } catch (error) {
65
- if (error.code === "MODULE_NOT_FOUND") {
66
- throw new Error("MySQL driver not installed. Run: npm install mysql2");
67
- }
68
- console.error("MySQL connection error:", error);
69
- throw error;
70
- }
71
- }
72
- async connectPostgres() {
73
- try {
74
- const pg = await import("pg");
75
- this.pgPool = new pg.Pool({ connectionString: this.config.url });
76
- const client = await this.pgPool.connect();
77
- client.release();
78
- console.log("Connected to PostgreSQL");
79
- } catch (error) {
80
- if (error.code === "MODULE_NOT_FOUND") {
81
- throw new Error("PostgreSQL driver not installed. Run: npm install pg @types/pg");
82
- }
83
- console.error("PostgreSQL connection error:", error);
84
- throw error;
85
- }
86
- }
87
- async disconnect() {
88
- if (this.mongoClient) {
89
- await this.mongoClient.close();
90
- this.mongoClient = null;
91
- this.mongoDb = null;
92
- }
93
- if (this.mysqlPool) {
94
- await this.mysqlPool.end();
95
- this.mysqlPool = null;
96
- }
97
- if (this.pgPool) {
98
- await this.pgPool.end();
99
- this.pgPool = null;
100
- }
101
- }
102
- // Database-specific methods
103
- getMongoDb() {
104
- return this.mongoDb;
105
- }
106
- getMysqlPool() {
107
- return this.mysqlPool;
108
- }
109
- getPgPool() {
110
- return this.pgPool;
111
- }
112
- // Generic query method
113
- async query(sql, values) {
114
- switch (this.config.type) {
115
- case "mongodb":
116
- throw new Error("For MongoDB, use getMongoDb() instead of query()");
117
- case "mysql":
118
- if (!this.mysqlPool)
119
- throw new Error("MySQL not connected");
120
- const [rows] = await this.mysqlPool.execute(sql, values || []);
121
- return rows;
122
- case "postgres":
123
- if (!this.pgPool)
124
- throw new Error("PostgreSQL not connected");
125
- const result = await this.pgPool.query(sql, values || []);
126
- return result.rows;
127
- default:
128
- throw new Error(`Unsupported database type: ${this.config.type}`);
129
- }
130
- }
131
- };
132
-
133
- // src/server/auth.ts
134
- var AuthService = class {
135
- constructor(config) {
136
- this.config = {
137
- expiresIn: "24h",
138
- ...config
139
- };
140
- }
141
- async hashPassword(password) {
142
- try {
143
- const bcrypt = await import("bcryptjs");
144
- return bcrypt.hash(password, 10);
145
- } catch (error) {
146
- if (error.code === "MODULE_NOT_FOUND") {
147
- throw new Error("bcryptjs not installed. Run: npm install bcryptjs @types/bcryptjs");
148
- }
149
- throw error;
150
- }
151
- }
152
- async comparePasswords(password, hashedPassword) {
153
- try {
154
- const bcrypt = await import("bcryptjs");
155
- return bcrypt.compare(password, hashedPassword);
156
- } catch (error) {
157
- if (error.code === "MODULE_NOT_FOUND") {
158
- throw new Error("bcryptjs not installed. Run: npm install bcryptjs @types/bcryptjs");
159
- }
160
- throw error;
161
- }
162
- }
163
- generateToken(user) {
164
- try {
165
- const jwt = __require("jsonwebtoken");
166
- const options = {};
167
- if (this.config.expiresIn) {
168
- options.expiresIn = this.config.expiresIn;
169
- }
170
- return jwt.sign(
171
- { id: user.id, username: user.username, roles: user.roles || [] },
172
- this.config.secret,
173
- options
174
- );
175
- } catch (error) {
176
- if (error.code === "MODULE_NOT_FOUND") {
177
- throw new Error("jsonwebtoken not installed. Run: npm install jsonwebtoken @types/jsonwebtoken");
178
- }
179
- throw error;
180
- }
181
- }
182
- verifyToken(token) {
183
- try {
184
- const jwt = __require("jsonwebtoken");
185
- return jwt.verify(token, this.config.secret);
186
- } catch (error) {
187
- if (error.code === "MODULE_NOT_FOUND") {
188
- throw new Error("jsonwebtoken not installed. Run: npm install jsonwebtoken @types/jsonwebtoken");
189
- }
190
- return null;
191
- }
192
- }
193
- // Express middleware for authentication
194
- initialize() {
195
- return (req, res, next) => {
196
- const token = this.extractToken(req);
197
- if (token) {
198
- const decoded = this.verifyToken(token);
199
- if (decoded) {
200
- req.user = decoded;
201
- }
202
- }
203
- next();
204
- };
205
- }
206
- // Express middleware for requiring authentication
207
- requireAuth() {
208
- return (req, res, next) => {
209
- if (!req.user) {
210
- return res.status(401).json({ message: "Unauthorized" });
211
- }
212
- return next();
213
- };
214
- }
215
- // Express middleware for requiring specific roles
216
- requireRoles(roles) {
217
- return (req, res, next) => {
218
- if (!req.user) {
219
- return res.status(401).json({ message: "Unauthorized" });
220
- }
221
- const userRoles = req.user.roles || [];
222
- const hasRequiredRole = roles.some((role) => userRoles.includes(role));
223
- if (!hasRequiredRole) {
224
- return res.status(403).json({ message: "Forbidden" });
225
- }
226
- return next();
227
- };
228
- }
229
- extractToken(req) {
230
- if (req.headers.authorization && req.headers.authorization.startsWith("Bearer ")) {
231
- return req.headers.authorization.substring(7);
232
- }
233
- return null;
19
+ var __copyProps = (to, from, except, desc) => {
20
+ if (from && typeof from === "object" || typeof from === "function") {
21
+ for (let key of __getOwnPropNames(from))
22
+ if (!__hasOwnProp.call(to, key) && key !== except)
23
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
234
24
  }
25
+ return to;
235
26
  };
27
+ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
236
28
 
237
- // src/server/api-router.ts
238
- import path from "path";
239
- import fs from "fs";
240
- import { pathToFileURL } from "url";
241
- var ApiRouter = class {
242
- constructor(apiDir, auth = null) {
243
- this.router = null;
244
- this.apiDir = path.resolve(process.cwd(), apiDir);
245
- this.auth = auth;
246
- this.initializeRouter();
247
- }
248
- async initializeRouter() {
249
- try {
250
- const express = await import("express");
251
- this.router = express.default.Router();
252
- this.setupRoutes();
253
- } catch (error) {
254
- if (error.code === "MODULE_NOT_FOUND") {
255
- throw new Error("Express not installed. Run: npm install express @types/express");
256
- }
257
- throw error;
258
- }
29
+ // src/wasm.ts
30
+ async function loadGoWasm(wasmUrl, options = {}) {
31
+ if (typeof window === "undefined") {
32
+ throw new Error("loadGoWasm() is for browser use only. Use loadGoWasmFromFile() in Node.js.");
259
33
  }
260
- setupRoutes() {
261
- if (!fs.existsSync(this.apiDir)) {
262
- console.log(`API directory not found: ${this.apiDir}`);
263
- return;
34
+ try {
35
+ if (!window.Go) {
36
+ throw new Error("Go WASM runtime not available. Make sure wasm_exec.js is loaded.");
264
37
  }
265
- this.scanDirectory(this.apiDir, "");
266
- }
267
- scanDirectory(dirPath, routePrefix) {
268
- const entries = fs.readdirSync(dirPath, { withFileTypes: true });
269
- for (const entry of entries) {
270
- const fullPath = path.join(dirPath, entry.name);
271
- if (entry.isDirectory()) {
272
- this.scanDirectory(fullPath, `${routePrefix}/${entry.name}`);
273
- } else if (this.isRouteFile(entry.name)) {
274
- const routePath = this.getRoutePath(entry.name, routePrefix);
275
- this.registerRoute(fullPath, routePath);
276
- }
38
+ if (options.debug) {
39
+ console.log("[WASM] Loading WASM from:", wasmUrl);
277
40
  }
278
- }
279
- isRouteFile(filename) {
280
- return filename.endsWith(".js") || filename.endsWith(".ts") || filename.endsWith(".mjs");
281
- }
282
- getRoutePath(filename, routePrefix) {
283
- const baseName = path.basename(filename, path.extname(filename));
284
- if (baseName === "index") {
285
- return routePrefix || "/";
41
+ const response = await fetch(wasmUrl);
42
+ if (!response.ok) {
43
+ throw new Error(`Failed to fetch WASM file: ${response.status}`);
286
44
  }
287
- const paramMatch = baseName.match(/^\[(.+)\]$/);
288
- if (paramMatch) {
289
- return `${routePrefix}/:${paramMatch[1]}`;
45
+ const wasmBytes = await response.arrayBuffer();
46
+ const go = new window.Go();
47
+ const wasmModule = await WebAssembly.instantiate(wasmBytes, go.importObject);
48
+ go.run(wasmModule.instance);
49
+ await new Promise((resolve) => setTimeout(resolve, 100));
50
+ if (options.debug) {
51
+ console.log("[WASM] Go program started, checking for registered functions...");
290
52
  }
291
- return `${routePrefix}/${baseName}`;
292
- }
293
- async registerRoute(filePath, routePath) {
294
- try {
295
- const absolutePath = path.isAbsolute(filePath) ? filePath : path.resolve(filePath);
296
- const fileUrl = pathToFileURL(absolutePath).href;
297
- if (process.platform === "win32") {
298
- const urlWithTimestamp = `${fileUrl}?t=${Date.now()}`;
299
- const routeModule = await import(urlWithTimestamp);
300
- if (!this.isValidRouteModule(routeModule)) {
301
- console.warn(`Invalid route module: ${filePath}`);
302
- return;
303
- }
304
- console.log(`Registering API route: ${routePath}`);
305
- const middleware = routeModule.middleware || [];
306
- for (const method of ["get", "post", "put", "delete", "patch", "options"]) {
307
- const handler = routeModule[method];
308
- if (typeof handler === "function") {
309
- const routerMethod = this.router[method];
310
- routerMethod.call(
311
- this.router,
312
- routePath,
313
- ...middleware,
314
- this.wrapHandler(handler)
315
- );
316
- }
317
- }
318
- } else {
319
- const routeModule = await import(fileUrl);
320
- if (!this.isValidRouteModule(routeModule)) {
321
- console.warn(`Invalid route module: ${filePath}`);
322
- return;
323
- }
324
- console.log(`Registering API route: ${routePath}`);
325
- const middleware = routeModule.middleware || [];
326
- for (const method of ["get", "post", "put", "delete", "patch", "options"]) {
327
- const handler = routeModule[method];
328
- if (typeof handler === "function") {
329
- const routerMethod = this.router[method];
330
- routerMethod.call(
331
- this.router,
332
- routePath,
333
- ...middleware,
334
- this.wrapHandler(handler)
335
- );
336
- }
53
+ const functions = {};
54
+ for (const key in window) {
55
+ if (typeof window[key] === "function" && key.startsWith("go")) {
56
+ functions[key] = window[key];
57
+ if (options.debug) {
58
+ console.log(`[WASM] Found function: ${key}`);
337
59
  }
338
60
  }
339
- } catch (error) {
340
- console.error(`Error registering route (${filePath}):`, error);
341
61
  }
342
- }
343
- isValidRouteModule(module) {
344
- if (!module)
345
- return false;
346
- return ["get", "post", "put", "delete", "patch", "options"].some((method) => typeof module[method] === "function");
347
- }
348
- wrapHandler(handler) {
349
- return async (req, res, next) => {
350
- try {
351
- await handler(req, res, next);
352
- } catch (error) {
353
- next(error);
354
- }
62
+ const wasmInstance = {
63
+ instance: wasmModule.instance,
64
+ module: wasmModule,
65
+ exports: wasmModule.instance.exports,
66
+ functions
355
67
  };
356
- }
357
- };
358
-
359
- // src/server/middleware.ts
360
- var requestLogger = (req, res, next) => {
361
- console.log(`${(/* @__PURE__ */ new Date()).toISOString()} - ${req.method} ${req.url}`);
362
- next();
363
- };
364
- var errorHandler = (err, req, res, next) => {
365
- console.error(err.stack);
366
- res.status(500).json({
367
- error: {
368
- message: "Internal Server Error",
369
- ...process.env.NODE_ENV !== "production" ? { details: err.message, stack: err.stack } : {}
370
- }
371
- });
372
- };
373
- var notFoundHandler = (req, res) => {
374
- res.status(404).json({
375
- error: {
376
- message: `Not Found - ${req.method} ${req.url}`
68
+ if (options.onLoad) {
69
+ options.onLoad(wasmInstance);
377
70
  }
378
- });
379
- };
380
- function rateLimit(options) {
381
- const requests = /* @__PURE__ */ new Map();
382
- return (req, res, next) => {
383
- const ip = req.ip || req.socket.remoteAddress || "unknown";
384
- const now = Date.now();
385
- const reqTimes = (requests.get(ip) || []).filter((time) => now - time < options.windowMs);
386
- reqTimes.push(now);
387
- requests.set(ip, reqTimes);
388
- if (reqTimes.length > options.max) {
389
- return res.status(429).json({
390
- error: {
391
- message: "Too Many Requests",
392
- retryAfter: Math.ceil(options.windowMs / 1e3)
393
- }
394
- });
71
+ if (options.debug) {
72
+ console.log(`[WASM] Module loaded successfully with ${Object.keys(functions).length} functions`);
395
73
  }
396
- return next();
397
- };
398
- }
399
-
400
- // src/server/utils.ts
401
- var utils_exports = {};
402
- __export(utils_exports, {
403
- ensureDirectory: () => ensureDirectory,
404
- generateToken: () => generateToken,
405
- getEnvironmentInfo: () => getEnvironmentInfo,
406
- getPagination: () => getPagination,
407
- hashString: () => hashString,
408
- isDirectoryEmpty: () => isDirectoryEmpty,
409
- readJsonFile: () => readJsonFile,
410
- safeJsonParse: () => safeJsonParse,
411
- sendError: () => sendError,
412
- sendSuccess: () => sendSuccess,
413
- validateFields: () => validateFields,
414
- validateFileUpload: () => validateFileUpload,
415
- writeJsonFile: () => writeJsonFile
416
- });
417
- import crypto from "crypto";
418
- import fs2 from "fs/promises";
419
- import path2 from "path";
420
- function safeJsonParse(json, fallback) {
421
- try {
422
- return JSON.parse(json);
74
+ return wasmInstance;
423
75
  } catch (error) {
424
- return fallback;
425
- }
426
- }
427
- function generateToken(length = 32) {
428
- return crypto.randomBytes(length).toString("hex");
429
- }
430
- function hashString(input, salt = "") {
431
- return crypto.createHash("sha256").update(input + salt).digest("hex");
432
- }
433
- function getPagination(req) {
434
- const page = Math.max(1, parseInt(req.query.page) || 1);
435
- const rawLimit = parseInt(req.query.limit);
436
- let limit;
437
- if (isNaN(rawLimit) || rawLimit <= 0) {
438
- limit = 20;
439
- } else {
440
- limit = Math.max(1, Math.min(100, rawLimit));
76
+ console.error("[WASM] Error loading Go WASM module:", error);
77
+ throw error;
441
78
  }
442
- const skip = (page - 1) * limit;
443
- return { page, limit, skip };
444
- }
445
- function sendSuccess(res, data, message = "Success") {
446
- return res.json({
447
- success: true,
448
- message,
449
- data
450
- });
451
- }
452
- function sendError(res, message = "An error occurred", statusCode = 400, errors) {
453
- return res.status(statusCode).json({
454
- success: false,
455
- message,
456
- errors: errors || void 0
457
- });
458
- }
459
- function validateFields(req, requiredFields) {
460
- const missing = requiredFields.filter((field) => {
461
- const value = req.body[field];
462
- return value === void 0 || value === null || value === "";
463
- });
464
- return {
465
- valid: missing.length === 0,
466
- missing
467
- };
468
79
  }
469
- function validateFileUpload(file, options = {}) {
470
- if (!file) {
471
- return { valid: false, error: "No file provided" };
472
- }
473
- if (options.maxSize && file.size > options.maxSize) {
474
- return {
475
- valid: false,
476
- error: `File too large. Maximum size allowed is ${options.maxSize / 1024 / 1024}MB`
477
- };
80
+ function callWasmFunction(funcName, ...args) {
81
+ if (typeof window === "undefined") {
82
+ throw new Error("callWasmFunction() is for browser use only.");
478
83
  }
479
- if (options.allowedTypes && options.allowedTypes.length > 0) {
480
- const fileType = file.mimetype;
481
- if (!options.allowedTypes.includes(fileType)) {
482
- return {
483
- valid: false,
484
- error: `Invalid file type. Allowed types: ${options.allowedTypes.join(", ")}`
485
- };
486
- }
84
+ const func = window[funcName];
85
+ if (typeof func !== "function") {
86
+ throw new Error(`Function ${funcName} not found. Make sure the WASM module is loaded.`);
487
87
  }
488
- return { valid: true };
88
+ return func(...args);
489
89
  }
490
- function getEnvironmentInfo() {
491
- return {
492
- nodeVersion: process.version,
493
- platform: process.platform,
494
- arch: process.arch,
495
- memory: process.memoryUsage(),
496
- uptime: process.uptime(),
497
- env: process.env.NODE_ENV || "development"
498
- };
499
- }
500
- async function isDirectoryEmpty(dirPath) {
501
- try {
502
- const files = await fs2.readdir(dirPath);
503
- return files.length === 0;
504
- } catch (error) {
505
- return true;
90
+ function isWasmReady() {
91
+ if (typeof window === "undefined") {
92
+ return false;
506
93
  }
94
+ return !!(window.Go && Object.keys(window).some(
95
+ (key) => key.startsWith("go") && typeof window[key] === "function"
96
+ ));
507
97
  }
508
- async function ensureDirectory(dirPath) {
509
- try {
510
- await fs2.access(dirPath);
511
- } catch (error) {
512
- await fs2.mkdir(dirPath, { recursive: true });
98
+ function getWasmFunctions() {
99
+ if (typeof window === "undefined") {
100
+ return [];
513
101
  }
102
+ return Object.keys(window).filter(
103
+ (key) => key.startsWith("go") && typeof window[key] === "function"
104
+ );
514
105
  }
515
- async function writeJsonFile(filePath, data) {
516
- await ensureDirectory(path2.dirname(filePath));
517
- await fs2.writeFile(filePath, JSON.stringify(data, null, 2), "utf8");
518
- }
519
- async function readJsonFile(filePath, defaultValue) {
520
- try {
521
- const data = await fs2.readFile(filePath, "utf8");
522
- return safeJsonParse(data, defaultValue);
523
- } catch (error) {
524
- return defaultValue;
106
+ function useGoWasm(wasmUrl, options = {}) {
107
+ if (typeof window === "undefined") {
108
+ throw new Error("useGoWasm() is for browser use only.");
525
109
  }
110
+ return {
111
+ loadWasm: () => loadGoWasm(wasmUrl, options),
112
+ callFunction: callWasmFunction,
113
+ isReady: isWasmReady,
114
+ getFunctions: getWasmFunctions
115
+ };
526
116
  }
117
+ var init_wasm = __esm({
118
+ "src/wasm.ts"() {
119
+ "use strict";
120
+ }
121
+ });
527
122
 
528
123
  // src/server/templates.ts
529
124
  var templates_exports = {};
@@ -717,13 +312,762 @@ function generateLoadingPage(message = "Loading...") {
717
312
  function escapeHtml(text) {
718
313
  return String(text).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
719
314
  }
315
+ var init_templates = __esm({
316
+ "src/server/templates.ts"() {
317
+ "use strict";
318
+ }
319
+ });
320
+
321
+ // src/server/utils.ts
322
+ var utils_exports = {};
323
+ __export(utils_exports, {
324
+ ensureDirectory: () => ensureDirectory,
325
+ generateToken: () => generateToken,
326
+ getEnvironmentInfo: () => getEnvironmentInfo,
327
+ getPagination: () => getPagination,
328
+ hashString: () => hashString,
329
+ isDirectoryEmpty: () => isDirectoryEmpty,
330
+ readJsonFile: () => readJsonFile,
331
+ safeJsonParse: () => safeJsonParse,
332
+ sendError: () => sendError,
333
+ sendSuccess: () => sendSuccess,
334
+ validateFields: () => validateFields,
335
+ validateFileUpload: () => validateFileUpload,
336
+ writeJsonFile: () => writeJsonFile
337
+ });
338
+ import crypto2 from "crypto";
339
+ import fs from "fs/promises";
340
+ import path from "path";
341
+ function safeJsonParse(json, fallback) {
342
+ try {
343
+ return JSON.parse(json);
344
+ } catch (error) {
345
+ return fallback;
346
+ }
347
+ }
348
+ function generateToken(length = 32) {
349
+ return crypto2.randomBytes(length).toString("hex");
350
+ }
351
+ function hashString(input, salt = "") {
352
+ return crypto2.createHash("sha256").update(input + salt).digest("hex");
353
+ }
354
+ function getPagination(req) {
355
+ const page = Math.max(1, parseInt(req.query.page) || 1);
356
+ const rawLimit = parseInt(req.query.limit);
357
+ let limit;
358
+ if (isNaN(rawLimit) || rawLimit <= 0) {
359
+ limit = 20;
360
+ } else {
361
+ limit = Math.max(1, Math.min(100, rawLimit));
362
+ }
363
+ const skip = (page - 1) * limit;
364
+ return { page, limit, skip };
365
+ }
366
+ function sendSuccess(res, data, message = "Success") {
367
+ return res.json({
368
+ success: true,
369
+ message,
370
+ data
371
+ });
372
+ }
373
+ function sendError(res, message = "An error occurred", statusCode = 400, errors) {
374
+ return res.status(statusCode).json({
375
+ success: false,
376
+ message,
377
+ errors: errors || void 0
378
+ });
379
+ }
380
+ function validateFields(req, requiredFields) {
381
+ const missing = requiredFields.filter((field) => {
382
+ const value = req.body[field];
383
+ return value === void 0 || value === null || value === "";
384
+ });
385
+ return {
386
+ valid: missing.length === 0,
387
+ missing
388
+ };
389
+ }
390
+ function validateFileUpload(file, options = {}) {
391
+ if (!file) {
392
+ return { valid: false, error: "No file provided" };
393
+ }
394
+ if (options.maxSize && file.size > options.maxSize) {
395
+ return {
396
+ valid: false,
397
+ error: `File too large. Maximum size allowed is ${options.maxSize / 1024 / 1024}MB`
398
+ };
399
+ }
400
+ if (options.allowedTypes && options.allowedTypes.length > 0) {
401
+ const fileType = file.mimetype;
402
+ if (!options.allowedTypes.includes(fileType)) {
403
+ return {
404
+ valid: false,
405
+ error: `Invalid file type. Allowed types: ${options.allowedTypes.join(", ")}`
406
+ };
407
+ }
408
+ }
409
+ return { valid: true };
410
+ }
411
+ function getEnvironmentInfo() {
412
+ return {
413
+ nodeVersion: process.version,
414
+ platform: process.platform,
415
+ arch: process.arch,
416
+ memory: process.memoryUsage(),
417
+ uptime: process.uptime(),
418
+ env: process.env.NODE_ENV || "development"
419
+ };
420
+ }
421
+ async function isDirectoryEmpty(dirPath) {
422
+ try {
423
+ const files = await fs.readdir(dirPath);
424
+ return files.length === 0;
425
+ } catch (error) {
426
+ return true;
427
+ }
428
+ }
429
+ async function ensureDirectory(dirPath) {
430
+ try {
431
+ await fs.access(dirPath);
432
+ } catch (error) {
433
+ await fs.mkdir(dirPath, { recursive: true });
434
+ }
435
+ }
436
+ async function writeJsonFile(filePath, data) {
437
+ await ensureDirectory(path.dirname(filePath));
438
+ await fs.writeFile(filePath, JSON.stringify(data, null, 2), "utf8");
439
+ }
440
+ async function readJsonFile(filePath, defaultValue) {
441
+ try {
442
+ const data = await fs.readFile(filePath, "utf8");
443
+ return safeJsonParse(data, defaultValue);
444
+ } catch (error) {
445
+ return defaultValue;
446
+ }
447
+ }
448
+ var init_utils = __esm({
449
+ "src/server/utils.ts"() {
450
+ "use strict";
451
+ }
452
+ });
453
+
454
+ // src/server-renderer.ts
455
+ var server_renderer_exports = {};
456
+ __export(server_renderer_exports, {
457
+ renderToString: () => renderToString
458
+ });
459
+ function renderToString(component) {
460
+ try {
461
+ if (typeof component === "function") {
462
+ const result = component();
463
+ if (typeof result === "string") {
464
+ return result;
465
+ }
466
+ if (result && typeof result === "object") {
467
+ return JSON.stringify(result);
468
+ }
469
+ return String(result || "");
470
+ }
471
+ if (typeof component === "string") {
472
+ return component;
473
+ }
474
+ return String(component || "");
475
+ } catch (error) {
476
+ console.error("Error in renderToString:", error);
477
+ return "<div>Error rendering component</div>";
478
+ }
479
+ }
480
+ var init_server_renderer = __esm({
481
+ "src/server-renderer.ts"() {
482
+ "use strict";
483
+ }
484
+ });
485
+
486
+ // src/index.ts
487
+ var src_exports = {};
488
+ __export(src_exports, {
489
+ ApiRouter: () => ApiRouter,
490
+ AuthService: () => AuthService,
491
+ BaraqexServer: () => BaraqexServer,
492
+ Database: () => Database,
493
+ baraqexRenderToString: () => baraqexRenderToString,
494
+ callWasmFunction: () => callWasmFunction,
495
+ createBaraqexServer: () => createBaraqexServer,
496
+ createDevServer: () => createDevServer,
497
+ createProductionServer: () => createProductionServer,
498
+ createServer: () => createServer,
499
+ ensureDirectory: () => ensureDirectory2,
500
+ errorHandler: () => errorHandler,
501
+ generateDocument: () => generateDocument,
502
+ generateErrorPage: () => generateErrorPage,
503
+ generateLoadingPage: () => generateLoadingPage,
504
+ generateToken: () => generateToken2,
505
+ getEnvironmentInfo: () => getEnvironmentInfo2,
506
+ getPagination: () => getPagination2,
507
+ getWasmFunctions: () => getWasmFunctions,
508
+ hashString: () => hashString2,
509
+ initNodeWasm: () => initNodeWasm,
510
+ isDirectoryEmpty: () => isDirectoryEmpty2,
511
+ isWasmReady: () => isWasmReady,
512
+ loadGoWasm: () => loadGoWasm,
513
+ loadGoWasmFromFile: () => loadGoWasmFromFile,
514
+ notFoundHandler: () => notFoundHandler,
515
+ rateLimit: () => rateLimit,
516
+ readJsonFile: () => readJsonFile2,
517
+ renderComponent: () => renderComponent,
518
+ requestLogger: () => requestLogger,
519
+ safeJsonParse: () => safeJsonParse2,
520
+ sendError: () => sendError2,
521
+ sendSuccess: () => sendSuccess2,
522
+ useGoWasm: () => useGoWasm,
523
+ validateFields: () => validateFields2,
524
+ validateFileUpload: () => validateFileUpload2,
525
+ writeJsonFile: () => writeJsonFile2
526
+ });
527
+ import * as frontend_hamroun_star from "frontend-hamroun";
528
+ function createBaraqexServer(options = {}) {
529
+ return new Promise((resolve, reject) => {
530
+ const checkServer = () => {
531
+ if (createDevServer && typeof createDevServer === "function") {
532
+ resolve(createDevServer(options));
533
+ } else if (isNode) {
534
+ setTimeout(checkServer, 100);
535
+ } else {
536
+ reject(new Error("Server functionality not available in browser environment"));
537
+ }
538
+ };
539
+ checkServer();
540
+ });
541
+ }
542
+ var isNode, isBrowser, BaraqexServer, createServer, createDevServer, createProductionServer, renderComponent, Database, AuthService, ApiRouter, requestLogger, errorHandler, notFoundHandler, rateLimit, initNodeWasm, loadGoWasmFromFile, safeJsonParse2, generateToken2, hashString2, getPagination2, sendSuccess2, sendError2, validateFields2, validateFileUpload2, getEnvironmentInfo2, isDirectoryEmpty2, ensureDirectory2, writeJsonFile2, readJsonFile2, baraqexRenderToString;
543
+ var init_src = __esm({
544
+ "src/index.ts"() {
545
+ "use strict";
546
+ __reExport(src_exports, frontend_hamroun_star);
547
+ init_wasm();
548
+ init_templates();
549
+ isNode = typeof process !== "undefined" && process.versions?.node;
550
+ isBrowser = typeof window !== "undefined";
551
+ BaraqexServer = null;
552
+ createServer = null;
553
+ createDevServer = null;
554
+ createProductionServer = null;
555
+ renderComponent = null;
556
+ Database = null;
557
+ AuthService = null;
558
+ ApiRouter = null;
559
+ requestLogger = null;
560
+ errorHandler = null;
561
+ notFoundHandler = null;
562
+ rateLimit = null;
563
+ initNodeWasm = null;
564
+ loadGoWasmFromFile = null;
565
+ safeJsonParse2 = (json, fallback) => {
566
+ try {
567
+ return JSON.parse(json);
568
+ } catch {
569
+ return fallback;
570
+ }
571
+ };
572
+ generateToken2 = (length = 32) => {
573
+ const array = new Uint8Array(length);
574
+ if (typeof crypto !== "undefined" && crypto.getRandomValues) {
575
+ crypto.getRandomValues(array);
576
+ } else {
577
+ for (let i = 0; i < array.length; i++) {
578
+ array[i] = Math.floor(Math.random() * 256);
579
+ }
580
+ }
581
+ return Array.from(array, (byte) => byte.toString(16).padStart(2, "0")).join("");
582
+ };
583
+ hashString2 = null;
584
+ getPagination2 = null;
585
+ sendSuccess2 = null;
586
+ sendError2 = null;
587
+ validateFields2 = null;
588
+ validateFileUpload2 = null;
589
+ getEnvironmentInfo2 = null;
590
+ isDirectoryEmpty2 = null;
591
+ ensureDirectory2 = null;
592
+ writeJsonFile2 = null;
593
+ readJsonFile2 = null;
594
+ baraqexRenderToString = null;
595
+ if (isNode && !isBrowser) {
596
+ Promise.resolve().then(async () => {
597
+ try {
598
+ try {
599
+ await import("express");
600
+ } catch {
601
+ console.warn("Express not available - server functionality disabled");
602
+ return;
603
+ }
604
+ const serverModule = await Promise.resolve().then(() => (init_server(), server_exports));
605
+ Object.assign(exports, {
606
+ BaraqexServer: serverModule.Server,
607
+ createServer: serverModule.createServer,
608
+ createDevServer: serverModule.createDevServer,
609
+ createProductionServer: serverModule.createProductionServer,
610
+ renderComponent: serverModule.renderComponent,
611
+ Database: serverModule.Database,
612
+ AuthService: serverModule.AuthService,
613
+ ApiRouter: serverModule.ApiRouter,
614
+ requestLogger: serverModule.requestLogger,
615
+ errorHandler: serverModule.errorHandler,
616
+ notFoundHandler: serverModule.notFoundHandler,
617
+ rateLimit: serverModule.rateLimit,
618
+ initNodeWasm: serverModule.initNodeWasm,
619
+ loadGoWasmFromFile: serverModule.loadGoWasmFromFile
620
+ });
621
+ BaraqexServer = serverModule.Server;
622
+ createServer = serverModule.createServer;
623
+ createDevServer = serverModule.createDevServer;
624
+ createProductionServer = serverModule.createProductionServer;
625
+ renderComponent = serverModule.renderComponent;
626
+ Database = serverModule.Database;
627
+ AuthService = serverModule.AuthService;
628
+ ApiRouter = serverModule.ApiRouter;
629
+ requestLogger = serverModule.requestLogger;
630
+ errorHandler = serverModule.errorHandler;
631
+ notFoundHandler = serverModule.notFoundHandler;
632
+ rateLimit = serverModule.rateLimit;
633
+ initNodeWasm = serverModule.initNodeWasm;
634
+ loadGoWasmFromFile = serverModule.loadGoWasmFromFile;
635
+ const utilsModule = await Promise.resolve().then(() => (init_utils(), utils_exports));
636
+ safeJsonParse2 = utilsModule.safeJsonParse;
637
+ generateToken2 = utilsModule.generateToken;
638
+ hashString2 = utilsModule.hashString;
639
+ getPagination2 = utilsModule.getPagination;
640
+ sendSuccess2 = utilsModule.sendSuccess;
641
+ sendError2 = utilsModule.sendError;
642
+ validateFields2 = utilsModule.validateFields;
643
+ validateFileUpload2 = utilsModule.validateFileUpload;
644
+ getEnvironmentInfo2 = utilsModule.getEnvironmentInfo;
645
+ isDirectoryEmpty2 = utilsModule.isDirectoryEmpty;
646
+ ensureDirectory2 = utilsModule.ensureDirectory;
647
+ writeJsonFile2 = utilsModule.writeJsonFile;
648
+ readJsonFile2 = utilsModule.readJsonFile;
649
+ const rendererModule = await Promise.resolve().then(() => (init_server_renderer(), server_renderer_exports));
650
+ baraqexRenderToString = rendererModule.renderToString;
651
+ console.log("\u2705 Baraqex server modules loaded successfully");
652
+ } catch (error) {
653
+ console.warn("Server modules not available:", error.message);
654
+ }
655
+ });
656
+ }
657
+ console.log("Baraqex - powered by Frontend Hamroun Framework with additional utilities");
658
+ }
659
+ });
660
+
661
+ // src/server/database.ts
662
+ var Database2;
663
+ var init_database = __esm({
664
+ "src/server/database.ts"() {
665
+ "use strict";
666
+ Database2 = class {
667
+ constructor(config) {
668
+ this.mongoClient = null;
669
+ this.mongoDb = null;
670
+ this.mysqlPool = null;
671
+ this.pgPool = null;
672
+ this.config = config;
673
+ }
674
+ async connect() {
675
+ switch (this.config.type) {
676
+ case "mongodb":
677
+ await this.connectMongo();
678
+ break;
679
+ case "mysql":
680
+ await this.connectMysql();
681
+ break;
682
+ case "postgres":
683
+ await this.connectPostgres();
684
+ break;
685
+ default:
686
+ throw new Error(`Unsupported database type: ${this.config.type}`);
687
+ }
688
+ }
689
+ async connectMongo() {
690
+ try {
691
+ const { MongoClient } = await import("mongodb");
692
+ this.mongoClient = new MongoClient(this.config.url);
693
+ await this.mongoClient.connect();
694
+ this.mongoDb = this.mongoClient.db();
695
+ console.log("Connected to MongoDB");
696
+ } catch (error) {
697
+ if (error.code === "MODULE_NOT_FOUND") {
698
+ throw new Error("MongoDB driver not installed. Run: npm install mongodb");
699
+ }
700
+ console.error("MongoDB connection error:", error);
701
+ throw error;
702
+ }
703
+ }
704
+ async connectMysql() {
705
+ try {
706
+ const mysql = await import("mysql2/promise");
707
+ this.mysqlPool = mysql.createPool(this.config.url);
708
+ await this.mysqlPool.getConnection();
709
+ console.log("Connected to MySQL");
710
+ } catch (error) {
711
+ if (error.code === "MODULE_NOT_FOUND") {
712
+ throw new Error("MySQL driver not installed. Run: npm install mysql2");
713
+ }
714
+ console.error("MySQL connection error:", error);
715
+ throw error;
716
+ }
717
+ }
718
+ async connectPostgres() {
719
+ try {
720
+ const pg = await import("pg");
721
+ this.pgPool = new pg.Pool({ connectionString: this.config.url });
722
+ const client = await this.pgPool.connect();
723
+ client.release();
724
+ console.log("Connected to PostgreSQL");
725
+ } catch (error) {
726
+ if (error.code === "MODULE_NOT_FOUND") {
727
+ throw new Error("PostgreSQL driver not installed. Run: npm install pg @types/pg");
728
+ }
729
+ console.error("PostgreSQL connection error:", error);
730
+ throw error;
731
+ }
732
+ }
733
+ async disconnect() {
734
+ if (this.mongoClient) {
735
+ await this.mongoClient.close();
736
+ this.mongoClient = null;
737
+ this.mongoDb = null;
738
+ }
739
+ if (this.mysqlPool) {
740
+ await this.mysqlPool.end();
741
+ this.mysqlPool = null;
742
+ }
743
+ if (this.pgPool) {
744
+ await this.pgPool.end();
745
+ this.pgPool = null;
746
+ }
747
+ }
748
+ // Database-specific methods
749
+ getMongoDb() {
750
+ return this.mongoDb;
751
+ }
752
+ getMysqlPool() {
753
+ return this.mysqlPool;
754
+ }
755
+ getPgPool() {
756
+ return this.pgPool;
757
+ }
758
+ // Generic query method
759
+ async query(sql, values) {
760
+ switch (this.config.type) {
761
+ case "mongodb":
762
+ throw new Error("For MongoDB, use getMongoDb() instead of query()");
763
+ case "mysql":
764
+ if (!this.mysqlPool)
765
+ throw new Error("MySQL not connected");
766
+ const [rows] = await this.mysqlPool.execute(sql, values || []);
767
+ return rows;
768
+ case "postgres":
769
+ if (!this.pgPool)
770
+ throw new Error("PostgreSQL not connected");
771
+ const result = await this.pgPool.query(sql, values || []);
772
+ return result.rows;
773
+ default:
774
+ throw new Error(`Unsupported database type: ${this.config.type}`);
775
+ }
776
+ }
777
+ };
778
+ }
779
+ });
780
+
781
+ // src/server/auth.ts
782
+ var AuthService2;
783
+ var init_auth = __esm({
784
+ "src/server/auth.ts"() {
785
+ "use strict";
786
+ AuthService2 = class {
787
+ constructor(config) {
788
+ this.config = {
789
+ expiresIn: "24h",
790
+ ...config
791
+ };
792
+ }
793
+ async hashPassword(password) {
794
+ try {
795
+ const bcrypt = await import("bcryptjs");
796
+ return bcrypt.hash(password, 10);
797
+ } catch (error) {
798
+ if (error.code === "MODULE_NOT_FOUND") {
799
+ throw new Error("bcryptjs not installed. Run: npm install bcryptjs @types/bcryptjs");
800
+ }
801
+ throw error;
802
+ }
803
+ }
804
+ async comparePasswords(password, hashedPassword) {
805
+ try {
806
+ const bcrypt = await import("bcryptjs");
807
+ return bcrypt.compare(password, hashedPassword);
808
+ } catch (error) {
809
+ if (error.code === "MODULE_NOT_FOUND") {
810
+ throw new Error("bcryptjs not installed. Run: npm install bcryptjs @types/bcryptjs");
811
+ }
812
+ throw error;
813
+ }
814
+ }
815
+ generateToken(user) {
816
+ try {
817
+ const jwt = __require("jsonwebtoken");
818
+ const options = {};
819
+ if (this.config.expiresIn) {
820
+ options.expiresIn = this.config.expiresIn;
821
+ }
822
+ return jwt.sign(
823
+ { id: user.id, username: user.username, roles: user.roles || [] },
824
+ this.config.secret,
825
+ options
826
+ );
827
+ } catch (error) {
828
+ if (error.code === "MODULE_NOT_FOUND") {
829
+ throw new Error("jsonwebtoken not installed. Run: npm install jsonwebtoken @types/jsonwebtoken");
830
+ }
831
+ throw error;
832
+ }
833
+ }
834
+ verifyToken(token) {
835
+ try {
836
+ const jwt = __require("jsonwebtoken");
837
+ return jwt.verify(token, this.config.secret);
838
+ } catch (error) {
839
+ if (error.code === "MODULE_NOT_FOUND") {
840
+ throw new Error("jsonwebtoken not installed. Run: npm install jsonwebtoken @types/jsonwebtoken");
841
+ }
842
+ return null;
843
+ }
844
+ }
845
+ // Express middleware for authentication
846
+ initialize() {
847
+ return (req, res, next) => {
848
+ const token = this.extractToken(req);
849
+ if (token) {
850
+ const decoded = this.verifyToken(token);
851
+ if (decoded) {
852
+ req.user = decoded;
853
+ }
854
+ }
855
+ next();
856
+ };
857
+ }
858
+ // Express middleware for requiring authentication
859
+ requireAuth() {
860
+ return (req, res, next) => {
861
+ if (!req.user) {
862
+ return res.status(401).json({ message: "Unauthorized" });
863
+ }
864
+ return next();
865
+ };
866
+ }
867
+ // Express middleware for requiring specific roles
868
+ requireRoles(roles) {
869
+ return (req, res, next) => {
870
+ if (!req.user) {
871
+ return res.status(401).json({ message: "Unauthorized" });
872
+ }
873
+ const userRoles = req.user.roles || [];
874
+ const hasRequiredRole = roles.some((role) => userRoles.includes(role));
875
+ if (!hasRequiredRole) {
876
+ return res.status(403).json({ message: "Forbidden" });
877
+ }
878
+ return next();
879
+ };
880
+ }
881
+ extractToken(req) {
882
+ if (req.headers.authorization && req.headers.authorization.startsWith("Bearer ")) {
883
+ return req.headers.authorization.substring(7);
884
+ }
885
+ return null;
886
+ }
887
+ };
888
+ }
889
+ });
890
+
891
+ // src/server/api-router.ts
892
+ import path2 from "path";
893
+ import fs2 from "fs";
894
+ import { pathToFileURL } from "url";
895
+ var ApiRouter2;
896
+ var init_api_router = __esm({
897
+ "src/server/api-router.ts"() {
898
+ "use strict";
899
+ ApiRouter2 = class {
900
+ constructor(apiDir, auth = null) {
901
+ this.router = null;
902
+ this.apiDir = path2.resolve(process.cwd(), apiDir);
903
+ this.auth = auth;
904
+ this.initializeRouter();
905
+ }
906
+ async initializeRouter() {
907
+ try {
908
+ const express = await import("express");
909
+ this.router = express.default.Router();
910
+ this.setupRoutes();
911
+ } catch (error) {
912
+ if (error.code === "MODULE_NOT_FOUND") {
913
+ throw new Error("Express not installed. Run: npm install express @types/express");
914
+ }
915
+ throw error;
916
+ }
917
+ }
918
+ setupRoutes() {
919
+ if (!fs2.existsSync(this.apiDir)) {
920
+ console.log(`API directory not found: ${this.apiDir}`);
921
+ return;
922
+ }
923
+ this.scanDirectory(this.apiDir, "");
924
+ }
925
+ scanDirectory(dirPath, routePrefix) {
926
+ const entries = fs2.readdirSync(dirPath, { withFileTypes: true });
927
+ for (const entry of entries) {
928
+ const fullPath = path2.join(dirPath, entry.name);
929
+ if (entry.isDirectory()) {
930
+ this.scanDirectory(fullPath, `${routePrefix}/${entry.name}`);
931
+ } else if (this.isRouteFile(entry.name)) {
932
+ const routePath = this.getRoutePath(entry.name, routePrefix);
933
+ this.registerRoute(fullPath, routePath);
934
+ }
935
+ }
936
+ }
937
+ isRouteFile(filename) {
938
+ return filename.endsWith(".js") || filename.endsWith(".ts") || filename.endsWith(".mjs");
939
+ }
940
+ getRoutePath(filename, routePrefix) {
941
+ const baseName = path2.basename(filename, path2.extname(filename));
942
+ if (baseName === "index") {
943
+ return routePrefix || "/";
944
+ }
945
+ const paramMatch = baseName.match(/^\[(.+)\]$/);
946
+ if (paramMatch) {
947
+ return `${routePrefix}/:${paramMatch[1]}`;
948
+ }
949
+ return `${routePrefix}/${baseName}`;
950
+ }
951
+ async registerRoute(filePath, routePath) {
952
+ try {
953
+ const absolutePath = path2.isAbsolute(filePath) ? filePath : path2.resolve(filePath);
954
+ const fileUrl = pathToFileURL(absolutePath).href;
955
+ if (process.platform === "win32") {
956
+ const urlWithTimestamp = `${fileUrl}?t=${Date.now()}`;
957
+ const routeModule = await import(urlWithTimestamp);
958
+ if (!this.isValidRouteModule(routeModule)) {
959
+ console.warn(`Invalid route module: ${filePath}`);
960
+ return;
961
+ }
962
+ console.log(`Registering API route: ${routePath}`);
963
+ const middleware = routeModule.middleware || [];
964
+ for (const method of ["get", "post", "put", "delete", "patch", "options"]) {
965
+ const handler = routeModule[method];
966
+ if (typeof handler === "function") {
967
+ const routerMethod = this.router[method];
968
+ routerMethod.call(
969
+ this.router,
970
+ routePath,
971
+ ...middleware,
972
+ this.wrapHandler(handler)
973
+ );
974
+ }
975
+ }
976
+ } else {
977
+ const routeModule = await import(fileUrl);
978
+ if (!this.isValidRouteModule(routeModule)) {
979
+ console.warn(`Invalid route module: ${filePath}`);
980
+ return;
981
+ }
982
+ console.log(`Registering API route: ${routePath}`);
983
+ const middleware = routeModule.middleware || [];
984
+ for (const method of ["get", "post", "put", "delete", "patch", "options"]) {
985
+ const handler = routeModule[method];
986
+ if (typeof handler === "function") {
987
+ const routerMethod = this.router[method];
988
+ routerMethod.call(
989
+ this.router,
990
+ routePath,
991
+ ...middleware,
992
+ this.wrapHandler(handler)
993
+ );
994
+ }
995
+ }
996
+ }
997
+ } catch (error) {
998
+ console.error(`Error registering route (${filePath}):`, error);
999
+ }
1000
+ }
1001
+ isValidRouteModule(module) {
1002
+ if (!module)
1003
+ return false;
1004
+ return ["get", "post", "put", "delete", "patch", "options"].some((method) => typeof module[method] === "function");
1005
+ }
1006
+ wrapHandler(handler) {
1007
+ return async (req, res, next) => {
1008
+ try {
1009
+ await handler(req, res, next);
1010
+ } catch (error) {
1011
+ next(error);
1012
+ }
1013
+ };
1014
+ }
1015
+ };
1016
+ }
1017
+ });
1018
+
1019
+ // src/server/middleware.ts
1020
+ function rateLimit2(options) {
1021
+ const requests = /* @__PURE__ */ new Map();
1022
+ return (req, res, next) => {
1023
+ const ip = req.ip || req.socket.remoteAddress || "unknown";
1024
+ const now = Date.now();
1025
+ const reqTimes = (requests.get(ip) || []).filter((time) => now - time < options.windowMs);
1026
+ reqTimes.push(now);
1027
+ requests.set(ip, reqTimes);
1028
+ if (reqTimes.length > options.max) {
1029
+ return res.status(429).json({
1030
+ error: {
1031
+ message: "Too Many Requests",
1032
+ retryAfter: Math.ceil(options.windowMs / 1e3)
1033
+ }
1034
+ });
1035
+ }
1036
+ return next();
1037
+ };
1038
+ }
1039
+ var requestLogger2, errorHandler2, notFoundHandler2;
1040
+ var init_middleware = __esm({
1041
+ "src/server/middleware.ts"() {
1042
+ "use strict";
1043
+ requestLogger2 = (req, res, next) => {
1044
+ console.log(`${(/* @__PURE__ */ new Date()).toISOString()} - ${req.method} ${req.url}`);
1045
+ next();
1046
+ };
1047
+ errorHandler2 = (err, req, res, next) => {
1048
+ console.error(err.stack);
1049
+ res.status(500).json({
1050
+ error: {
1051
+ message: "Internal Server Error",
1052
+ ...process.env.NODE_ENV !== "production" ? { details: err.message, stack: err.stack } : {}
1053
+ }
1054
+ });
1055
+ };
1056
+ notFoundHandler2 = (req, res) => {
1057
+ res.status(404).json({
1058
+ error: {
1059
+ message: `Not Found - ${req.method} ${req.url}`
1060
+ }
1061
+ });
1062
+ };
1063
+ }
1064
+ });
720
1065
 
721
1066
  // src/server/wasm.ts
722
1067
  import fs3 from "fs/promises";
723
1068
  import path3 from "path";
724
1069
  import { pathToFileURL as pathToFileURL2 } from "url";
725
- var initialized = false;
726
- async function initNodeWasm() {
1070
+ async function initNodeWasm2() {
727
1071
  if (initialized)
728
1072
  return;
729
1073
  try {
@@ -787,9 +1131,9 @@ You can get it from: https://github.com/golang/go/blob/master/misc/wasm/wasm_exe
787
1131
  Searched paths: ${possiblePaths.join(", ")}`
788
1132
  );
789
1133
  }
790
- async function loadGoWasmFromFile(wasmFilePath, options = {}) {
1134
+ async function loadGoWasmFromFile2(wasmFilePath, options = {}) {
791
1135
  try {
792
- await initNodeWasm();
1136
+ await initNodeWasm2();
793
1137
  if (options.debug) {
794
1138
  console.log("[WASM] Loading WASM from file:", wasmFilePath);
795
1139
  }
@@ -862,8 +1206,55 @@ async function loadGoWasmFromFile(wasmFilePath, options = {}) {
862
1206
  throw error;
863
1207
  }
864
1208
  }
1209
+ var initialized;
1210
+ var init_wasm2 = __esm({
1211
+ "src/server/wasm.ts"() {
1212
+ "use strict";
1213
+ initialized = false;
1214
+ }
1215
+ });
865
1216
 
866
1217
  // src/server/index.ts
1218
+ var server_exports = {};
1219
+ __export(server_exports, {
1220
+ ApiRouter: () => ApiRouter2,
1221
+ AuthService: () => AuthService2,
1222
+ Database: () => Database2,
1223
+ Server: () => Server,
1224
+ createDevServer: () => createDevServer2,
1225
+ createProductionServer: () => createProductionServer2,
1226
+ createServer: () => createServer2,
1227
+ default: () => server_default,
1228
+ ensureDirectory: () => ensureDirectory,
1229
+ errorHandler: () => errorHandler2,
1230
+ generateDocument: () => generateDocument,
1231
+ generateErrorPage: () => generateErrorPage,
1232
+ generateLoadingPage: () => generateLoadingPage,
1233
+ generateToken: () => generateToken,
1234
+ getEnvironmentInfo: () => getEnvironmentInfo,
1235
+ getPagination: () => getPagination,
1236
+ getRequestIp: () => getRequestIp,
1237
+ hashString: () => hashString,
1238
+ initNodeWasm: () => initNodeWasm2,
1239
+ isDirectoryEmpty: () => isDirectoryEmpty,
1240
+ loadGoWasmFromFile: () => loadGoWasmFromFile2,
1241
+ notFoundHandler: () => notFoundHandler2,
1242
+ parseCookies: () => parseCookies,
1243
+ rateLimit: () => rateLimit2,
1244
+ readJsonFile: () => readJsonFile,
1245
+ renderComponent: () => renderComponent2,
1246
+ renderToString: () => src_exports.renderToString,
1247
+ requestLogger: () => requestLogger2,
1248
+ safeJsonParse: () => safeJsonParse,
1249
+ sendError: () => sendError,
1250
+ sendSuccess: () => sendSuccess,
1251
+ validateFields: () => validateFields,
1252
+ validateFileUpload: () => validateFileUpload,
1253
+ writeJsonFile: () => writeJsonFile
1254
+ });
1255
+ import path4 from "path";
1256
+ import fs4 from "fs";
1257
+ import { pathToFileURL as pathToFileURL3 } from "url";
867
1258
  function getComponentName(filePath, pagesDir) {
868
1259
  try {
869
1260
  const relativePath = path4.relative(pagesDir, filePath);
@@ -874,291 +1265,349 @@ function getComponentName(filePath, pagesDir) {
874
1265
  return "";
875
1266
  }
876
1267
  }
877
- var Server = class {
878
- constructor(config = {}) {
879
- this.server = null;
880
- this.db = null;
881
- this.auth = null;
882
- this.initialized = false;
883
- this.config = {
884
- port: 3e3,
885
- apiDir: "./api",
886
- pagesDir: "./pages",
887
- staticDir: "./public",
888
- enableCors: true,
889
- ...config
890
- };
1268
+ function createServer2(config = {}) {
1269
+ return new Server(config);
1270
+ }
1271
+ function createDevServer2(options = {}) {
1272
+ return new Server({
1273
+ port: options.port || 3e3,
1274
+ enableCors: options.enableCors !== false,
1275
+ apiDir: "./src/api",
1276
+ pagesDir: "./src/pages",
1277
+ staticDir: "./public"
1278
+ });
1279
+ }
1280
+ function createProductionServer2(config) {
1281
+ const server = new Server({
1282
+ ...config,
1283
+ port: config.port || (process.env.PORT ? parseInt(process.env.PORT) : 8080)
1284
+ });
1285
+ server.addShutdownHandler();
1286
+ return server;
1287
+ }
1288
+ function getRequestIp(req) {
1289
+ return req.ip || req.headers["x-forwarded-for"]?.split(",")[0].trim() || req.socket.remoteAddress || "";
1290
+ }
1291
+ function parseCookies(req) {
1292
+ const cookies = {};
1293
+ const cookieHeader = req.headers.cookie;
1294
+ if (cookieHeader) {
1295
+ cookieHeader.split(";").forEach((cookie) => {
1296
+ const [name, value] = cookie.split("=").map((c) => c.trim());
1297
+ cookies[name] = value;
1298
+ });
891
1299
  }
892
- async initializeApp() {
893
- if (this.initialized) {
894
- return;
895
- }
896
- try {
897
- const express = await import("express");
898
- this.app = express.default();
899
- this.app.use(express.default.json());
900
- this.app.use(express.default.urlencoded({ extended: true }));
901
- if (this.config.enableCors) {
1300
+ return cookies;
1301
+ }
1302
+ var Server, renderComponent2, server_default;
1303
+ var init_server = __esm({
1304
+ "src/server/index.ts"() {
1305
+ init_src();
1306
+ init_database();
1307
+ init_auth();
1308
+ init_api_router();
1309
+ init_middleware();
1310
+ init_utils();
1311
+ init_templates();
1312
+ init_wasm2();
1313
+ init_wasm2();
1314
+ init_utils();
1315
+ init_templates();
1316
+ init_database();
1317
+ init_auth();
1318
+ init_api_router();
1319
+ init_middleware();
1320
+ Server = class {
1321
+ constructor(config = {}) {
1322
+ this.server = null;
1323
+ this.db = null;
1324
+ this.auth = null;
1325
+ this.initialized = false;
1326
+ this.config = {
1327
+ port: 3e3,
1328
+ apiDir: "./api",
1329
+ pagesDir: "./pages",
1330
+ staticDir: "./public",
1331
+ enableCors: true,
1332
+ ...config
1333
+ };
1334
+ this.initializeApp().catch((error) => {
1335
+ console.error("Failed to initialize server:", error);
1336
+ });
1337
+ }
1338
+ async initializeApp() {
1339
+ if (this.initialized) {
1340
+ return;
1341
+ }
902
1342
  try {
903
- const cors = await import("cors");
904
- this.app.use(cors.default(this.config.corsOptions));
1343
+ const express = await import("express");
1344
+ this.app = express.default();
1345
+ this.app.use(express.default.json());
1346
+ this.app.use(express.default.urlencoded({ extended: true }));
1347
+ if (this.config.enableCors) {
1348
+ try {
1349
+ const cors = await import("cors");
1350
+ this.app.use(cors.default(this.config.corsOptions));
1351
+ } catch (error) {
1352
+ console.warn("CORS not available - install with: npm install cors @types/cors");
1353
+ }
1354
+ }
1355
+ if (this.config.db) {
1356
+ this.db = new Database2(this.config.db);
1357
+ }
1358
+ if (this.config.auth) {
1359
+ this.auth = new AuthService2({
1360
+ secret: this.config.auth.secret,
1361
+ expiresIn: this.config.auth.expiresIn
1362
+ });
1363
+ this.app.use(this.auth.initialize());
1364
+ }
1365
+ const staticPath = path4.resolve(process.cwd(), this.config.staticDir);
1366
+ if (fs4.existsSync(staticPath)) {
1367
+ this.app.use(express.default.static(staticPath));
1368
+ }
1369
+ this.setupApiRoutes();
1370
+ this.setupPageRoutes();
1371
+ this.app.use(notFoundHandler2);
1372
+ this.app.use(errorHandler2);
1373
+ this.initialized = true;
1374
+ console.log("\u2705 Baraqex server initialized successfully");
905
1375
  } catch (error) {
906
- console.warn("CORS not available - install with: npm install cors @types/cors");
1376
+ if (error.code === "MODULE_NOT_FOUND" && error.message.includes("express")) {
1377
+ throw new Error("Express not installed. Run: npm install express @types/express");
1378
+ }
1379
+ throw error;
907
1380
  }
908
1381
  }
909
- if (this.config.db) {
910
- this.db = new Database(this.config.db);
911
- }
912
- if (this.config.auth) {
913
- this.auth = new AuthService({
914
- secret: this.config.auth.secret,
915
- expiresIn: this.config.auth.expiresIn
916
- });
917
- this.app.use(this.auth.initialize());
918
- }
919
- const staticPath = path4.resolve(process.cwd(), this.config.staticDir);
920
- if (fs4.existsSync(staticPath)) {
921
- this.app.use(express.default.static(staticPath));
922
- }
923
- this.setupApiRoutes();
924
- this.setupPageRoutes();
925
- this.app.use(notFoundHandler);
926
- this.app.use(errorHandler);
927
- this.initialized = true;
928
- console.log("Server initialized successfully");
929
- } catch (error) {
930
- if (error.code === "MODULE_NOT_FOUND" && error.message.includes("express")) {
931
- throw new Error("Express not installed. Run: npm install express @types/express");
932
- }
933
- throw error;
934
- }
935
- }
936
- setupApiRoutes() {
937
- const apiRouter = new ApiRouter(this.config.apiDir, this.auth);
938
- this.app.use("/api", requestLogger, apiRouter.router);
939
- this.app.get("/api-docs", (req, res) => {
940
- const apiDocs = this.generateApiDocs();
941
- res.json(apiDocs);
942
- });
943
- }
944
- generateApiDocs() {
945
- const apiDir = path4.resolve(process.cwd(), this.config.apiDir);
946
- const docs = { endpoints: [] };
947
- if (fs4.existsSync(apiDir)) {
948
- this.scanApiDirectory(apiDir, "", docs.endpoints);
949
- }
950
- return docs;
951
- }
952
- scanApiDirectory(dirPath, routePrefix, endpoints) {
953
- const entries = fs4.readdirSync(dirPath, { withFileTypes: true });
954
- for (const entry of entries) {
955
- const fullPath = path4.join(dirPath, entry.name);
956
- if (entry.isDirectory()) {
957
- this.scanApiDirectory(fullPath, `${routePrefix}/${entry.name}`, endpoints);
958
- } else if (entry.name.endsWith(".js") || entry.name.endsWith(".ts")) {
959
- const routePath = this.getRoutePath(entry.name, routePrefix);
960
- endpoints.push({
961
- path: routePath,
962
- file: path4.relative(process.cwd(), fullPath),
963
- methods: this.detectApiMethods(fullPath)
1382
+ setupApiRoutes() {
1383
+ const apiRouter = new ApiRouter2(this.config.apiDir, this.auth);
1384
+ this.app.use("/api", requestLogger2, apiRouter.router);
1385
+ this.app.get("/api-docs", (req, res) => {
1386
+ const apiDocs = this.generateApiDocs();
1387
+ res.json(apiDocs);
964
1388
  });
965
1389
  }
966
- }
967
- }
968
- getRoutePath(filename, routePrefix) {
969
- const baseName = path4.basename(filename, path4.extname(filename));
970
- if (baseName === "index") {
971
- return routePrefix || "/";
972
- }
973
- const paramMatch = baseName.match(/^\[(.+)\]$/);
974
- if (paramMatch) {
975
- return `${routePrefix}/:${paramMatch[1]}`;
976
- }
977
- return `${routePrefix}/${baseName}`;
978
- }
979
- detectApiMethods(filePath) {
980
- try {
981
- const content = fs4.readFileSync(filePath, "utf8");
982
- const methods = ["get", "post", "put", "delete", "patch", "options"];
983
- return methods.filter(
984
- (method) => new RegExp(`export (async )?function ${method}\\s*\\(`).test(content) || new RegExp(`export const ${method}\\s*=`).test(content)
985
- );
986
- } catch (error) {
987
- return [];
988
- }
989
- }
990
- setupPageRoutes() {
991
- const pagesPath = path4.resolve(process.cwd(), this.config.pagesDir);
992
- if (!fs4.existsSync(pagesPath)) {
993
- return;
994
- }
995
- this.app.get("*", async (req, res) => {
996
- try {
997
- const { html, statusCode } = await this.renderPage(req.path);
998
- res.status(statusCode || 200).send(html);
999
- } catch (error) {
1000
- console.error("Error rendering page:", error);
1001
- const errorHtml = generateErrorPage(500, "Server Error");
1002
- res.status(500).send(errorHtml);
1003
- }
1004
- });
1005
- }
1006
- async renderPage(routePath) {
1007
- try {
1008
- const pagesDir = this.config.pagesDir ? path4.resolve(process.cwd(), this.config.pagesDir) : "";
1009
- if (!pagesDir || !fs4.existsSync(pagesDir)) {
1010
- return {
1011
- html: generateErrorPage(404, "Pages directory not found"),
1012
- statusCode: 404
1013
- };
1014
- }
1015
- let normalizedPath = routePath;
1016
- if (!normalizedPath.startsWith("/")) {
1017
- normalizedPath = "/" + normalizedPath;
1390
+ generateApiDocs() {
1391
+ const apiDir = path4.resolve(process.cwd(), this.config.apiDir);
1392
+ const docs = { endpoints: [] };
1393
+ if (fs4.existsSync(apiDir)) {
1394
+ this.scanApiDirectory(apiDir, "", docs.endpoints);
1395
+ }
1396
+ return docs;
1018
1397
  }
1019
- if (normalizedPath === "/") {
1020
- normalizedPath = "/index";
1398
+ scanApiDirectory(dirPath, routePrefix, endpoints) {
1399
+ const entries = fs4.readdirSync(dirPath, { withFileTypes: true });
1400
+ for (const entry of entries) {
1401
+ const fullPath = path4.join(dirPath, entry.name);
1402
+ if (entry.isDirectory()) {
1403
+ this.scanApiDirectory(fullPath, `${routePrefix}/${entry.name}`, endpoints);
1404
+ } else if (entry.name.endsWith(".js") || entry.name.endsWith(".ts")) {
1405
+ const routePath = this.getRoutePath(entry.name, routePrefix);
1406
+ endpoints.push({
1407
+ path: routePath,
1408
+ file: path4.relative(process.cwd(), fullPath),
1409
+ methods: this.detectApiMethods(fullPath)
1410
+ });
1411
+ }
1412
+ }
1021
1413
  }
1022
- let pagePath = "";
1023
- const possiblePaths = [
1024
- path4.join(pagesDir, `${normalizedPath}.js`),
1025
- path4.join(pagesDir, `${normalizedPath}.ts`),
1026
- path4.join(pagesDir, `${normalizedPath}.jsx`),
1027
- path4.join(pagesDir, `${normalizedPath}.tsx`),
1028
- path4.join(pagesDir, `${normalizedPath}/index.js`),
1029
- path4.join(pagesDir, `${normalizedPath}/index.ts`),
1030
- path4.join(pagesDir, `${normalizedPath}/index.jsx`),
1031
- path4.join(pagesDir, `${normalizedPath}/index.tsx`)
1032
- ];
1033
- for (const p of possiblePaths) {
1034
- if (fs4.existsSync(p)) {
1035
- pagePath = p;
1036
- break;
1414
+ getRoutePath(filename, routePrefix) {
1415
+ const baseName = path4.basename(filename, path4.extname(filename));
1416
+ if (baseName === "index") {
1417
+ return routePrefix || "/";
1037
1418
  }
1419
+ const paramMatch = baseName.match(/^\[(.+)\]$/);
1420
+ if (paramMatch) {
1421
+ return `${routePrefix}/:${paramMatch[1]}`;
1422
+ }
1423
+ return `${routePrefix}/${baseName}`;
1038
1424
  }
1039
- if (!pagePath) {
1040
- return {
1041
- html: generateErrorPage(404, `Page not found: ${normalizedPath}`),
1042
- statusCode: 404
1043
- };
1425
+ detectApiMethods(filePath) {
1426
+ try {
1427
+ const content = fs4.readFileSync(filePath, "utf8");
1428
+ const methods = ["get", "post", "put", "delete", "patch", "options"];
1429
+ return methods.filter(
1430
+ (method) => new RegExp(`export (async )?function ${method}\\s*\\(`).test(content) || new RegExp(`export const ${method}\\s*=`).test(content)
1431
+ );
1432
+ } catch (error) {
1433
+ return [];
1434
+ }
1044
1435
  }
1045
- try {
1046
- const pageModule = await import(pagePath);
1047
- if (!pageModule || !pageModule.default) {
1048
- throw new Error(`No default export found in ${pagePath}`);
1436
+ setupPageRoutes() {
1437
+ const pagesPath = path4.resolve(process.cwd(), this.config.pagesDir);
1438
+ if (!fs4.existsSync(pagesPath)) {
1439
+ return;
1049
1440
  }
1050
- const PageComponent = pageModule.default;
1051
- const initialProps = {
1052
- // Provide any initial props here
1053
- path: normalizedPath,
1054
- query: {},
1055
- // Could be parsed from URL
1056
- api: { serverTime: (/* @__PURE__ */ new Date()).toISOString() }
1057
- };
1058
- const renderResult = await renderComponent(PageComponent, initialProps);
1059
- if (!renderResult.success) {
1441
+ this.app.get("*", async (req, res) => {
1442
+ try {
1443
+ const { html, statusCode } = await this.renderPage(req.path);
1444
+ res.status(statusCode || 200).send(html);
1445
+ } catch (error) {
1446
+ console.error("Error rendering page:", error);
1447
+ const errorHtml = generateErrorPage(500, "Server Error");
1448
+ res.status(500).send(errorHtml);
1449
+ }
1450
+ });
1451
+ }
1452
+ async renderPage(routePath) {
1453
+ try {
1454
+ const pagesDir = this.config.pagesDir ? path4.resolve(process.cwd(), this.config.pagesDir) : "";
1455
+ if (!pagesDir || !fs4.existsSync(pagesDir)) {
1456
+ return {
1457
+ html: generateErrorPage(404, "Pages directory not found"),
1458
+ statusCode: 404
1459
+ };
1460
+ }
1461
+ let normalizedPath = routePath;
1462
+ if (!normalizedPath.startsWith("/")) {
1463
+ normalizedPath = "/" + normalizedPath;
1464
+ }
1465
+ if (normalizedPath === "/") {
1466
+ normalizedPath = "/index";
1467
+ }
1468
+ let pagePath = "";
1469
+ const possiblePaths = [
1470
+ path4.join(pagesDir, `${normalizedPath}.js`),
1471
+ path4.join(pagesDir, `${normalizedPath}.ts`),
1472
+ path4.join(pagesDir, `${normalizedPath}.jsx`),
1473
+ path4.join(pagesDir, `${normalizedPath}.tsx`),
1474
+ path4.join(pagesDir, `${normalizedPath}/index.js`),
1475
+ path4.join(pagesDir, `${normalizedPath}/index.ts`),
1476
+ path4.join(pagesDir, `${normalizedPath}/index.jsx`),
1477
+ path4.join(pagesDir, `${normalizedPath}/index.tsx`)
1478
+ ];
1479
+ for (const p of possiblePaths) {
1480
+ if (fs4.existsSync(p)) {
1481
+ pagePath = p;
1482
+ break;
1483
+ }
1484
+ }
1485
+ if (!pagePath) {
1486
+ return {
1487
+ html: generateErrorPage(404, `Page not found: ${normalizedPath}`),
1488
+ statusCode: 404
1489
+ };
1490
+ }
1491
+ try {
1492
+ const absolutePath = path4.resolve(pagePath);
1493
+ const fileUrl = pathToFileURL3(absolutePath).href;
1494
+ const urlWithTimestamp = `${fileUrl}?t=${Date.now()}`;
1495
+ const pageModule = await import(urlWithTimestamp);
1496
+ if (!pageModule || !pageModule.default) {
1497
+ throw new Error(`No default export found in ${pagePath}`);
1498
+ }
1499
+ const PageComponent = pageModule.default;
1500
+ const initialProps = {
1501
+ // Provide any initial props here
1502
+ path: normalizedPath,
1503
+ query: {},
1504
+ // Could be parsed from URL
1505
+ api: { serverTime: (/* @__PURE__ */ new Date()).toISOString() }
1506
+ };
1507
+ const renderResult = await renderComponent2(PageComponent, initialProps);
1508
+ if (!renderResult.success) {
1509
+ return {
1510
+ html: generateErrorPage(500, "Failed to render page", renderResult.error instanceof Error ? renderResult.error : new Error("Unknown error")),
1511
+ statusCode: 500
1512
+ };
1513
+ }
1514
+ const htmlContent = renderResult.html;
1515
+ let pageTitle = "My App";
1516
+ try {
1517
+ if (typeof PageComponent.getTitle === "function") {
1518
+ pageTitle = PageComponent.getTitle(initialProps);
1519
+ } else if (PageComponent.title) {
1520
+ pageTitle = PageComponent.title;
1521
+ }
1522
+ } catch (e) {
1523
+ }
1524
+ const componentName = getComponentName(pagePath, pagesDir);
1525
+ const fullHtml = generateDocument(htmlContent, {
1526
+ title: pageTitle,
1527
+ // Get description from component if available
1528
+ description: typeof PageComponent.getDescription === "function" ? PageComponent.getDescription(initialProps) : PageComponent.description || "",
1529
+ // Add scripts for client-side hydration
1530
+ scripts: ["/client.js"],
1531
+ // Add any custom meta tags
1532
+ meta: typeof PageComponent.getMeta === "function" ? PageComponent.getMeta(initialProps) : {},
1533
+ // Add custom styles
1534
+ styles: ["/styles.css"],
1535
+ // Add initial data for client-side hydration
1536
+ initialData: initialProps,
1537
+ // Add component information for hydration
1538
+ componentName
1539
+ });
1540
+ return { html: fullHtml, statusCode: 200 };
1541
+ } catch (error) {
1542
+ console.error("Error rendering page:", error);
1543
+ return {
1544
+ html: generateErrorPage(500, "Error rendering page", error instanceof Error ? error : new Error("Unknown error")),
1545
+ statusCode: 500
1546
+ };
1547
+ }
1548
+ } catch (error) {
1549
+ console.error("Error finding page:", error);
1060
1550
  return {
1061
- html: generateErrorPage(500, "Failed to render page", renderResult.error instanceof Error ? renderResult.error : new Error("Unknown error")),
1551
+ html: generateErrorPage(500, "Server error", error instanceof Error ? error : new Error("Unknown error")),
1062
1552
  statusCode: 500
1063
1553
  };
1064
1554
  }
1065
- const htmlContent = renderResult.html;
1066
- let pageTitle = "My App";
1067
- try {
1068
- if (typeof PageComponent.getTitle === "function") {
1069
- pageTitle = PageComponent.getTitle(initialProps);
1070
- } else if (PageComponent.title) {
1071
- pageTitle = PageComponent.title;
1072
- }
1073
- } catch (e) {
1555
+ }
1556
+ getExpressApp() {
1557
+ return this.app;
1558
+ }
1559
+ getDatabase() {
1560
+ return this.db;
1561
+ }
1562
+ getAuth() {
1563
+ return this.auth;
1564
+ }
1565
+ async start() {
1566
+ while (!this.initialized) {
1567
+ await new Promise((resolve) => setTimeout(resolve, 50));
1074
1568
  }
1075
- const componentName = getComponentName(pagePath, pagesDir);
1076
- const fullHtml = generateDocument(htmlContent, {
1077
- title: pageTitle,
1078
- // Get description from component if available
1079
- description: typeof PageComponent.getDescription === "function" ? PageComponent.getDescription(initialProps) : PageComponent.description || "",
1080
- // Add scripts for client-side hydration
1081
- scripts: ["/client.js"],
1082
- // Add any custom meta tags
1083
- meta: typeof PageComponent.getMeta === "function" ? PageComponent.getMeta(initialProps) : {},
1084
- // Add custom styles
1085
- styles: ["/styles.css"],
1086
- // Add initial data for client-side hydration
1087
- initialData: initialProps,
1088
- // Add component information for hydration
1089
- componentName
1569
+ return new Promise((resolve, reject) => {
1570
+ if (!this.app) {
1571
+ reject(new Error("Server not initialized. Express app is missing."));
1572
+ return;
1573
+ }
1574
+ this.server = this.app.listen(this.config.port, () => {
1575
+ console.log(`\u{1F680} Server running at http://localhost:${this.config.port}`);
1576
+ resolve();
1577
+ });
1578
+ this.server.on("error", (error) => {
1579
+ reject(error);
1580
+ });
1090
1581
  });
1091
- return { html: fullHtml, statusCode: 200 };
1092
- } catch (error) {
1093
- console.error("Error rendering page:", error);
1094
- return {
1095
- html: generateErrorPage(500, "Error rendering page", error instanceof Error ? error : new Error("Unknown error")),
1096
- statusCode: 500
1097
- };
1098
- }
1099
- } catch (error) {
1100
- console.error("Error finding page:", error);
1101
- return {
1102
- html: generateErrorPage(500, "Server error", error instanceof Error ? error : new Error("Unknown error")),
1103
- statusCode: 500
1104
- };
1105
- }
1106
- }
1107
- getExpressApp() {
1108
- return this.app;
1109
- }
1110
- getDatabase() {
1111
- return this.db;
1112
- }
1113
- getAuth() {
1114
- return this.auth;
1115
- }
1116
- async start() {
1117
- if (!this.initialized) {
1118
- await this.initializeApp();
1119
- }
1120
- return new Promise((resolve, reject) => {
1121
- if (!this.app) {
1122
- reject(new Error("Server not initialized. Express app is missing."));
1123
- return;
1124
1582
  }
1125
- this.server = this.app.listen(this.config.port, () => {
1126
- console.log(`Server running at http://localhost:${this.config.port}`);
1127
- resolve();
1128
- });
1129
- this.server.on("error", (error) => {
1130
- reject(error);
1131
- });
1132
- });
1133
- }
1134
- stop() {
1135
- return new Promise((resolve, reject) => {
1136
- if (!this.server) {
1137
- return resolve();
1583
+ stop() {
1584
+ return new Promise((resolve, reject) => {
1585
+ if (!this.server) {
1586
+ return resolve();
1587
+ }
1588
+ this.server.close((err) => {
1589
+ if (err)
1590
+ return reject(err);
1591
+ this.server = null;
1592
+ resolve();
1593
+ });
1594
+ });
1138
1595
  }
1139
- this.server.close((err) => {
1140
- if (err)
1141
- return reject(err);
1142
- this.server = null;
1143
- resolve();
1144
- });
1145
- });
1146
- }
1147
- restart() {
1148
- return this.stop().then(() => this.start());
1149
- }
1150
- enableSSR(options = {}) {
1151
- if (!fs4.existsSync(path4.resolve(process.cwd(), this.config.pagesDir))) {
1152
- fs4.mkdirSync(path4.resolve(process.cwd(), this.config.pagesDir), { recursive: true });
1153
- }
1154
- if (options.hydratable) {
1155
- const staticDir = path4.resolve(process.cwd(), this.config.staticDir);
1156
- if (!fs4.existsSync(staticDir)) {
1157
- fs4.mkdirSync(staticDir, { recursive: true });
1596
+ restart() {
1597
+ return this.stop().then(() => this.start());
1158
1598
  }
1159
- const clientJsPath = path4.join(staticDir, "client.js");
1160
- if (!fs4.existsSync(clientJsPath)) {
1161
- const clientJsContent = `
1599
+ enableSSR(options = {}) {
1600
+ if (!fs4.existsSync(path4.resolve(process.cwd(), this.config.pagesDir))) {
1601
+ fs4.mkdirSync(path4.resolve(process.cwd(), this.config.pagesDir), { recursive: true });
1602
+ }
1603
+ if (options.hydratable) {
1604
+ const staticDir = path4.resolve(process.cwd(), this.config.staticDir);
1605
+ if (!fs4.existsSync(staticDir)) {
1606
+ fs4.mkdirSync(staticDir, { recursive: true });
1607
+ }
1608
+ const clientJsPath = path4.join(staticDir, "client.js");
1609
+ if (!fs4.existsSync(clientJsPath)) {
1610
+ const clientJsContent = `
1162
1611
  // Auto-generated hydration script
1163
1612
  import { hydrate } from 'frontend-hamroun';
1164
1613
 
@@ -1175,119 +1624,88 @@ var Server = class {
1175
1624
  });
1176
1625
  });
1177
1626
  `;
1178
- fs4.writeFileSync(clientJsPath, clientJsContent);
1627
+ fs4.writeFileSync(clientJsPath, clientJsContent);
1628
+ }
1629
+ }
1179
1630
  }
1180
- }
1181
- }
1182
- registerPlugin(plugin) {
1183
- plugin(this);
1184
- }
1185
- addShutdownHandler() {
1186
- const gracefulShutdown = async () => {
1187
- console.log("Received shutdown signal, closing server...");
1631
+ registerPlugin(plugin) {
1632
+ plugin(this);
1633
+ }
1634
+ addShutdownHandler() {
1635
+ const gracefulShutdown = async () => {
1636
+ console.log("Received shutdown signal, closing server...");
1637
+ try {
1638
+ await this.stop();
1639
+ if (this.db) {
1640
+ await this.db.disconnect();
1641
+ }
1642
+ console.log("Server shut down gracefully");
1643
+ process.exit(0);
1644
+ } catch (error) {
1645
+ console.error("Error during shutdown:", error);
1646
+ process.exit(1);
1647
+ }
1648
+ };
1649
+ process.on("SIGTERM", gracefulShutdown);
1650
+ process.on("SIGINT", gracefulShutdown);
1651
+ }
1652
+ };
1653
+ renderComponent2 = async (Component, props = {}) => {
1188
1654
  try {
1189
- await this.stop();
1190
- if (this.db) {
1191
- await this.db.disconnect();
1192
- }
1193
- console.log("Server shut down gracefully");
1194
- process.exit(0);
1655
+ const { jsx, renderToString: renderToString3 } = await import("frontend-hamroun");
1656
+ const element = jsx(Component, props);
1657
+ const html = renderToString3(element);
1658
+ return {
1659
+ html: typeof html === "string" ? html : String(html),
1660
+ success: true
1661
+ };
1195
1662
  } catch (error) {
1196
- console.error("Error during shutdown:", error);
1197
- process.exit(1);
1663
+ console.error("Error rendering component:", error);
1664
+ return {
1665
+ html: `<div class="error">Error rendering component: ${error instanceof Error ? error.message : "Unknown error"}</div>`,
1666
+ success: false,
1667
+ error
1668
+ };
1198
1669
  }
1199
1670
  };
1200
- process.on("SIGTERM", gracefulShutdown);
1201
- process.on("SIGINT", gracefulShutdown);
1202
- }
1203
- };
1204
- function createServer(config = {}) {
1205
- return new Server(config);
1206
- }
1207
- function createDevServer(options = {}) {
1208
- return new Server({
1209
- port: options.port || 3e3,
1210
- enableCors: options.enableCors !== false,
1211
- apiDir: "./src/api",
1212
- pagesDir: "./src/pages",
1213
- staticDir: "./public"
1214
- });
1215
- }
1216
- function createProductionServer(config) {
1217
- const server = new Server({
1218
- ...config,
1219
- // Fix the PORT parsing
1220
- port: config.port || (process.env.PORT ? parseInt(process.env.PORT) : 8080)
1221
- });
1222
- server.addShutdownHandler();
1223
- return server;
1224
- }
1225
- function getRequestIp(req) {
1226
- return req.ip || req.headers["x-forwarded-for"]?.split(",")[0].trim() || req.socket.remoteAddress || "";
1227
- }
1228
- function parseCookies(req) {
1229
- const cookies = {};
1230
- const cookieHeader = req.headers.cookie;
1231
- if (cookieHeader) {
1232
- cookieHeader.split(";").forEach((cookie) => {
1233
- const [name, value] = cookie.split("=").map((c) => c.trim());
1234
- cookies[name] = value;
1235
- });
1236
- }
1237
- return cookies;
1238
- }
1239
- var renderComponent = async (Component, props = {}) => {
1240
- try {
1241
- const { jsx, renderToString: renderToString2 } = await import("frontend-hamroun");
1242
- const element = jsx(Component, props);
1243
- const html = renderToString2(element);
1244
- return {
1245
- html: typeof html === "string" ? html : String(html),
1246
- success: true
1247
- };
1248
- } catch (error) {
1249
- console.error("Error rendering component:", error);
1250
- return {
1251
- html: `<div class="error">Error rendering component: ${error instanceof Error ? error.message : "Unknown error"}</div>`,
1252
- success: false,
1253
- error
1671
+ server_default = {
1672
+ Server,
1673
+ createServer: createServer2,
1674
+ createDevServer: createDevServer2,
1675
+ createProductionServer: createProductionServer2,
1676
+ rateLimit: rateLimit2,
1677
+ requestLogger: requestLogger2,
1678
+ errorHandler: errorHandler2,
1679
+ notFoundHandler: notFoundHandler2,
1680
+ loadGoWasmFromFile: loadGoWasmFromFile2,
1681
+ // Template utilities
1682
+ templates: templates_exports,
1683
+ // Server utilities
1684
+ utils: utils_exports,
1685
+ // Additional exports
1686
+ renderComponent: renderComponent2,
1687
+ renderToString: src_exports.renderToString,
1688
+ getRequestIp,
1689
+ parseCookies,
1690
+ Database: Database2,
1691
+ AuthService: AuthService2,
1692
+ ApiRouter: ApiRouter2
1254
1693
  };
1255
1694
  }
1256
- };
1257
- var server_default = {
1258
- Server,
1259
- createServer,
1260
- createDevServer,
1261
- createProductionServer,
1262
- rateLimit,
1263
- requestLogger,
1264
- errorHandler,
1265
- notFoundHandler,
1266
- loadGoWasmFromFile,
1267
- // Template utilities
1268
- templates: templates_exports,
1269
- // Server utilities
1270
- utils: utils_exports,
1271
- // Additional exports
1272
- renderComponent,
1273
- renderToString,
1274
- getRequestIp,
1275
- parseCookies,
1276
- Database,
1277
- AuthService,
1278
- ApiRouter
1279
- };
1695
+ });
1696
+ init_server();
1697
+ var export_renderToString = src_exports.renderToString;
1280
1698
  export {
1281
- ApiRouter,
1282
- AuthService,
1283
- Database,
1699
+ ApiRouter2 as ApiRouter,
1700
+ AuthService2 as AuthService,
1701
+ Database2 as Database,
1284
1702
  Server,
1285
- createDevServer,
1286
- createProductionServer,
1287
- createServer,
1703
+ createDevServer2 as createDevServer,
1704
+ createProductionServer2 as createProductionServer,
1705
+ createServer2 as createServer,
1288
1706
  server_default as default,
1289
1707
  ensureDirectory,
1290
- errorHandler,
1708
+ errorHandler2 as errorHandler,
1291
1709
  generateDocument,
1292
1710
  generateErrorPage,
1293
1711
  generateLoadingPage,
@@ -1296,16 +1714,16 @@ export {
1296
1714
  getPagination,
1297
1715
  getRequestIp,
1298
1716
  hashString,
1299
- initNodeWasm,
1717
+ initNodeWasm2 as initNodeWasm,
1300
1718
  isDirectoryEmpty,
1301
- loadGoWasmFromFile,
1302
- notFoundHandler,
1719
+ loadGoWasmFromFile2 as loadGoWasmFromFile,
1720
+ notFoundHandler2 as notFoundHandler,
1303
1721
  parseCookies,
1304
- rateLimit,
1722
+ rateLimit2 as rateLimit,
1305
1723
  readJsonFile,
1306
- renderComponent,
1307
- renderToString,
1308
- requestLogger,
1724
+ renderComponent2 as renderComponent,
1725
+ export_renderToString as renderToString,
1726
+ requestLogger2 as requestLogger,
1309
1727
  safeJsonParse,
1310
1728
  sendError,
1311
1729
  sendSuccess,