@je-es/server 0.0.4 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -8,7 +8,7 @@
8
8
  </div>
9
9
 
10
10
  <div align="center">
11
- <img src="https://img.shields.io/badge/v-0.0.4-black"/>
11
+ <img src="https://img.shields.io/badge/v-0.0.5-black"/>
12
12
  <a href="https://github.com/maysara-elshewehy">
13
13
  </a>
14
14
  <a href="https://github.com/je-es/server"> <img src="https://img.shields.io/badge/🔥-@je--es/server-black"/> </a>
@@ -95,39 +95,36 @@
95
95
  - ### With Database
96
96
 
97
97
  ```typescript
98
- import { server, sqliteTable, integer, text } from '@je-es/server';
98
+ import { server, table, integer, text, primaryKey, notNull } from '@je-es/server';
99
99
 
100
- // Define your schema - all Drizzle types exported from @je-es/server!
101
- const users = sqliteTable('users', {
102
- id : integer('id').primaryKey(),
103
- name : text('name').notNull(),
104
- email : text('email').notNull()
105
- });
100
+ // Define your schema using the built-in schema builder
101
+ const users = table('users', [
102
+ primaryKey(integer('id'), true), // auto-increment primary key
103
+ notNull(text('name')),
104
+ notNull(text('email'))
105
+ ]);
106
106
 
107
107
  const app = server({
108
108
  port : 3000,
109
109
  database: {
110
- connection : './my_app.db', // File-based SQLite database
110
+ connection : './my_app.db', // File-based SQLite database
111
111
  schema : { users }
112
112
  },
113
113
  routes : [
114
114
  {
115
115
  method : 'GET',
116
116
  path : '/users',
117
- handler : async (c) => {
118
- const allUsers = await c.db.select().from(users);
117
+ handler : (c) => {
118
+ const allUsers = c.db.all('users');
119
119
  return c.json(allUsers);
120
120
  }
121
121
  },
122
122
  {
123
123
  method : 'POST',
124
124
  path : '/users',
125
- handler : async (c) => {
126
- const newUser = await c.db
127
- .insert(users)
128
- .values(c.body)
129
- .returning();
130
- return c.json(newUser[0]);
125
+ handler : (c) => {
126
+ const newUser = c.db.insert('users', c.body);
127
+ return c.json(newUser);
131
128
  }
132
129
  }
133
130
  ]
@@ -198,8 +195,7 @@
198
195
 
199
196
  // Database
200
197
  database: {
201
- type : 'bun-sql',
202
- connection : ':memory:',
198
+ connection : ':memory:', // or file path like './app.db'
203
199
  schema : {}
204
200
  },
205
201
 
@@ -436,110 +432,334 @@
436
432
  {
437
433
  method : 'GET',
438
434
  path : '/data',
439
- handler : async (c) => {
435
+ handler : (c) => {
440
436
  // Access default database
441
- const users = await c.db.select().from(usersTable);
437
+ const users = c.db.all('users');
442
438
 
443
439
  // Access named databases
444
440
  const mainDb = app.db.get('default');
445
441
  const analyticsDb = app.db.get('analytics');
446
442
 
447
- return c.json({ users });
443
+ const mainData = mainDb.all('some_table');
444
+ const analyticsData = analyticsDb.all('analytics_table');
445
+
446
+ return c.json({ users, mainData, analyticsData });
448
447
  }
449
448
  }
450
449
  ]
451
450
  });
452
451
  ```
453
452
 
454
- - ### Complete Database Example
453
+ - ### Schema Definition
455
454
 
456
455
  ```typescript
457
456
  import {
458
457
  server,
459
- sqliteTable,
458
+ table,
460
459
  integer,
461
460
  text,
462
461
  real,
463
- eq,
464
- and,
465
- like
462
+ blob,
463
+ numeric,
464
+ primaryKey,
465
+ notNull,
466
+ unique,
467
+ defaultValue,
468
+ references
466
469
  } from '@je-es/server';
467
470
 
468
- // Define schema with all column types
469
- const products = sqliteTable('products', {
470
- id: integer('id').primaryKey(),
471
- name: text('name').notNull(),
472
- description: text('description'),
473
- price: real('price').notNull(),
474
- stock: integer('stock').default(0)
475
- });
471
+ // Define products table
472
+ const products = table('products', [
473
+ primaryKey(integer('id'), true), // Auto-increment primary key
474
+ notNull(text('name')),
475
+ text('description'),
476
+ notNull(real('price')),
477
+ defaultValue(integer('stock'), 0)
478
+ ]);
479
+
480
+ // Define orders table with foreign key
481
+ const orders = table('orders', [
482
+ primaryKey(integer('id'), true),
483
+ notNull(integer('product_id')),
484
+ references(integer('product_id'), 'products', 'id'),
485
+ notNull(integer('quantity')),
486
+ defaultValue(text('status'), 'pending')
487
+ ]);
476
488
 
477
489
  const app = server({
478
490
  database: {
479
491
  connection: './store.db',
480
- schema: { products }
492
+ schema: { products, orders }
493
+ }
494
+ });
495
+ ```
496
+
497
+ - ### Database Operations
498
+
499
+ ```typescript
500
+ import { server, table, integer, text, primaryKey, notNull } from '@je-es/server';
501
+
502
+ const users = table('users', [
503
+ primaryKey(integer('id'), true),
504
+ notNull(text('name')),
505
+ notNull(text('email')),
506
+ integer('age')
507
+ ]);
508
+
509
+ const app = server({
510
+ database: {
511
+ connection: './app.db',
512
+ schema: { users }
481
513
  },
482
514
  routes : [
515
+ // Get all records
483
516
  {
484
517
  method : 'GET',
485
- path : '/products',
486
- handler : async (c) => {
487
- // Query with filters
488
- const allProducts = await c.db
489
- .select()
490
- .from(products)
491
- .where(and(
492
- eq(products.stock, 0),
493
- like(products.name, '%laptop%')
494
- ));
518
+ path : '/users',
519
+ handler : (c) => {
520
+ const allUsers = c.db.all('users');
521
+ return c.json(allUsers);
522
+ }
523
+ },
495
524
 
496
- return c.json(allProducts);
525
+ // Find by ID
526
+ {
527
+ method : 'GET',
528
+ path : '/users/:id',
529
+ handler : (c) => {
530
+ const user = c.db.findById('users', parseInt(c.params.id));
531
+ if (!user) return c.status(404).json({ error: 'Not found' });
532
+ return c.json(user);
497
533
  }
498
534
  },
535
+
536
+ // Find with conditions
499
537
  {
500
- method : 'POST',
501
- path : '/products',
502
- handler : async (c) => {
503
- // Insert new product
504
- const newProduct = await c.db
505
- .insert(products)
506
- .values(c.body)
507
- .returning();
538
+ method : 'GET',
539
+ path : '/users/search',
540
+ handler : (c) => {
541
+ const users = c.db.find('users', {
542
+ name: c.query.name
543
+ });
544
+ return c.json(users);
545
+ }
546
+ },
508
547
 
509
- return c.json(newProduct[0]);
548
+ // Insert
549
+ {
550
+ method : 'POST',
551
+ path : '/users',
552
+ handler : (c) => {
553
+ const newUser = c.db.insert('users', c.body);
554
+ return c.json(newUser);
510
555
  }
511
556
  },
557
+
558
+ // Update
512
559
  {
513
560
  method : 'PUT',
514
- path : '/products/:id',
515
- handler : async (c) => {
516
- // Update product
517
- const updated = await c.db
518
- .update(products)
519
- .set(c.body)
520
- .where(eq(products.id, parseInt(c.params.id)))
521
- .returning();
522
-
523
- return c.json(updated[0]);
561
+ path : '/users/:id',
562
+ handler : (c) => {
563
+ const updated = c.db.update(
564
+ 'users',
565
+ parseInt(c.params.id),
566
+ c.body
567
+ );
568
+ if (!updated) return c.status(404).json({ error: 'Not found' });
569
+ return c.json(updated);
524
570
  }
525
571
  },
572
+
573
+ // Delete
526
574
  {
527
575
  method : 'DELETE',
528
- path : '/products/:id',
529
- handler : async (c) => {
530
- // Delete product
531
- await c.db
532
- .delete(products)
533
- .where(eq(products.id, parseInt(c.params.id)));
534
-
576
+ path : '/users/:id',
577
+ handler : (c) => {
578
+ c.db.delete('users', parseInt(c.params.id));
535
579
  return c.json({ deleted: true });
536
580
  }
537
581
  }
538
582
  ]
539
583
  });
584
+ ```
540
585
 
541
- await app.start();
542
- // All data saved to ./store.db and persists across restarts!
586
+ - ### Query Builder
587
+
588
+ ```typescript
589
+ const app = server({
590
+ database: {
591
+ connection: './app.db',
592
+ schema: { users }
593
+ },
594
+ routes : [
595
+ {
596
+ method : 'GET',
597
+ path : '/advanced-search',
598
+ handler : (c) => {
599
+ // Complex queries with query builder
600
+ const results = c.db.query()
601
+ .select(['name', 'email', 'age'])
602
+ .from('users')
603
+ .where({
604
+ column: 'age',
605
+ operator: '>=',
606
+ value: 18
607
+ })
608
+ .and({
609
+ column: 'name',
610
+ operator: 'LIKE',
611
+ value: '%John%'
612
+ })
613
+ .orderBy('age', 'DESC')
614
+ .limit(10)
615
+ .offset(0)
616
+ .execute();
617
+
618
+ return c.json(results);
619
+ }
620
+ },
621
+
622
+ // Multiple where conditions
623
+ {
624
+ method : 'GET',
625
+ path : '/filter',
626
+ handler : (c) => {
627
+ const users = c.db.query()
628
+ .select()
629
+ .from('users')
630
+ .where([
631
+ { column: 'age', operator: '>', value: 25 },
632
+ { column: 'age', operator: '<', value: 50 }
633
+ ])
634
+ .execute();
635
+
636
+ return c.json(users);
637
+ }
638
+ },
639
+
640
+ // OR conditions
641
+ {
642
+ method : 'GET',
643
+ path : '/or-search',
644
+ handler : (c) => {
645
+ const users = c.db.query()
646
+ .select()
647
+ .from('users')
648
+ .where({ column: 'name', operator: '=', value: 'John' })
649
+ .or({ column: 'name', operator: '=', value: 'Jane' })
650
+ .execute();
651
+
652
+ return c.json(users);
653
+ }
654
+ },
655
+
656
+ // Get single result
657
+ {
658
+ method : 'GET',
659
+ path : '/first-user',
660
+ handler : (c) => {
661
+ const user = c.db.query()
662
+ .select()
663
+ .from('users')
664
+ .limit(1)
665
+ .executeOne();
666
+
667
+ return c.json(user);
668
+ }
669
+ }
670
+ ]
671
+ });
672
+ ```
673
+
674
+ - ### Transactions
675
+
676
+ ```typescript
677
+ const app = server({
678
+ database: {
679
+ connection: './app.db',
680
+ schema: { users, orders }
681
+ },
682
+ routes : [
683
+ {
684
+ method : 'POST',
685
+ path : '/place-order',
686
+ handler : (c) => {
687
+ try {
688
+ c.db.transaction((db) => {
689
+ // Insert order
690
+ const order = db.insert('orders', {
691
+ product_id: c.body.productId,
692
+ quantity: c.body.quantity
693
+ });
694
+
695
+ // Update product stock
696
+ const product = db.findById('products', c.body.productId);
697
+ db.update('products', c.body.productId, {
698
+ stock: product.stock - c.body.quantity
699
+ });
700
+ });
701
+
702
+ return c.json({ success: true });
703
+ } catch (error) {
704
+ return c.status(500).json({
705
+ error: 'Transaction failed'
706
+ });
707
+ }
708
+ }
709
+ }
710
+ ]
711
+ });
712
+ ```
713
+
714
+ - ### Raw SQL
715
+
716
+ ```typescript
717
+ const app = server({
718
+ database: {
719
+ connection: './app.db',
720
+ schema: { users }
721
+ },
722
+ routes : [
723
+ {
724
+ method : 'GET',
725
+ path : '/custom-query',
726
+ handler : (c) => {
727
+ // Execute raw SQL
728
+ const results = c.db.raw(
729
+ 'SELECT * FROM users WHERE age > ? AND name LIKE ?',
730
+ [25, '%John%']
731
+ );
732
+
733
+ return c.json(results);
734
+ }
735
+ },
736
+
737
+ {
738
+ method : 'GET',
739
+ path : '/single-result',
740
+ handler : (c) => {
741
+ // Get single row
742
+ const user = c.db.rawOne(
743
+ 'SELECT * FROM users WHERE id = ?',
744
+ [1]
745
+ );
746
+
747
+ return c.json(user);
748
+ }
749
+ },
750
+
751
+ {
752
+ method : 'POST',
753
+ path : '/execute-sql',
754
+ handler : (c) => {
755
+ // Execute without return
756
+ c.db.exec('DELETE FROM users WHERE age < 18');
757
+
758
+ return c.json({ success: true });
759
+ }
760
+ }
761
+ ]
762
+ });
543
763
  ```
544
764
 
545
765
  <div align="center"> <img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/> <br> </div>
package/dist/main.cjs CHANGED
@@ -1,11 +1,11 @@
1
- 'use strict';Object.defineProperty(exports,'__esModule',{value:true});var bunSql=require('drizzle-orm/bun-sql'),W=require('crypto'),sqliteCore=require('drizzle-orm/sqlite-core'),drizzleOrm=require('drizzle-orm');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var W__default=/*#__PURE__*/_interopDefault(W);var D=class{constructor(){this.routes=new Map;this.regexRoutes=[];}match(e,t){let r=`${e}:${t}`;if(this.routes.has(r))return {handler:this.routes.get(r),params:{}};for(let n of this.regexRoutes)if(n.method===e){let c=t.match(n.pattern);if(c?.groups)return {handler:n.handler,params:c.groups}}return null}getAll(){let e=Array.from(this.routes.entries()).map(([r,n])=>{let c=r.indexOf(":"),d=r.substring(0,c),a=r.substring(c+1);return {method:d,path:a,handler:n}}),t=this.regexRoutes.map(r=>{let n=r.key.indexOf(":");return {method:r.method,path:r.key.substring(n+1),handler:r.handler}});return [...e,...t]}clear(){this.routes.clear(),this.regexRoutes=[];}remove(e,t){let r=`${e}:${t}`;if(this.routes.has(r))return this.routes.delete(r),true;let n=this.regexRoutes.findIndex(c=>c.key===r);return n>=0?(this.regexRoutes.splice(n,1),true):false}register(e,t,r,n={}){let c=`${e}:${t}`;if(t.includes(":")){let d=this.pathToRegex(t),a=this.regexRoutes.findIndex(b=>b.key===c),l={pattern:d,method:e,handler:r,key:c};a>=0?this.regexRoutes[a]=l:this.regexRoutes.push(l);}else this.routes.set(c,r);}pathToRegex(e){let r=e.replace(/[.+?^${}()|[\]\\]/g,"\\$&").replace(/:(\w+)/g,"(?<$1>[^/]+)");return new RegExp(`^${r}$`)}};var I=class{constructor(){this.rateLimitStore=new Map;this.csrfTokens=new Map;this.requestLog=new Map;this.MAX_REQUEST_LOG_SIZE=1e3;}checkRateLimit(e,t,r){let n=Date.now(),c=this.rateLimitStore.get(e);return c?n<c.reset?c.count>=t?false:(c.count++,true):(this.rateLimitStore.set(e,{count:1,reset:n+r}),true):(this.rateLimitStore.set(e,{count:1,reset:n+r}),true)}cleanupRateLimit(){let e=Date.now();for(let[t,r]of this.rateLimitStore.entries())e>r.reset&&this.rateLimitStore.delete(t);}generateCsrfToken(e,t=36e5){let r=W__default.default.randomBytes(32).toString("hex");return this.csrfTokens.set(r,{sessionId:e,expires:Date.now()+t}),r}validateCsrfToken(e,t){let r=this.csrfTokens.get(e);return r?Date.now()>r.expires?(this.csrfTokens.delete(e),false):r.sessionId===t?(this.csrfTokens.delete(e),true):false:false}cleanupCsrfTokens(){let e=Date.now();for(let[t,r]of this.csrfTokens.entries())e>r.expires&&this.csrfTokens.delete(t);}sanitizeHtml(e){return e?e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#x27;").replace(/\//g,"&#x2F;"):""}sanitizeSql(e){return e?e.replace(/\\/g,"\\\\").replace(/;/g,"").replace(/'/g,"''").replace(/"/g,'\\"').replace(/\x00/g,""):""}logRequest(e,t,r,n,c,d){if(this.requestLog.set(e,{timestamp:new Date().toISOString(),method:t,path:r,ip:n,status:c,duration:d}),this.requestLog.size>this.MAX_REQUEST_LOG_SIZE){let{value:a}=this.requestLog.keys().next()||{value:null};a&&this.requestLog.delete(a);}}getRequestLog(e){return this.requestLog.get(e)}getAllRequestLogs(){return Array.from(this.requestLog.values())}clearAll(){this.rateLimitStore.clear(),this.csrfTokens.clear(),this.requestLog.clear();}getStats(){return {rateLimitEntries:this.rateLimitStore.size,csrfTokens:this.csrfTokens.size,requestLogs:this.requestLog.size}}};var P=class{constructor(e="info",t=false){this.level=1;this.pretty=false;this.levels={debug:0,info:1,warn:2,error:3,fatal:4};this.level=this.levels[e]??1,this.pretty=t;}debug(e,t){this.log("debug",this.levels.debug,e,t);}info(e,t){this.log("info",this.levels.info,e,t);}warn(e,t){this.log("warn",this.levels.warn,e,t);}error(e,t){this.log("error",this.levels.error,e,t);}fatal(e,t){this.log("fatal",this.levels.fatal,e,t),process.env.NODE_ENV;}log(e,t,r,n){if(t<this.level)return;let c=new Date().toISOString(),d=r??{},a={timestamp:c,level:e.toUpperCase(),message:n||"No message",...d},l=this.pretty?`[${c}] ${e.toUpperCase()} ${n||"No message"}
2
- ${JSON.stringify(d,null,2)}`:JSON.stringify(a);e==="error"||e==="fatal"?console.error(l):e==="warn"?console.warn(l):console.log(l);}};var v=class extends Error{constructor(t,r=500,n){super(t);this.message=t;this.statusCode=r;this.code=n;this.name="AppError";}},A=class extends v{constructor(t,r){super(t,400,"VALIDATION_ERROR");this.issues=r;this.name="ValidationError";}},Q=class extends v{constructor(e){super(e,500,"DATABASE_ERROR"),this.name="DatabaseError";}},$=class extends v{constructor(e="Request timeout"){super(e,408,"TIMEOUT_ERROR"),this.name="TimeoutError";}},X=class extends v{constructor(e="Too many requests"){super(e,429,"RATE_LIMIT_ERROR"),this.name="RateLimitError";}};var H=new I,O=new D;function Y(s={}){let e=s.port||3e3,t=s.hostname||"localhost",r=s.maxRequestSize||10*1024*1024,n=s.requestTimeout||3e4,c=s.gracefulShutdownTimeout||1e4,d=typeof s.logging=="object"?s.logging:{},a=s.logging?new P(d.level||"info",d.pretty):null,l=new Map,b=[],x=new Set,T=setInterval(()=>{H.cleanupRateLimit(),H.cleanupCsrfTokens();},120*1e3);async function u(o){let h=Date.now(),i=crypto.randomUUID(),m=new URL(o.url).pathname,E=o.method.toUpperCase(),R=re(o);x.add(i);try{let y=o.headers.get("content-length");if(y&&parseInt(y)>r)return a?.warn({requestId:i,size:y,ip:R},"Request too large"),new Response(JSON.stringify({error:"Payload too large"}),{status:413,headers:{"Content-Type":"application/json"}});let q=ne(o,s);if(E==="OPTIONS")return new Response(null,{status:204,headers:q});if(s.security&&typeof s.security=="object"&&s.security.rateLimit){let w=typeof s.security.rateLimit=="object"?s.security.rateLimit:{},L=w.max||100,z=w.windowMs||6e4,V=w.keyGenerator?w.keyGenerator({request:o,ip:R}):R;if(!H.checkRateLimit(V,L,z))return a?.warn({requestId:i,ip:R,key:V},"Rate limit exceeded"),new Response(JSON.stringify({error:w.message||"Too many requests"}),{status:429,headers:{"Content-Type":"application/json"}})}let U=null;["POST","PUT","PATCH"].includes(E)&&(U=await ee(o,a,r));let B=l.get("default"),N=O.match(E,m);if(!N){let w=F(o,{},B,a,i);return a?.warn({requestId:i,method:E,path:m,ip:R},"Route not found"),w.json({error:"Not Found",path:m},404)}let M=F(o,N.params||{},B,a,i);M.body=U,M.request=o;let G=new AbortController,K=new Promise((w,L)=>{let z=setTimeout(()=>{G.abort(),L(new $("Request timeout"));},n);G.signal.addEventListener("abort",()=>clearTimeout(z));}),k=await Promise.race([N.handler(M),K]),S=new Headers(k.headers);q.forEach((w,L)=>{S.has(L)||S.set(L,w);}),S.set("X-Request-ID",i),S.set("X-Content-Type-Options","nosniff"),S.set("X-Frame-Options","DENY"),S.set("X-XSS-Protection","1; mode=block"),S.set("Referrer-Policy","strict-origin-when-cross-origin");let J=Date.now()-h;return H.logRequest(i,E,m,R,k.status,J),a?.info({requestId:i,method:E,path:m,status:k.status,duration:J,ip:R},"Request completed"),new Response(k.body,{status:k.status,headers:S})}catch(y){if(y instanceof v)return a?.warn({error:y.message,requestId:i,ip:R},`App error: ${y.message}`),new Response(JSON.stringify({error:y.message,code:y.code,requestId:i}),{status:y.statusCode,headers:{"Content-Type":"application/json"}});a?.error({error:String(y),requestId:i,ip:R},"Unhandled error");let q=process.env.NODE_ENV==="production"?"Internal Server Error":y.message;return new Response(JSON.stringify({error:q,requestId:i}),{status:500,headers:{"Content-Type":"application/json"}})}finally{x.delete(i);}}let p={method:"GET",path:"/health",handler:o=>o.json({status:"healthy",timestamp:new Date().toISOString(),uptime:process.uptime(),activeRequests:x.size})},g={method:"GET",path:"/readiness",handler:o=>{let h=l.size>0,i=h||l.size===0;return o.json({ready:i,checks:{database:h?"connected":"not configured",activeRequests:x.size},timestamp:new Date().toISOString()},i?200:503)}};s.routes&&s.routes.forEach(o=>{b.push(o),(Array.isArray(o.method)?o.method:[o.method]).forEach(i=>{O.register(i,o.path,o.handler,o);});}),b.push(p,g),O.register("GET","/health",p.handler,p),O.register("GET","/readiness",g.handler,g);let f=null,_={app:null,logger:a,db:l,bunServer:null,async start(){if(s.database){let h=Array.isArray(s.database)?s.database:[s.database];for(let i of h){let C=i.name||"default";try{if(i.type||(i.type="bun-sql"),i.type==="bun-sql")if(typeof i.connection=="string"){let m=bunSql.drizzle(i.connection,{schema:i.schema});l.set(C,m),a?.info({name:C,connection:"string"},"\u2705 Bun SQL connected");}else if(typeof i.connection=="function"){let m=bunSql.drizzle({client:i.connection,schema:i.schema});l.set(C,m),a?.info({name:C,connection:"function"},"\u2705 Bun SQL connected");}else if(i.connection!==null&&i.connection!==void 0&&typeof i.connection=="object"){let m=bunSql.drizzle({client:i.connection,schema:i.schema});l.set(C,m),a?.info({name:C,connection:"object"},"\u2705 Bun SQL connected");}else {let m=typeof i.connection;throw new Error(`Bun SQL connection must be a connection string, SQL function, or SQL instance (got ${m})`)}else throw new Error(`Unsupported database type: ${i.type}`)}catch(m){throw a?.error({error:String(m),name:C,type:i.type},"Failed to connect to database"),m}}}f=Bun.serve({port:e,hostname:t,fetch:u}),_.bunServer=f;let o=`http://${t}:${e}`;console.log(`\u2192 URL: ${o}
1
+ 'use strict';Object.defineProperty(exports,'__esModule',{value:true});var bun_sqlite=require('bun:sqlite'),ce=require('crypto');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var ce__default=/*#__PURE__*/_interopDefault(ce);var q=class{constructor(e=":memory:"){this.schemas=new Map;this.currentQuery="";this.currentParams=[];this.db=new bun_sqlite.Database(e),this.db.exec("PRAGMA foreign_keys = ON");}close(){this.db.close();}defineSchema(e){this.schemas.set(e.name,e);let r=this.generateCreateTableSQL(e);if(this.db.exec(r),e.indexes)for(let t of e.indexes){let a=`CREATE ${t.unique?"UNIQUE":""} INDEX IF NOT EXISTS ${t.name} ON ${e.name} (${t.columns.join(", ")})`;this.db.exec(a);}}getSchema(e){return this.schemas.get(e)}listTables(){return this.db.query("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'").all().map(r=>r.name)}dropTable(e){this.db.exec(`DROP TABLE IF EXISTS ${e}`),this.schemas.delete(e);}query(){return this.reset(),this.createQueryBuilder()}find(e,r){let t=Object.entries(r).map(([n,a])=>({column:n,operator:"=",value:a}));return this.query().select().from(e).where(t).execute()}findOne(e,r){return this.query().select().from(e).where(Object.entries(r).map(([t,n])=>({column:t,operator:"=",value:n}))).limit(1).executeOne()}findById(e,r){return this.findOne(e,{id:r})}all(e){return this.query().select().from(e).execute()}insert(e,r){this.query().insert(e,r).execute();let t=this.db.query("SELECT last_insert_rowid() as id").get();return this.findById(e,t.id)}update(e,r,t){return this.query().update(e,t).where({column:"id",operator:"=",value:r}).execute(),this.findById(e,r)}delete(e,r){this.query().delete(e).where({column:"id",operator:"=",value:r}).execute();return true}transaction(e){this.db.exec("BEGIN TRANSACTION");try{e(this),this.db.exec("COMMIT");}catch(r){throw this.db.exec("ROLLBACK"),r}}exec(e){this.db.exec(e);}raw(e,r=[]){return this.db.query(e).all(...r)}rawOne(e,r=[]){return this.db.query(e).get(...r)}reset(){this.currentQuery="",this.currentParams=[];}createQueryBuilder(){let e={_select:["*"],_from:"",_where:[],_orderBy:"",_limit:null,_offset:null,_isInsert:false,_isUpdate:false,_isDelete:false,_insertData:null,_updateData:null},r=this;return e.select=function(t){return this._select=t||["*"],this},e.from=function(t){return this._from=t,this},e.where=function(t){let a=(Array.isArray(t)?t:[t]).map(u=>{if(u.operator==="IS NULL"||u.operator==="IS NOT NULL")return `${u.column} ${u.operator}`;if(u.operator==="IN"&&Array.isArray(u.value)){let i=u.value.map(()=>"?").join(", ");return u.value.forEach(p=>{r.currentParams.push(p);}),`${u.column} IN (${i})`}else return r.currentParams.push(u.value),`${u.column} ${u.operator} ?`});return this._where.push(...a),this},e.and=function(t){return this.where(t)},e.or=function(t){if(t.operator==="IS NULL"||t.operator==="IS NOT NULL")this._where.push(`OR ${t.column} ${t.operator}`);else if(t.operator==="IN"&&Array.isArray(t.value)){let n=t.value.map(()=>"?").join(", ");t.value.forEach(a=>{r.currentParams.push(a);}),this._where.push(`OR ${t.column} IN (${n})`);}else r.currentParams.push(t.value),this._where.push(`OR ${t.column} ${t.operator} ?`);return this},e.orderBy=function(t,n="ASC"){return this._orderBy=`ORDER BY ${t} ${n}`,this},e.limit=function(t){return this._limit=t,this},e.offset=function(t){return this._offset=t,this},e.insert=function(t,n){return this._isInsert=true,this._from=t,this._insertData=n,this},e.update=function(t,n){return this._isUpdate=true,this._from=t,this._updateData=n,this},e.delete=function(t){return this._isDelete=true,this._from=t,this},e.raw=function(t,n=[]){return r.currentQuery=t,r.currentParams=n,this},e.execute=function(){let t="";if(this._isInsert&&this._insertData){let u=Object.keys(this._insertData),i=u.map(()=>"?").join(", ");t=`INSERT INTO ${this._from} (${u.join(", ")}) VALUES (${i})`,r.currentParams=Object.values(this._insertData);}else if(this._isUpdate&&this._updateData){let u=Object.keys(this._updateData).map(p=>`${p} = ?`),i=Object.values(this._updateData);r.currentParams=[...i,...r.currentParams],t=`UPDATE ${this._from} SET ${u.join(", ")}`,this._where.length>0&&(t+=` WHERE ${this._where.join(" AND ")}`);}else this._isDelete?(t=`DELETE FROM ${this._from}`,this._where.length>0&&(t+=` WHERE ${this._where.join(" AND ")}`)):(t=`SELECT ${this._select.join(", ")} FROM ${this._from}`,this._where.length>0&&(t+=` WHERE ${this._where.join(" AND ")}`),this._orderBy&&(t+=` ${this._orderBy}`),this._limit!==null&&(t+=` LIMIT ${this._limit}`),this._offset!==null&&(t+=` OFFSET ${this._offset}`));!t&&r.currentQuery&&(t=r.currentQuery);let a=r.db.query(t).all(...r.currentParams);return r.reset(),a},e.executeOne=function(){let t=this.execute();return t.length>0?t[0]:null},e.executeRaw=function(t,n=[]){return r.db.query(t).all(...n)},e}generateCreateTableSQL(e){let r=e.columns.map(t=>{let n=`${t.name} ${t.type}`;return t.primaryKey&&(n+=" PRIMARY KEY",t.autoIncrement&&(n+=" AUTOINCREMENT")),t.notNull&&!t.primaryKey&&(n+=" NOT NULL"),t.unique&&(n+=" UNIQUE"),t.default!==void 0&&(typeof t.default=="string"?n+=` DEFAULT '${t.default}'`:t.default===null?n+=" DEFAULT NULL":n+=` DEFAULT ${t.default}`),t.references&&(n+=` REFERENCES ${t.references.table}(${t.references.column})`),n});return `CREATE TABLE IF NOT EXISTS ${e.name} (${r.join(", ")})`}};function Y(s,e){return {name:s,columns:e}}function Z(s,e){return {name:s,type:e}}function ee(s){return {name:s,type:"INTEGER"}}function te(s){return {name:s,type:"TEXT"}}function re(s){return {name:s,type:"REAL"}}function ne(s){return {name:s,type:"BLOB"}}function se(s){return {name:s,type:"NUMERIC"}}function oe(s,e=false){return {...s,primaryKey:true,autoIncrement:e}}function ie(s){return {...s,notNull:true}}function ae(s){return {...s,unique:true}}function ue(s,e){return {...s,default:e}}function le(s,e,r){return {...s,references:{table:e,column:r}}}var _=class{constructor(){this.routes=new Map;this.regexRoutes=[];}match(e,r){let t=`${e}:${r}`;if(this.routes.has(t))return {handler:this.routes.get(t),params:{}};for(let n of this.regexRoutes)if(n.method===e){let a=r.match(n.pattern);if(a?.groups)return {handler:n.handler,params:a.groups}}return null}getAll(){let e=Array.from(this.routes.entries()).map(([t,n])=>{let a=t.indexOf(":"),u=t.substring(0,a),i=t.substring(a+1);return {method:u,path:i,handler:n}}),r=this.regexRoutes.map(t=>{let n=t.key.indexOf(":");return {method:t.method,path:t.key.substring(n+1),handler:t.handler}});return [...e,...r]}clear(){this.routes.clear(),this.regexRoutes=[];}remove(e,r){let t=`${e}:${r}`;if(this.routes.has(t))return this.routes.delete(t),true;let n=this.regexRoutes.findIndex(a=>a.key===t);return n>=0?(this.regexRoutes.splice(n,1),true):false}register(e,r,t,n={}){let a=`${e}:${r}`;if(r.includes(":")){let u=this.pathToRegex(r),i=this.regexRoutes.findIndex(b=>b.key===a),p={pattern:u,method:e,handler:t,key:a};i>=0?this.regexRoutes[i]=p:this.regexRoutes.push(p);}else this.routes.set(a,t);}pathToRegex(e){let t=e.replace(/[.+?^${}()|[\]\\]/g,"\\$&").replace(/:(\w+)/g,"(?<$1>[^/]+)");return new RegExp(`^${t}$`)}};var N=class{constructor(){this.rateLimitStore=new Map;this.csrfTokens=new Map;this.requestLog=new Map;this.MAX_REQUEST_LOG_SIZE=1e3;}checkRateLimit(e,r,t){let n=Date.now(),a=this.rateLimitStore.get(e);return a?n<a.reset?a.count>=r?false:(a.count++,true):(this.rateLimitStore.set(e,{count:1,reset:n+t}),true):(this.rateLimitStore.set(e,{count:1,reset:n+t}),true)}cleanupRateLimit(){let e=Date.now();for(let[r,t]of this.rateLimitStore.entries())e>t.reset&&this.rateLimitStore.delete(r);}generateCsrfToken(e,r=36e5){let t=ce__default.default.randomBytes(32).toString("hex");return this.csrfTokens.set(t,{sessionId:e,expires:Date.now()+r}),t}validateCsrfToken(e,r){let t=this.csrfTokens.get(e);return t?Date.now()>t.expires?(this.csrfTokens.delete(e),false):t.sessionId===r?(this.csrfTokens.delete(e),true):false:false}cleanupCsrfTokens(){let e=Date.now();for(let[r,t]of this.csrfTokens.entries())e>t.expires&&this.csrfTokens.delete(r);}sanitizeHtml(e){return e?e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#x27;").replace(/\//g,"&#x2F;"):""}sanitizeSql(e){return e?e.replace(/\\/g,"\\\\").replace(/;/g,"").replace(/'/g,"''").replace(/"/g,'\\"').replace(/\x00/g,""):""}logRequest(e,r,t,n,a,u){if(this.requestLog.set(e,{timestamp:new Date().toISOString(),method:r,path:t,ip:n,status:a,duration:u}),this.requestLog.size>this.MAX_REQUEST_LOG_SIZE){let{value:i}=this.requestLog.keys().next()||{value:null};i&&this.requestLog.delete(i);}}getRequestLog(e){return this.requestLog.get(e)}getAllRequestLogs(){return Array.from(this.requestLog.values())}clearAll(){this.rateLimitStore.clear(),this.csrfTokens.clear(),this.requestLog.clear();}getStats(){return {rateLimitEntries:this.rateLimitStore.size,csrfTokens:this.csrfTokens.size,requestLogs:this.requestLog.size}}};var $=class{constructor(e="info",r=false){this.level=1;this.pretty=false;this.levels={debug:0,info:1,warn:2,error:3,fatal:4};this.level=this.levels[e]??1,this.pretty=r;}debug(e,r){this.log("debug",this.levels.debug,e,r);}info(e,r){this.log("info",this.levels.info,e,r);}warn(e,r){this.log("warn",this.levels.warn,e,r);}error(e,r){this.log("error",this.levels.error,e,r);}fatal(e,r){this.log("fatal",this.levels.fatal,e,r),process.env.NODE_ENV;}log(e,r,t,n){if(r<this.level)return;let a=new Date().toISOString(),u=t??{},i={timestamp:a,level:e.toUpperCase(),message:n||"No message",...u},p=this.pretty?`[${a}] ${e.toUpperCase()} ${n||"No message"}
2
+ ${JSON.stringify(u,null,2)}`:JSON.stringify(i);e==="error"||e==="fatal"?console.error(p):e==="warn"?console.warn(p):console.log(p);}};var w=class extends Error{constructor(r,t=500,n){super(r);this.message=r;this.statusCode=t;this.code=n;this.name="AppError";}},E=class extends w{constructor(r,t){super(r,400,"VALIDATION_ERROR");this.issues=t;this.name="ValidationError";}},W=class extends w{constructor(e){super(e,500,"DATABASE_ERROR"),this.name="DatabaseError";}},k=class extends w{constructor(e="Request timeout"){super(e,408,"TIMEOUT_ERROR"),this.name="TimeoutError";}},G=class extends w{constructor(e="Too many requests"){super(e,429,"RATE_LIMIT_ERROR"),this.name="RateLimitError";}};var P=new N,L=new _;function de(s={}){let e=s.port||3e3,r=s.hostname||"localhost",t=s.maxRequestSize||10*1024*1024,n=s.requestTimeout||3e4,a=s.gracefulShutdownTimeout||1e4,u=typeof s.logging=="object"?s.logging:{},i=s.logging?new $(u.level||"info",u.pretty):null,p=new Map,b=[],x=new Set,T=setInterval(()=>{P.cleanupRateLimit(),P.cleanupCsrfTokens();},120*1e3);async function c(o){let m=Date.now(),l=crypto.randomUUID(),R=new URL(o.url).pathname,A=o.method.toUpperCase(),f=he(o);x.add(l);try{let y=o.headers.get("content-length");if(y&&parseInt(y)>t)return i?.warn({requestId:l,size:y,ip:f},"Request too large"),new Response(JSON.stringify({error:"Payload too large"}),{status:413,headers:{"Content-Type":"application/json"}});let I=fe(o,s);if(A==="OPTIONS")return new Response(null,{status:204,headers:I});if(s.security&&typeof s.security=="object"&&s.security.rateLimit){let C=typeof s.security.rateLimit=="object"?s.security.rateLimit:{},v=C.max||100,j=C.windowMs||6e4,F=C.keyGenerator?C.keyGenerator({request:o,ip:f}):f;if(!P.checkRateLimit(F,v,j))return i?.warn({requestId:l,ip:f,key:F},"Rate limit exceeded"),new Response(JSON.stringify({error:C.message||"Too many requests"}),{status:429,headers:{"Content-Type":"application/json"}})}let M=null;["POST","PUT","PATCH"].includes(A)&&(M=await ge(o,i,t));let H=p.get("default"),B=L.match(A,R);if(!B){let C=X(o,{},H,i,l);return i?.warn({requestId:l,method:A,path:R,ip:f},"Route not found"),C.json({error:"Not Found",path:R},404)}let U=X(o,B.params||{},H,i,l);U.body=M,U.request=o;let Q=new AbortController,K=new Promise((C,v)=>{let j=setTimeout(()=>{Q.abort(),v(new k("Request timeout"));},n);Q.signal.addEventListener("abort",()=>clearTimeout(j));}),D=await Promise.race([B.handler(U),K]),S=new Headers(D.headers);I.forEach((C,v)=>{S.has(v)||S.set(v,C);}),S.set("X-Request-ID",l),S.set("X-Content-Type-Options","nosniff"),S.set("X-Frame-Options","DENY"),S.set("X-XSS-Protection","1; mode=block"),S.set("Referrer-Policy","strict-origin-when-cross-origin");let z=Date.now()-m;return P.logRequest(l,A,R,f,D.status,z),i?.info({requestId:l,method:A,path:R,status:D.status,duration:z,ip:f},"Request completed"),new Response(D.body,{status:D.status,headers:S})}catch(y){if(y instanceof w)return i?.warn({error:y.message,requestId:l,ip:f},`App error: ${y.message}`),new Response(JSON.stringify({error:y.message,code:y.code,requestId:l}),{status:y.statusCode,headers:{"Content-Type":"application/json"}});i?.error({error:String(y),requestId:l,ip:f},"Unhandled error");let I=process.env.NODE_ENV==="production"?"Internal Server Error":y.message;return new Response(JSON.stringify({error:I,requestId:l}),{status:500,headers:{"Content-Type":"application/json"}})}finally{x.delete(l);}}let d={method:"GET",path:"/health",handler:o=>o.json({status:"healthy",timestamp:new Date().toISOString(),uptime:process.uptime(),activeRequests:x.size})},g={method:"GET",path:"/readiness",handler:o=>{let m=p.size>0,l=m||p.size===0;return o.json({ready:l,checks:{database:m?"connected":"not configured",activeRequests:x.size},timestamp:new Date().toISOString()},l?200:503)}};s.routes&&s.routes.forEach(o=>{b.push(o),(Array.isArray(o.method)?o.method:[o.method]).forEach(l=>{L.register(l,o.path,o.handler,o);});}),b.push(d,g),L.register("GET","/health",d.handler,d),L.register("GET","/readiness",g.handler,g);let h=null,V={app:null,logger:i,db:p,bunServer:null,async start(){if(s.database){let m=Array.isArray(s.database)?s.database:[s.database];for(let l of m){let O=l.name||"default";try{if(typeof l.connection=="string"){let R=new q(l.connection);if(l.schema&&typeof l.schema=="object")for(let[A,f]of Object.entries(l.schema))f&&typeof f=="object"&&R.defineSchema(f);p.set(O,R),i?.info({name:O,connection:l.connection},"\u2705 Database connected");}else throw new Error(`Database connection must be a string path (got ${typeof l.connection})`)}catch(R){throw i?.error({error:String(R),name:O},"Failed to connect to database"),R}}}h=Bun.serve({port:e,hostname:r,fetch:c}),V.bunServer=h;let o=`http://${r}:${e}`;console.log(`\u2192 URL: ${o}
3
3
  \u2192 Environment: ${process.env.NODE_ENV||"development"}
4
4
  \u2192 Routes: ${b.length.toString()}
5
- \u2192 Database: ${l.size>0?"\u2705 Connected":"\u274C None"}
5
+ \u2192 Database: ${p.size>0?"\u2705 Connected":"\u274C None"}
6
6
  \u2192 Security: ${s.security?"\u2705 ENABLED":"\u274C Disabled"}
7
7
 
8
8
  \u{1F50D} Health: ${o}/health
9
9
  \u{1F50D} Ready: ${o}/readiness
10
- `),a?.info({url:o},"Server started");},async stop(){if(a?.info("Stopping server..."),x.size>0){a?.info({count:x.size},"Waiting for active requests...");let o=Date.now()+c;for(;x.size>0&&Date.now()<o;)await new Promise(h=>setTimeout(h,100));x.size>0&&a?.warn({count:x.size},"Force closing with active requests");}if(clearInterval(T),s.onShutdown)try{await s.onShutdown();}catch(o){a?.error({error:String(o)},"Error in shutdown handler");}for(let[o,h]of l.entries())try{h?.$client?.close&&h.$client.close(),a?.info({name:o},"Database closed");}catch(i){a?.error({error:String(i),name:o},"Error closing database");}f&&(f.stop(),a?.info("Bun server stopped")),a?.info("Server stopped successfully");},addRoute(o){b.push(o),(Array.isArray(o.method)?o.method:[o.method]).forEach(i=>{O.register(i,o.path,o.handler,o);}),a?.info({method:o.method,path:o.path},"Route added");},getRoutes(){return b}};return _}async function ee(s,e,t){let r=s.headers.get("content-type")||"";try{if(r.includes("application/json")){let n=await s.text();if(n.length>t)throw new A("Payload too large");if(!n.trim())return {};try{return JSON.parse(n)}catch(c){throw e?.warn({error:String(c),bodyPreview:n.substring(0,100)},"Invalid JSON in request body"),new A("Invalid JSON in request body")}}if(r.includes("application/x-www-form-urlencoded")){let n=await s.text();if(n.length>t)throw new A("Payload too large");return Object.fromEntries(new URLSearchParams(n))}if(r.includes("multipart/form-data"))return await s.formData()}catch(n){throw n instanceof A?n:(e?.error({error:String(n)},"Error parsing request body"),new A("Failed to parse request body"))}return {}}function te(s){let e=new Map;if(!s)return e;let t=s.split(";");for(let r of t){let[n,...c]=r.trim().split("=");if(n){let d=c.join("=");e.set(n,d?decodeURIComponent(d):"");}}return e}function F(s,e,t,r,n){let c=new URL(s.url),d=Object.fromEntries(c.searchParams),a=s.headers,l=200,b=new Map,x=te(a.get("cookie")||""),T={request:s,params:e,query:d,headers:a,db:t,logger:r,requestId:n,get statusCode(){return l},set statusCode(u){l=u;},body:null,json(u,p){return new Response(JSON.stringify(u),{status:p??l,headers:{"Content-Type":"application/json",...this._setCookieHeaders()}})},text(u,p){return new Response(u,{status:p??l,headers:{"Content-Type":"text/plain",...this._setCookieHeaders()}})},html(u,p){return new Response(u,{status:p??l,headers:{"Content-Type":"text/html; charset=utf-8",...this._setCookieHeaders()}})},redirect(u,p=302){return new Response(null,{status:p,headers:{Location:u,...this._setCookieHeaders()}})},file(u,p="application/octet-stream"){let g=Bun.file(u);return new Response(g,{headers:{"Content-Type":p,...this._setCookieHeaders()}})},setCookie(u,p,g={}){let f=`${u}=${encodeURIComponent(p)}`;return g.maxAge!==void 0&&(f+=`; Max-Age=${g.maxAge}`),g.expires&&(f+=`; Expires=${g.expires.toUTCString()}`),g.path&&(f+=`; Path=${g.path}`),g.domain&&(f+=`; Domain=${g.domain}`),g.secure&&(f+="; Secure"),g.httpOnly&&(f+="; HttpOnly"),g.sameSite&&(f+=`; SameSite=${g.sameSite}`),b.set(u,f),T},getCookie(u){return x.get(u)},deleteCookie(u,p={}){return T.setCookie(u,"",{...p,maxAge:0,path:p.path||"/"})},setHeader(u,p){return a.set(u,p),T},getHeader(u){return a.get(u)||void 0},status(u){return l=u,T},_setCookieHeaders(){let u={};return b.size>0&&(u["Set-Cookie"]=Array.from(b.values())),u}};return T}function re(s){let e=s.headers.get("x-forwarded-for");if(e)return e.split(",").map(n=>n.trim())[0]||"unknown";let t=s.headers.get("x-real-ip");return t||"unknown"}function ne(s,e){let t=new Headers;if(!e.security||typeof e.security!="object"||!e.security.cors)return t;let r=typeof e.security.cors=="object"?e.security.cors:{},n=s.headers.get("Origin");if(n){typeof r.origin=="function"?r.origin(n)&&t.set("Access-Control-Allow-Origin",n):Array.isArray(r.origin)?r.origin.includes(n)&&t.set("Access-Control-Allow-Origin",n):typeof r.origin=="string"?t.set("Access-Control-Allow-Origin",r.origin):t.set("Access-Control-Allow-Origin",n);let c=r.methods||["GET","POST","PUT","DELETE","PATCH","OPTIONS"];t.set("Access-Control-Allow-Methods",c.join(", "));let d=r.allowedHeaders||["Content-Type","Authorization","X-Requested-With"];t.set("Access-Control-Allow-Headers",d.join(", ")),r.credentials&&t.set("Access-Control-Allow-Credentials","true"),r.maxAge&&t.set("Access-Control-Max-Age",r.maxAge.toString());}return t}var de=Y;Object.defineProperty(exports,"blob",{enumerable:true,get:function(){return sqliteCore.blob}});Object.defineProperty(exports,"check",{enumerable:true,get:function(){return sqliteCore.check}});Object.defineProperty(exports,"foreignKey",{enumerable:true,get:function(){return sqliteCore.foreignKey}});Object.defineProperty(exports,"index",{enumerable:true,get:function(){return sqliteCore.index}});Object.defineProperty(exports,"integer",{enumerable:true,get:function(){return sqliteCore.integer}});Object.defineProperty(exports,"numeric",{enumerable:true,get:function(){return sqliteCore.numeric}});Object.defineProperty(exports,"primaryKey",{enumerable:true,get:function(){return sqliteCore.primaryKey}});Object.defineProperty(exports,"real",{enumerable:true,get:function(){return sqliteCore.real}});Object.defineProperty(exports,"sqliteTable",{enumerable:true,get:function(){return sqliteCore.sqliteTable}});Object.defineProperty(exports,"text",{enumerable:true,get:function(){return sqliteCore.text}});Object.defineProperty(exports,"uniqueIndex",{enumerable:true,get:function(){return sqliteCore.uniqueIndex}});Object.defineProperty(exports,"Many",{enumerable:true,get:function(){return drizzleOrm.Many}});Object.defineProperty(exports,"One",{enumerable:true,get:function(){return drizzleOrm.One}});Object.defineProperty(exports,"and",{enumerable:true,get:function(){return drizzleOrm.and}});Object.defineProperty(exports,"asc",{enumerable:true,get:function(){return drizzleOrm.asc}});Object.defineProperty(exports,"between",{enumerable:true,get:function(){return drizzleOrm.between}});Object.defineProperty(exports,"desc",{enumerable:true,get:function(){return drizzleOrm.desc}});Object.defineProperty(exports,"eq",{enumerable:true,get:function(){return drizzleOrm.eq}});Object.defineProperty(exports,"exists",{enumerable:true,get:function(){return drizzleOrm.exists}});Object.defineProperty(exports,"gt",{enumerable:true,get:function(){return drizzleOrm.gt}});Object.defineProperty(exports,"gte",{enumerable:true,get:function(){return drizzleOrm.gte}});Object.defineProperty(exports,"ilike",{enumerable:true,get:function(){return drizzleOrm.ilike}});Object.defineProperty(exports,"inArray",{enumerable:true,get:function(){return drizzleOrm.inArray}});Object.defineProperty(exports,"isNotNull",{enumerable:true,get:function(){return drizzleOrm.isNotNull}});Object.defineProperty(exports,"isNull",{enumerable:true,get:function(){return drizzleOrm.isNull}});Object.defineProperty(exports,"like",{enumerable:true,get:function(){return drizzleOrm.like}});Object.defineProperty(exports,"lt",{enumerable:true,get:function(){return drizzleOrm.lt}});Object.defineProperty(exports,"lte",{enumerable:true,get:function(){return drizzleOrm.lte}});Object.defineProperty(exports,"ne",{enumerable:true,get:function(){return drizzleOrm.ne}});Object.defineProperty(exports,"not",{enumerable:true,get:function(){return drizzleOrm.not}});Object.defineProperty(exports,"notBetween",{enumerable:true,get:function(){return drizzleOrm.notBetween}});Object.defineProperty(exports,"notExists",{enumerable:true,get:function(){return drizzleOrm.notExists}});Object.defineProperty(exports,"notInArray",{enumerable:true,get:function(){return drizzleOrm.notInArray}});Object.defineProperty(exports,"or",{enumerable:true,get:function(){return drizzleOrm.or}});Object.defineProperty(exports,"relations",{enumerable:true,get:function(){return drizzleOrm.relations}});Object.defineProperty(exports,"sql",{enumerable:true,get:function(){return drizzleOrm.sql}});exports.AppError=v;exports.DatabaseError=Q;exports.Logger=P;exports.RateLimitError=X;exports.Router=D;exports.SecurityManager=I;exports.TimeoutError=$;exports.ValidationError=A;exports.default=de;exports.server=Y;//# sourceMappingURL=main.cjs.map
10
+ `),i?.info({url:o},"Server started");},async stop(){if(i?.info("Stopping server..."),x.size>0){i?.info({count:x.size},"Waiting for active requests...");let o=Date.now()+a;for(;x.size>0&&Date.now()<o;)await new Promise(m=>setTimeout(m,100));x.size>0&&i?.warn({count:x.size},"Force closing with active requests");}if(clearInterval(T),s.onShutdown)try{await s.onShutdown();}catch(o){i?.error({error:String(o)},"Error in shutdown handler");}for(let[o,m]of p.entries())try{m&&typeof m.close=="function"&&m.close(),i?.info({name:o},"Database closed");}catch(l){i?.error({error:String(l),name:o},"Error closing database");}h&&(h.stop(),i?.info("Bun server stopped")),i?.info("Server stopped successfully");},addRoute(o){b.push(o),(Array.isArray(o.method)?o.method:[o.method]).forEach(l=>{L.register(l,o.path,o.handler,o);}),i?.info({method:o.method,path:o.path},"Route added");},getRoutes(){return b}};return V}async function ge(s,e,r){let t=s.headers.get("content-type")||"";try{if(t.includes("application/json")){let n=await s.text();if(n.length>r)throw new E("Payload too large");if(!n.trim())return {};try{return JSON.parse(n)}catch(a){throw e?.warn({error:String(a),bodyPreview:n.substring(0,100)},"Invalid JSON in request body"),new E("Invalid JSON in request body")}}if(t.includes("application/x-www-form-urlencoded")){let n=await s.text();if(n.length>r)throw new E("Payload too large");return Object.fromEntries(new URLSearchParams(n))}if(t.includes("multipart/form-data"))return await s.formData()}catch(n){throw n instanceof E?n:(e?.error({error:String(n)},"Error parsing request body"),new E("Failed to parse request body"))}return {}}function me(s){let e=new Map;if(!s)return e;let r=s.split(";");for(let t of r){let[n,...a]=t.trim().split("=");if(n){let u=a.join("=");e.set(n,u?decodeURIComponent(u):"");}}return e}function X(s,e,r,t,n){let a=new URL(s.url),u=Object.fromEntries(a.searchParams),i=s.headers,p=200,b=new Map,x=me(i.get("cookie")||""),T={request:s,params:e,query:u,headers:i,db:r,logger:t,requestId:n,get statusCode(){return p},set statusCode(c){p=c;},body:null,json(c,d){return new Response(JSON.stringify(c),{status:d??p,headers:{"Content-Type":"application/json",...this._setCookieHeaders()}})},text(c,d){return new Response(c,{status:d??p,headers:{"Content-Type":"text/plain",...this._setCookieHeaders()}})},html(c,d){return new Response(c,{status:d??p,headers:{"Content-Type":"text/html; charset=utf-8",...this._setCookieHeaders()}})},redirect(c,d=302){return new Response(null,{status:d,headers:{Location:c,...this._setCookieHeaders()}})},file(c,d="application/octet-stream"){let g=Bun.file(c);return new Response(g,{headers:{"Content-Type":d,...this._setCookieHeaders()}})},setCookie(c,d,g={}){let h=`${c}=${encodeURIComponent(d)}`;return g.maxAge!==void 0&&(h+=`; Max-Age=${g.maxAge}`),g.expires&&(h+=`; Expires=${g.expires.toUTCString()}`),g.path&&(h+=`; Path=${g.path}`),g.domain&&(h+=`; Domain=${g.domain}`),g.secure&&(h+="; Secure"),g.httpOnly&&(h+="; HttpOnly"),g.sameSite&&(h+=`; SameSite=${g.sameSite}`),b.set(c,h),T},getCookie(c){return x.get(c)},deleteCookie(c,d={}){return T.setCookie(c,"",{...d,maxAge:0,path:d.path||"/"})},setHeader(c,d){return i.set(c,d),T},getHeader(c){return i.get(c)||void 0},status(c){return p=c,T},_setCookieHeaders(){let c={};return b.size>0&&(c["Set-Cookie"]=Array.from(b.values())),c}};return T}function he(s){let e=s.headers.get("x-forwarded-for");if(e)return e.split(",").map(n=>n.trim())[0]||"unknown";let r=s.headers.get("x-real-ip");return r||"unknown"}function fe(s,e){let r=new Headers;if(!e.security||typeof e.security!="object"||!e.security.cors)return r;let t=typeof e.security.cors=="object"?e.security.cors:{},n=s.headers.get("Origin");if(n){typeof t.origin=="function"?t.origin(n)&&r.set("Access-Control-Allow-Origin",n):Array.isArray(t.origin)?t.origin.includes(n)&&r.set("Access-Control-Allow-Origin",n):typeof t.origin=="string"?r.set("Access-Control-Allow-Origin",t.origin):r.set("Access-Control-Allow-Origin",n);let a=t.methods||["GET","POST","PUT","DELETE","PATCH","OPTIONS"];r.set("Access-Control-Allow-Methods",a.join(", "));let u=t.allowedHeaders||["Content-Type","Authorization","X-Requested-With"];r.set("Access-Control-Allow-Headers",u.join(", ")),t.credentials&&r.set("Access-Control-Allow-Credentials","true"),t.maxAge&&r.set("Access-Control-Max-Age",t.maxAge.toString());}return r}var ve=de;exports.AppError=w;exports.DB=q;exports.DatabaseError=W;exports.Logger=$;exports.RateLimitError=G;exports.Router=_;exports.SecurityManager=N;exports.TimeoutError=k;exports.ValidationError=E;exports.blob=ne;exports.column=Z;exports.default=ve;exports.defaultValue=ue;exports.integer=ee;exports.notNull=ie;exports.numeric=se;exports.primaryKey=oe;exports.real=re;exports.references=le;exports.server=de;exports.table=Y;exports.text=te;exports.unique=ae;//# sourceMappingURL=main.cjs.map
11
11
  //# sourceMappingURL=main.cjs.map