@je-es/server 0.0.9 → 0.1.1
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 +78 -26
- package/dist/main.cjs +2 -2
- package/dist/main.cjs.map +1 -1
- package/dist/main.js +2 -2
- package/dist/main.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -3,41 +3,55 @@
|
|
|
3
3
|
<br>
|
|
4
4
|
<div align="center">
|
|
5
5
|
<p>
|
|
6
|
-
<img src="./assets/img/logo.png" alt="logo" style="" height="
|
|
6
|
+
<img src="./assets/img/logo.png" alt="logo" style="" height="80" />
|
|
7
7
|
</p>
|
|
8
8
|
</div>
|
|
9
9
|
|
|
10
10
|
<div align="center">
|
|
11
|
-
<img src="https://img.shields.io/badge/v-
|
|
11
|
+
<img src="https://img.shields.io/badge/v-1.1.0-black"/>
|
|
12
12
|
<a href="https://github.com/maysara-elshewehy">
|
|
13
13
|
</a>
|
|
14
|
-
<a href="https://github.com/je-es
|
|
15
|
-
</div>
|
|
16
|
-
|
|
17
|
-
<div align="center">
|
|
18
|
-
<img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/>
|
|
19
|
-
<br>
|
|
14
|
+
<a href="https://github.com/je-es"> <img src="https://img.shields.io/badge/@-je--es-black"/> </a>
|
|
20
15
|
</div>
|
|
16
|
+
<br>
|
|
21
17
|
|
|
22
18
|
<!-- ╚═════════════════════════════════════════════════════════════════╝ -->
|
|
23
19
|
|
|
24
20
|
|
|
25
21
|
|
|
22
|
+
|
|
26
23
|
<!-- ╔══════════════════════════════ DOC ══════════════════════════════╗ -->
|
|
27
24
|
|
|
25
|
+
|
|
28
26
|
- ## Quick Start 🔥
|
|
29
27
|
|
|
30
|
-
|
|
28
|
+
> _**The simplest, fastest, most organized and stable way to build servers.**_
|
|
31
29
|
|
|
32
|
-
|
|
33
|
-
# install
|
|
34
|
-
space i @je-es/server
|
|
30
|
+
> _We prefer to use [`space`](https://github.com//solution-lib/space) with [`@solution-dist/server`](https://github.com/solution-dist/server) for a better experience._
|
|
35
31
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
32
|
+
```bash
|
|
33
|
+
space init <server-name> -t server
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
cd <server-name>
|
|
38
|
+
space install
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# example
|
|
43
|
+
> space start
|
|
44
|
+
|
|
45
|
+
# output
|
|
46
|
+
16:16:31 ✓ Server started at http://localhost:3000
|
|
47
|
+
16:17:25 GET / 200 4ms
|
|
48
|
+
...
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
<br>
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
- ## Examples
|
|
41
55
|
|
|
42
56
|
- ### Basic Server
|
|
43
57
|
|
|
@@ -92,6 +106,8 @@
|
|
|
92
106
|
...
|
|
93
107
|
```
|
|
94
108
|
|
|
109
|
+
<div align="center"> <img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/> <br> </div>
|
|
110
|
+
|
|
95
111
|
- ### With Database
|
|
96
112
|
|
|
97
113
|
```typescript
|
|
@@ -134,6 +150,8 @@
|
|
|
134
150
|
// Data persists in ./my_app.db file!
|
|
135
151
|
```
|
|
136
152
|
|
|
153
|
+
<div align="center"> <img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/> <br> </div>
|
|
154
|
+
|
|
137
155
|
- ### With Security
|
|
138
156
|
|
|
139
157
|
```typescript
|
|
@@ -168,7 +186,7 @@
|
|
|
168
186
|
await app.start();
|
|
169
187
|
```
|
|
170
188
|
|
|
171
|
-
<
|
|
189
|
+
<br>
|
|
172
190
|
|
|
173
191
|
- ## API Reference
|
|
174
192
|
|
|
@@ -219,6 +237,8 @@
|
|
|
219
237
|
await app.start();
|
|
220
238
|
```
|
|
221
239
|
|
|
240
|
+
<div align="center"> <img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/> <br> </div>
|
|
241
|
+
|
|
222
242
|
- ### Route Definition
|
|
223
243
|
|
|
224
244
|
```typescript
|
|
@@ -258,6 +278,8 @@
|
|
|
258
278
|
};
|
|
259
279
|
```
|
|
260
280
|
|
|
281
|
+
<div align="center"> <img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/> <br> </div>
|
|
282
|
+
|
|
261
283
|
- ### Context API
|
|
262
284
|
|
|
263
285
|
```typescript
|
|
@@ -315,7 +337,7 @@
|
|
|
315
337
|
}
|
|
316
338
|
```
|
|
317
339
|
|
|
318
|
-
<
|
|
340
|
+
<br>
|
|
319
341
|
|
|
320
342
|
- ## Security Features
|
|
321
343
|
|
|
@@ -337,6 +359,8 @@
|
|
|
337
359
|
});
|
|
338
360
|
```
|
|
339
361
|
|
|
362
|
+
<div align="center"> <img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/> <br> </div>
|
|
363
|
+
|
|
340
364
|
- ### CORS Configuration
|
|
341
365
|
|
|
342
366
|
```typescript
|
|
@@ -363,6 +387,8 @@
|
|
|
363
387
|
});
|
|
364
388
|
```
|
|
365
389
|
|
|
390
|
+
<div align="center"> <img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/> <br> </div>
|
|
391
|
+
|
|
366
392
|
- ### CSRF Protection
|
|
367
393
|
|
|
368
394
|
```typescript
|
|
@@ -377,6 +403,8 @@
|
|
|
377
403
|
const isValid = security.validateCsrfToken(token, 'session-id');
|
|
378
404
|
```
|
|
379
405
|
|
|
406
|
+
<div align="center"> <img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/> <br> </div>
|
|
407
|
+
|
|
380
408
|
- ### Input Sanitization
|
|
381
409
|
|
|
382
410
|
```typescript
|
|
@@ -393,7 +421,7 @@
|
|
|
393
421
|
// Output: ''; DROP TABLE users--
|
|
394
422
|
```
|
|
395
423
|
|
|
396
|
-
<
|
|
424
|
+
<br>
|
|
397
425
|
|
|
398
426
|
- ## Database Support
|
|
399
427
|
|
|
@@ -412,6 +440,8 @@
|
|
|
412
440
|
// Access in routes via c.db
|
|
413
441
|
```
|
|
414
442
|
|
|
443
|
+
<div align="center"> <img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/> <br> </div>
|
|
444
|
+
|
|
415
445
|
- ### Multiple Databases
|
|
416
446
|
|
|
417
447
|
```typescript
|
|
@@ -450,6 +480,8 @@
|
|
|
450
480
|
});
|
|
451
481
|
```
|
|
452
482
|
|
|
483
|
+
<div align="center"> <img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/> <br> </div>
|
|
484
|
+
|
|
453
485
|
- ### Schema Definition
|
|
454
486
|
|
|
455
487
|
```typescript
|
|
@@ -494,6 +526,8 @@
|
|
|
494
526
|
});
|
|
495
527
|
```
|
|
496
528
|
|
|
529
|
+
<div align="center"> <img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/> <br> </div>
|
|
530
|
+
|
|
497
531
|
- ### Database Operations
|
|
498
532
|
|
|
499
533
|
```typescript
|
|
@@ -583,6 +617,8 @@
|
|
|
583
617
|
});
|
|
584
618
|
```
|
|
585
619
|
|
|
620
|
+
<div align="center"> <img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/> <br> </div>
|
|
621
|
+
|
|
586
622
|
- ### Query Builder
|
|
587
623
|
|
|
588
624
|
```typescript
|
|
@@ -671,6 +707,8 @@
|
|
|
671
707
|
});
|
|
672
708
|
```
|
|
673
709
|
|
|
710
|
+
<div align="center"> <img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/> <br> </div>
|
|
711
|
+
|
|
674
712
|
- ### Transactions
|
|
675
713
|
|
|
676
714
|
```typescript
|
|
@@ -711,6 +749,8 @@
|
|
|
711
749
|
});
|
|
712
750
|
```
|
|
713
751
|
|
|
752
|
+
<div align="center"> <img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/> <br> </div>
|
|
753
|
+
|
|
714
754
|
- ### Raw SQL
|
|
715
755
|
|
|
716
756
|
```typescript
|
|
@@ -762,7 +802,7 @@
|
|
|
762
802
|
});
|
|
763
803
|
```
|
|
764
804
|
|
|
765
|
-
<
|
|
805
|
+
<br>
|
|
766
806
|
|
|
767
807
|
- ## Advanced Features
|
|
768
808
|
|
|
@@ -792,6 +832,8 @@
|
|
|
792
832
|
};
|
|
793
833
|
```
|
|
794
834
|
|
|
835
|
+
<div align="center"> <img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/> <br> </div>
|
|
836
|
+
|
|
795
837
|
- ### Cookie Management
|
|
796
838
|
|
|
797
839
|
```typescript
|
|
@@ -838,6 +880,8 @@
|
|
|
838
880
|
});
|
|
839
881
|
```
|
|
840
882
|
|
|
883
|
+
<div align="center"> <img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/> <br> </div>
|
|
884
|
+
|
|
841
885
|
- ### Dynamic Routing
|
|
842
886
|
|
|
843
887
|
```typescript
|
|
@@ -873,6 +917,8 @@
|
|
|
873
917
|
});
|
|
874
918
|
```
|
|
875
919
|
|
|
920
|
+
<div align="center"> <img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/> <br> </div>
|
|
921
|
+
|
|
876
922
|
- ### Health Checks
|
|
877
923
|
|
|
878
924
|
```typescript
|
|
@@ -899,6 +945,8 @@
|
|
|
899
945
|
}
|
|
900
946
|
```
|
|
901
947
|
|
|
948
|
+
<div align="center"> <img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/> <br> </div>
|
|
949
|
+
|
|
902
950
|
- ### Graceful Shutdown
|
|
903
951
|
|
|
904
952
|
```typescript
|
|
@@ -924,6 +972,8 @@
|
|
|
924
972
|
});
|
|
925
973
|
```
|
|
926
974
|
|
|
975
|
+
<div align="center"> <img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/> <br> </div>
|
|
976
|
+
|
|
927
977
|
- ### Dynamic Routes
|
|
928
978
|
|
|
929
979
|
```typescript
|
|
@@ -951,6 +1001,8 @@
|
|
|
951
1001
|
console.log(routes);
|
|
952
1002
|
```
|
|
953
1003
|
|
|
1004
|
+
<div align="center"> <img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/> <br> </div>
|
|
1005
|
+
|
|
954
1006
|
- ### Request Timeout
|
|
955
1007
|
|
|
956
1008
|
```typescript
|
|
@@ -970,6 +1022,8 @@
|
|
|
970
1022
|
});
|
|
971
1023
|
```
|
|
972
1024
|
|
|
1025
|
+
<div align="center"> <img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/> <br> </div>
|
|
1026
|
+
|
|
973
1027
|
- ### Custom Error Handling
|
|
974
1028
|
|
|
975
1029
|
```typescript
|
|
@@ -1010,11 +1064,9 @@
|
|
|
1010
1064
|
<!-- ╔══════════════════════════════ END ══════════════════════════════╗ -->
|
|
1011
1065
|
|
|
1012
1066
|
<br>
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
</div>
|
|
1017
|
-
<br>
|
|
1067
|
+
|
|
1068
|
+
---
|
|
1069
|
+
|
|
1018
1070
|
<div align="center">
|
|
1019
1071
|
<a href="https://github.com/solution-lib/space"><img src="https://img.shields.io/badge/by-Space-black"/></a>
|
|
1020
1072
|
</div>
|
package/dist/main.cjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
'use strict';Object.defineProperty(exports,'__esModule',{value:true});var bun_sqlite=require('bun:sqlite'),me=require('crypto'),path=require('path'),fs=require('fs');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var me__default=/*#__PURE__*/_interopDefault(me);var _=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 i=`CREATE ${t.unique?"UNIQUE":""} INDEX IF NOT EXISTS ${t.name} ON ${e.name} (${t.columns.join(", ")})`;this.db.exec(i);}}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,i])=>({column:n,operator:"=",value:i}));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 i=(Array.isArray(t)?t:[t]).map(o=>{if(o.operator==="IS NULL"||o.operator==="IS NOT NULL")return `${o.column} ${o.operator}`;if(o.operator==="IN"&&Array.isArray(o.value)){let a=o.value.map(()=>"?").join(", ");return o.value.forEach(d=>{r.currentParams.push(d);}),`${o.column} IN (${a})`}else return r.currentParams.push(o.value),`${o.column} ${o.operator} ?`});return this._where.push(...i),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(i=>{r.currentParams.push(i);}),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 o=Object.keys(this._insertData),a=o.map(()=>"?").join(", ");t=`INSERT INTO ${this._from} (${o.join(", ")}) VALUES (${a})`,r.currentParams=Object.values(this._insertData);}else if(this._isUpdate&&this._updateData){let o=Object.keys(this._updateData).map(d=>`${d} = ?`),a=Object.values(this._updateData);r.currentParams=[...a,...r.currentParams],t=`UPDATE ${this._from} SET ${o.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 i=r.db.query(t).all(...r.currentParams);return r.reset(),i},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 se(s,e){return {name:s,columns:e}}function ie(s,e){return {name:s,type:e}}function oe(s){return {name:s,type:"INTEGER"}}function ae(s){return {name:s,type:"TEXT"}}function ue(s){return {name:s,type:"REAL"}}function le(s){return {name:s,type:"BLOB"}}function ce(s){return {name:s,type:"NUMERIC"}}function de(s,e=false){return {...s,primaryKey:true,autoIncrement:e}}function pe(s){return {...s,notNull:true}}function fe(s){return {...s,unique:true}}function ge(s,e){return {...s,default:e}}function he(s,e,r){return {...s,references:{table:e,column:r}}}var k=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 i=r.match(n.pattern);if(i){let o=i.groups||{};return {handler:n.handler,params:o}}}return null}getAll(){let e=Array.from(this.routes.entries()).map(([t,n])=>{let i=t.indexOf(":"),o=t.substring(0,i),a=t.substring(i+1);return {method:o,path:a,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(i=>i.key===t);return n>=0?(this.regexRoutes.splice(n,1),true):false}register(e,r,t,n={}){let i=`${e}:${r}`;if(r.includes(":")||r.includes("*")){let o=this.pathToRegex(r),a=this.regexRoutes.findIndex(h=>h.key===i),d={pattern:o,method:e,handler:t,key:i};a>=0?this.regexRoutes[a]=d:this.regexRoutes.push(d);}else this.routes.set(i,t);}pathToRegex(e){let r=e.replace(/[.+?^${}()|[\]\\]/g,"\\$&");return r=r.replace(/:(\w+)/g,"(?<$1>[^/]+)"),r=r.replace(/\*/g,".*"),new RegExp(`^${r}$`)}};var P=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(),i=this.rateLimitStore.get(e);return i?n<i.reset?i.count>=r?false:(i.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=me__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,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/"):""}sanitizeSql(e){return e?e.replace(/\\/g,"\\\\").replace(/;/g,"").replace(/'/g,"''").replace(/"/g,'\\"').replace(/\x00/g,""):""}logRequest(e,r,t,n,i,o){if(this.requestLog.set(e,{timestamp:new Date().toISOString(),method:r,path:t,ip:n,status:i,duration:o}),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 j=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.colors={reset:"\x1B[0m",gray:"\x1B[90m",cyan:"\x1B[36m",green:"\x1B[32m",yellow:"\x1B[33m",red:"\x1B[31m",magenta:"\x1B[35m",bold:"\x1B[1m"};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 i,o;if(typeof t=="string"?(o=t,i={}):(i=t??{},o=n),this.pretty)this.prettyLog(e,i,o);else {let d={timestamp:new Date().toISOString(),level:e.toUpperCase(),message:o||"No message",...i},h=JSON.stringify(d);e==="error"||e==="fatal"?console.error(h):e==="warn"?console.warn(h):console.log(h);}}prettyLog(e,r,t){let n=this.colors,i=new Date().toLocaleTimeString("en-US",{hour12:false});if(r.method&&r.path&&r.status!==void 0){let f=this.colorizeMethod(r.method),x=this.colorizeStatus(r.status),C=r.duration?`${r.duration}ms`:"",l=r.path;console.log(`${n.gray}${i}${n.reset} ${f} ${n.bold}${l}${n.reset} ${x} ${n.gray}${C}${n.reset}`);return}if(t==="Route added"&&r.method&&r.path){let f=Array.isArray(r.method)?r.method.join("|"):r.method;console.log(`${n.gray}${i}${n.reset} ${n.cyan}\u2192${n.reset} ${n.bold}${f.padEnd(6)}${n.reset} ${r.path}`);return}if(t==="\u2714 Database connected"){console.log(`${n.gray}${i}${n.reset} ${n.green}\u2713${n.reset} Database connected ${n.gray}(${r.name})${n.reset}`);return}if(t==="Server started"){console.log(`${n.gray}${i}${n.reset} ${n.green}\u2713${n.reset} Server started at ${n.cyan}${r.url}${n.reset}`);return}let o=this.getLevelIcon(e),a=this.getLevelColor(e),d=`${n.gray}${i}${n.reset} ${a}${o}${n.reset} `;t&&(d+=`${t} `);let h=Object.keys(r).filter(f=>!["timestamp","level","message"].includes(f));if(h.length>0){let f=h.map(x=>{let C=r[x];return typeof C=="string"||typeof C=="number"?`${n.gray}${x}:${n.reset}${C}`:null}).filter(Boolean);f.length>0&&(d+=n.gray+f.join(" ")+n.reset);}console.log(d);}colorizeMethod(e){let r=this.colors,t=e.toUpperCase();switch(t){case "GET":return `${r.green}${t}${r.reset}`;case "POST":return `${r.cyan}${t}${r.reset}`;case "PUT":return `${r.yellow}${t}${r.reset}`;case "DELETE":return `${r.red}${t}${r.reset}`;case "PATCH":return `${r.magenta}${t}${r.reset}`;default:return `${r.gray}${t}${r.reset}`}}colorizeStatus(e){if(!e)return "";let r=this.colors,t=e.toString();return e>=200&&e<300?`${r.green}${t}${r.reset}`:e>=300&&e<400?`${r.cyan}${t}${r.reset}`:e>=400&&e<500?`${r.yellow}${t}${r.reset}`:e>=500?`${r.red}${t}${r.reset}`:`${r.gray}${t}${r.reset}`}getLevelIcon(e){switch(e){case "debug":return "-";case "info":return "-";case "warn":return "-";case "error":return "-";case "fatal":return "-";default:return "-"}}getLevelColor(e){let r=this.colors;switch(e){case "debug":return r.gray;case "info":return r.cyan;case "warn":return r.yellow;case "error":return r.red;case "fatal":return r.red+r.bold;default:return r.reset}}};var T=class extends Error{constructor(r,t=500,n){super(r);this.message=r;this.statusCode=t;this.code=n;this.name="AppError";}},D=class extends T{constructor(r,t){super(r,400,"VALIDATION_ERROR");this.issues=t;this.name="ValidationError";}},Y=class extends T{constructor(e){super(e,500,"DATABASE_ERROR"),this.name="DatabaseError";}},H=class extends T{constructor(e="Request timeout"){super(e,408,"TIMEOUT_ERROR"),this.name="TimeoutError";}},Z=class extends T{constructor(e="Too many requests"){super(e,429,"RATE_LIMIT_ERROR"),this.name="RateLimitError";}};var I=class{constructor(e){this.fileCache=new Map;this.CACHE_MAX_SIZE=1e3;if(!fs.existsSync(e.directory))throw new Error(`Static directory does not exist: ${e.directory}`);if(!fs.statSync(e.directory).isDirectory())throw new Error(`Static path is not a directory: ${e.directory}`);this.resolvedDir=path.resolve(e.directory),this.config={path:e.path,directory:e.directory,maxAge:e.maxAge??3600,index:e.index??["index.html"],dotfiles:e.dotfiles??"deny",etag:e.etag??true,lastModified:e.lastModified??true,immutable:e.immutable??false,extensions:e.extensions??[],fallthrough:e.fallthrough??false,setHeaders:e.setHeaders};}handler(){return async e=>{let r=e.request.url,n=new URL(r).pathname;n.startsWith(this.config.path)&&(n=n.slice(this.config.path.length));try{n=decodeURIComponent(n);}catch{return e.json({error:"Invalid URL encoding"},400)}if(n.includes("..")||n.includes("\\"))return e.json({error:"Forbidden"},403);if(this.config.dotfiles!=="allow"&&n.split("/").some(a=>a.startsWith(".")))return this.config.dotfiles==="deny"?e.json({error:"Forbidden"},403):this.handleNotFound(e);let i=this.resolveFilePath(n);if(!i)return this.handleNotFound(e);if(!this.isPathSafe(i))return e.json({error:"Forbidden"},403);if(!fs.existsSync(i))return this.handleNotFound(e);let o=fs.statSync(i);return o.isDirectory()?this.serveDirectory(e,i,n):this.serveFile(e,i,o)}}getPathPattern(){return `${this.config.path}/*`}resolveFilePath(e){e.startsWith("/")&&(e=e.slice(1));let r=path.join(this.resolvedDir,e);if(!fs.existsSync(r)&&this.config.extensions.length>0)for(let t of this.config.extensions){let n=`${r}.${t}`;if(fs.existsSync(n))return n}return r}isPathSafe(e){return !path.relative(this.resolvedDir,path.resolve(e)).startsWith("..")&&!path.resolve(e).startsWith("..")}async serveDirectory(e,r,t){for(let n of this.config.index){let i=path.join(r,n);if(fs.existsSync(i)){let o=fs.statSync(i);if(o.isFile())return this.serveFile(e,i,o)}}return this.handleNotFound(e)}async serveFile(e,r,t){let n=e.request.method.toUpperCase();if(n!=="GET"&&n!=="HEAD")return e.json({error:"Method not allowed"},405);let i=r,o=this.fileCache.get(i);if(o&&o.mtime!==t.mtimeMs&&(o=void 0),!o){if(o={etag:this.generateEtag(t),lastModified:new Date(t.mtime),size:t.size,mtime:t.mtimeMs},this.fileCache.size>=this.CACHE_MAX_SIZE){let x=this.fileCache.keys().next().value;x&&this.fileCache.delete(x);}this.fileCache.set(i,o);}let a=e.request.headers.get("if-none-match"),d=e.request.headers.get("if-modified-since");if(this.config.etag&&a===o.etag)return new Response(null,{status:304,headers:this.buildHeaders(r,o)});if(this.config.lastModified&&d){let x=new Date(d);if(o.lastModified<=x)return new Response(null,{status:304,headers:this.buildHeaders(r,o)})}let h=Bun.file(r),f=this.buildHeaders(r,o);return this.config.setHeaders&&this.config.setHeaders(e,r),n==="HEAD"?new Response(null,{status:200,headers:f}):new Response(h,{status:200,headers:f})}buildHeaders(e,r){let t=new Headers,n=this.getMimeType(e);if(t.set("Content-Type",n),t.set("Content-Length",r.size.toString()),this.config.etag&&t.set("ETag",r.etag),this.config.lastModified&&t.set("Last-Modified",r.lastModified.toUTCString()),this.config.maxAge>0){let i=`public, max-age=${this.config.maxAge}`;this.config.immutable&&(i+=", immutable"),t.set("Cache-Control",i);}else t.set("Cache-Control","no-cache");return t.set("Accept-Ranges","bytes"),t}generateEtag(e){return `"${e.size.toString(16)}-${e.mtimeMs.toString(16)}"`}getMimeType(e){let r=path.extname(e).toLowerCase();return we[r]||"application/octet-stream"}handleNotFound(e){return this.config.fallthrough?e.json({error:"Not Found"},404):e.json({error:"Not Found"},404)}clearCache(){this.fileCache.clear();}getCacheStats(){return {entries:this.fileCache.size,maxSize:this.CACHE_MAX_SIZE}}};function Ce(s){return new I(s)}var we={".html":"text/html; charset=utf-8",".htm":"text/html; charset=utf-8",".css":"text/css; charset=utf-8",".txt":"text/plain; charset=utf-8",".xml":"text/xml; charset=utf-8",".csv":"text/csv; charset=utf-8",".md":"text/markdown; charset=utf-8",".js":"application/javascript; charset=utf-8",".mjs":"application/javascript; charset=utf-8",".json":"application/json; charset=utf-8",".jsonld":"application/ld+json",".map":"application/json; charset=utf-8",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".svg":"image/svg+xml",".ico":"image/x-icon",".webp":"image/webp",".avif":"image/avif",".bmp":"image/bmp",".tiff":"image/tiff",".woff":"font/woff",".woff2":"font/woff2",".ttf":"font/ttf",".otf":"font/otf",".eot":"application/vnd.ms-fontobject",".mp3":"audio/mpeg",".wav":"audio/wav",".ogg":"audio/ogg",".m4a":"audio/mp4",".aac":"audio/aac",".flac":"audio/flac",".mp4":"video/mp4",".webm":"video/webm",".ogv":"video/ogg",".mov":"video/quicktime",".avi":"video/x-msvideo",".mkv":"video/x-matroska",".pdf":"application/pdf",".doc":"application/msword",".docx":"application/vnd.openxmlformats-officedocument.wordprocessingml.document",".xls":"application/vnd.ms-excel",".xlsx":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",".ppt":"application/vnd.ms-powerpoint",".pptx":"application/vnd.openxmlformats-officedocument.presentationml.presentation",".zip":"application/zip",".rar":"application/x-rar-compressed",".7z":"application/x-7z-compressed",".tar":"application/x-tar",".gz":"application/gzip",".wasm":"application/wasm",".manifest":"text/cache-manifest",".webmanifest":"application/manifest+json"};var U=new P,v=new k;function Se(s={}){let e=Number(s.port)||3e3,r=s.hostname||"localhost",t=s.maxRequestSize||10*1024*1024,n=s.requestTimeout||3e4,i=s.gracefulShutdownTimeout||1e4,o=typeof s.logging=="object"?s.logging:{},a=s.logging?new j(o.level||"info",o.pretty):null,d=new Map,h=[],f=new Set,x=setInterval(()=>{U.cleanupRateLimit(),U.cleanupCsrfTokens();},120*1e3);async function C(u,c){let g=Date.now(),p=crypto.randomUUID(),L=new URL(u.url).pathname,$=u.method.toUpperCase(),R=$e(u,c);f.add(p);try{let w=u.headers.get("content-length");if(w&&parseInt(w)>t)return a?.warn({requestId:p,size:w,ip:R},"Request too large"),new Response(JSON.stringify({error:"Payload too large"}),{status:413,headers:{"Content-Type":"application/json"}});let M=Ee(u,s);if($==="OPTIONS")return new Response(null,{status:204,headers:M});if(s.security&&typeof s.security=="object"&&s.security.rateLimit){let E=typeof s.security.rateLimit=="object"?s.security.rateLimit:{},q=E.max||100,V=E.windowMs||6e4,J=E.keyGenerator?E.keyGenerator({request:u,ip:R}):R;if(!U.checkRateLimit(J,q,V))return a?.warn({requestId:p,ip:R,key:J},"Rate limit exceeded"),new Response(JSON.stringify({error:E.message||"Too many requests"}),{status:429,headers:{"Content-Type":"application/json"}})}let W=null;["POST","PUT","PATCH"].includes($)&&(W=await Re(u,a,t));let G=d.get("default"),B=v.match($,L);if(!B){let E=te(R,u,{},G,a,p);return a?.warn({requestId:p,method:$,path:L,ip:R},"Route not found"),E.json({error:"Not Found",path:L},404)}let z=te(R,u,B.params||{},G,a,p);z.body=W,z.request=u;let X=new AbortController,re=new Promise((E,q)=>{let V=setTimeout(()=>{X.abort(),q(new H("Request timeout"));},n);X.signal.addEventListener("abort",()=>clearTimeout(V));}),O=await Promise.race([B.handler(z),re]),A=new Headers(O.headers);M.forEach((E,q)=>{A.has(q)||A.set(q,E);}),A.set("X-Request-ID",p),A.set("X-Content-Type-Options","nosniff"),A.set("X-Frame-Options","DENY"),A.set("X-XSS-Protection","1; mode=block"),A.set("Referrer-Policy","strict-origin-when-cross-origin");let K=Date.now()-g;return U.logRequest(p,$,L,R,O.status,K),a?.info({requestId:p,method:$,path:L,status:O.status,duration:K,ip:R},"Request completed"),new Response(O.body,{status:O.status,headers:A})}catch(w){if(w instanceof T)return a?.warn({error:w.message,requestId:p,ip:R},`App error: ${w.message}`),new Response(JSON.stringify({error:w.message,code:w.code,requestId:p}),{status:w.statusCode,headers:{"Content-Type":"application/json"}});a?.error({error:String(w),requestId:p,ip:R},"Unhandled error");let M=process.env.NODE_ENV==="production"?"Internal Server Error":w.message;return new Response(JSON.stringify({error:M,requestId:p}),{status:500,headers:{"Content-Type":"application/json"}})}finally{f.delete(p);}}let l={method:"GET",path:"/health",handler:u=>u.json({status:"healthy",timestamp:new Date().toISOString(),uptime:process.uptime(),activeRequests:f.size})},m={method:"GET",path:"/readiness",handler:u=>{let c=d.size>0,g=c||d.size===0;return u.json({ready:g,checks:{database:c?"connected":"not configured",activeRequests:f.size},timestamp:new Date().toISOString()},g?200:503)}};if(s.routes&&s.routes.forEach(u=>{h.push(u),(Array.isArray(u.method)?u.method:[u.method]).forEach(g=>{v.register(g,u.path,u.handler,u);});}),s.static){let u=Array.isArray(s.static)?s.static:[s.static];for(let c of u)try{let p=new I(c).handler(),b={method:"GET",path:c.path==="/"?"/*":`${c.path}/*`,handler:p};h.push(b),c.path==="/"?(v.register("GET","/",p,b),v.register("HEAD","/",p,b),v.register("GET","/*",p,b),v.register("HEAD","/*",p,b)):(v.register("GET",`${c.path}/*`,p,b),v.register("HEAD",`${c.path}/*`,p,b)),a?.info({urlPath:c.path,directory:c.directory,maxAge:c.maxAge||3600},"\u2714 Static file serving enabled");}catch(g){throw a?.error({error:String(g),path:c.path},"Failed to initialize static file server"),g}}h.push(l,m),v.register("GET","/health",l.handler,l),v.register("GET","/readiness",m.handler,m);let y=null,S={app:null,logger:a,db:d,bunServer:null,async start(){if(s.database){let c=Array.isArray(s.database)?s.database:[s.database];for(let g of c){let p=g.name||"default";try{if(typeof g.connection=="string"){let b=new _(g.connection);if(g.schema&&typeof g.schema=="object")for(let[L,$]of Object.entries(g.schema))$&&typeof $=="object"&&b.defineSchema($);d.set(p,b),a?.info({name:p,connection:g.connection},"\u2714 Database connected");}else throw new Error(`Database connection must be a string path (got ${typeof g.connection})`)}catch(b){throw a?.error({error:String(b),name:p},"Failed to connect to database"),b}}}y=Bun.serve({port:e,hostname:r,fetch:(c,g)=>C(c,g)}),S.bunServer=y;let u=`http://${r}:${e}`;a?.info({url:u},"Server started");},async stop(){if(a?.info("Stopping server..."),f.size>0){a?.info({count:f.size},"Waiting for active requests...");let u=Date.now()+i;for(;f.size>0&&Date.now()<u;)await new Promise(c=>setTimeout(c,100));f.size>0&&a?.warn({count:f.size},"Force closing with active requests");}if(clearInterval(x),s.onShutdown)try{await s.onShutdown();}catch(u){a?.error({error:String(u)},"Error in shutdown handler");}for(let[u,c]of d.entries())try{c&&typeof c.close=="function"&&c.close(),a?.info({name:u},"Database closed");}catch(g){a?.error({error:String(g),name:u},"Error closing database");}y&&(y.stop(),a?.info("Bun server stopped")),a?.info("Server stopped successfully");},addRoute(u){h.push(u),(Array.isArray(u.method)?u.method:[u.method]).forEach(g=>{v.register(g,u.path,u.handler,u);}),a?.info({method:u.method,path:u.path},"Route added");},addRoutes(u){u.forEach(c=>this.addRoute(c));},getRoutes(){return h}};return S}async function Re(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 D("Payload too large");if(!n.trim())return {};try{return JSON.parse(n)}catch(i){throw e?.warn({error:String(i),bodyPreview:n.substring(0,100)},"Invalid JSON in request body"),new D("Invalid JSON in request body")}}if(t.includes("application/x-www-form-urlencoded")){let n=await s.text();if(n.length>r)throw new D("Payload too large");return Object.fromEntries(new URLSearchParams(n))}if(t.includes("multipart/form-data"))return await s.formData()}catch(n){throw n instanceof D?n:(e?.error({error:String(n)},"Error parsing request body"),new D("Failed to parse request body"))}return {}}function ve(s){let e=new Map;if(!s)return e;let r=s.split(";");for(let t of r){let[n,...i]=t.trim().split("=");if(n){let o=i.join("=");e.set(n,o?decodeURIComponent(o):"");}}return e}function te(s,e,r,t,n,i){let o=new URL(e.url),a=Object.fromEntries(o.searchParams),d=e.headers,h=200,f=new Map,x=ve(d.get("cookie")||""),C={ip:s,request:e,params:r,query:a,headers:d,db:t,logger:n,requestId:i,get statusCode(){return h},set statusCode(l){h=l;},body:null,json(l,m){return new Response(JSON.stringify(l),{status:m??h,headers:{"Content-Type":"application/json",...this._setCookieHeaders()}})},text(l,m){return new Response(l,{status:m??h,headers:{"Content-Type":"text/plain",...this._setCookieHeaders()}})},html(l,m){return new Response(l,{status:m??h,headers:{"Content-Type":"text/html; charset=utf-8",...this._setCookieHeaders()}})},redirect(l,m=302){return new Response(null,{status:m,headers:{Location:l,...this._setCookieHeaders()}})},file(l,m="application/octet-stream"){let y=Bun.file(l);return new Response(y,{headers:{"Content-Type":m,...this._setCookieHeaders()}})},setCookie(l,m,y={}){let S=`${l}=${encodeURIComponent(m)}`;return y.maxAge!==void 0&&(S+=`; Max-Age=${y.maxAge}`),y.expires&&(S+=`; Expires=${y.expires.toUTCString()}`),y.path&&(S+=`; Path=${y.path}`),y.domain&&(S+=`; Domain=${y.domain}`),y.secure&&(S+="; Secure"),y.httpOnly&&(S+="; HttpOnly"),y.sameSite&&(S+=`; SameSite=${y.sameSite}`),f.set(l,S),C},getCookie(l){return x.get(l)},deleteCookie(l,m={}){return C.setCookie(l,"",{...m,maxAge:0,path:m.path||"/"})},setHeader(l,m){return d.set(l,m),C},getHeader(l){return d.get(l)||void 0},status(l){return h=l,C},_setCookieHeaders(){let l={};return f.size>0&&(l["Set-Cookie"]=Array.from(f.values())),l}};return C}function $e(s,e){let r=s.headers.get("x-forwarded-for");if(r)return r.split(",").map(i=>i.trim())[0]||"unknown";let t=s.headers.get("x-real-ip");if(t)return t;if(e)try{let n=e.requestIP(s);if(n?.address)return n.address}catch{}return "unknown"}function Ee(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 i=t.methods||["GET","POST","PUT","DELETE","PATCH","OPTIONS"];r.set("Access-Control-Allow-Methods",i.join(", "));let o=t.allowedHeaders||["Content-Type","Authorization","X-Requested-With"];r.set("Access-Control-Allow-Headers",o.join(", ")),t.credentials&&r.set("Access-Control-Allow-Credentials","true"),t.maxAge&&r.set("Access-Control-Max-Age",t.maxAge.toString());}return r}var Ue=Se;
|
|
2
|
-
exports.AppError=
|
|
1
|
+
'use strict';Object.defineProperty(exports,'__esModule',{value:true});var bun_sqlite=require('bun:sqlite'),me=require('crypto'),path=require('path'),fs=require('fs');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var me__default=/*#__PURE__*/_interopDefault(me);var _=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 i=`CREATE ${t.unique?"UNIQUE":""} INDEX IF NOT EXISTS ${t.name} ON ${e.name} (${t.columns.join(", ")})`;this.db.exec(i);}}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,i])=>({column:n,operator:"=",value:i}));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 i=(Array.isArray(t)?t:[t]).map(o=>{if(o.operator==="IS NULL"||o.operator==="IS NOT NULL")return `${o.column} ${o.operator}`;if(o.operator==="IN"&&Array.isArray(o.value)){let a=o.value.map(()=>"?").join(", ");return o.value.forEach(c=>{r.currentParams.push(c);}),`${o.column} IN (${a})`}else return r.currentParams.push(o.value),`${o.column} ${o.operator} ?`});return this._where.push(...i),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(i=>{r.currentParams.push(i);}),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 o=Object.keys(this._insertData),a=o.map(()=>"?").join(", ");t=`INSERT INTO ${this._from} (${o.join(", ")}) VALUES (${a})`,r.currentParams=Object.values(this._insertData);}else if(this._isUpdate&&this._updateData){let o=Object.keys(this._updateData).map(c=>`${c} = ?`),a=Object.values(this._updateData);r.currentParams=[...a,...r.currentParams],t=`UPDATE ${this._from} SET ${o.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 i=r.db.query(t).all(...r.currentParams);return r.reset(),i},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 se(s,e){return {name:s,columns:e}}function ie(s,e){return {name:s,type:e}}function oe(s){return {name:s,type:"INTEGER"}}function ae(s){return {name:s,type:"TEXT"}}function ue(s){return {name:s,type:"REAL"}}function le(s){return {name:s,type:"BLOB"}}function ce(s){return {name:s,type:"NUMERIC"}}function de(s,e=false){return {...s,primaryKey:true,autoIncrement:e}}function pe(s){return {...s,notNull:true}}function fe(s){return {...s,unique:true}}function ge(s,e){return {...s,default:e}}function he(s,e,r){return {...s,references:{table:e,column:r}}}var k=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 i=r.match(n.pattern);if(i){let o=i.groups||{};return {handler:n.handler,params:o}}}return null}getAll(){let e=Array.from(this.routes.entries()).map(([t,n])=>{let i=t.indexOf(":"),o=t.substring(0,i),a=t.substring(i+1);return {method:o,path:a,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(i=>i.key===t);return n>=0?(this.regexRoutes.splice(n,1),true):false}register(e,r,t,n={}){let i=`${e}:${r}`;if(r.includes(":")||r.includes("*")){let o=this.pathToRegex(r),a=this.regexRoutes.findIndex(h=>h.key===i),c={pattern:o,method:e,handler:t,key:i};a>=0?this.regexRoutes[a]=c:this.regexRoutes.push(c);}else this.routes.set(i,t);}pathToRegex(e){let r=e.replace(/[.+?^${}()|[\]\\]/g,"\\$&");return r=r.replace(/:(\w+)/g,"(?<$1>[^/]+)"),r=r.replace(/\*/g,".*"),new RegExp(`^${r}$`)}};var j=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(),i=this.rateLimitStore.get(e);return i?n<i.reset?i.count>=r?false:(i.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=me__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,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/"):""}sanitizeSql(e){return e?e.replace(/\\/g,"\\\\").replace(/;/g,"").replace(/'/g,"''").replace(/"/g,'\\"').replace(/\x00/g,""):""}logRequest(e,r,t,n,i,o){if(this.requestLog.set(e,{timestamp:new Date().toISOString(),method:r,path:t,ip:n,status:i,duration:o}),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",r=false){this.level=1;this.pretty=false;this.levels={debug:0,info:1,warn:2,error:3,fatal:4};this.colors={reset:"\x1B[0m",gray:"\x1B[90m",cyan:"\x1B[36m",green:"\x1B[32m",yellow:"\x1B[33m",red:"\x1B[31m",magenta:"\x1B[35m",bold:"\x1B[1m"};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 i,o;if(typeof t=="string"?(o=t,i={}):(i=t??{},o=n),this.pretty)this.prettyLog(e,i,o);else {let c={timestamp:new Date().toISOString(),level:e.toUpperCase(),message:o||"No message",...i},h=JSON.stringify(c);e==="error"||e==="fatal"?console.error(h):e==="warn"?console.warn(h):console.log(h);}}prettyLog(e,r,t){let n=this.colors,i=new Date().toLocaleTimeString("en-US",{hour12:false});if(r.method&&r.path&&r.status!==void 0){let f=this.colorizeMethod(r.method),x=this.colorizeStatus(r.status),C=r.duration?`${r.duration}ms`:"",l=r.path;console.log(`${n.gray}${i}${n.reset} ${f} ${n.bold}${l}${n.reset} ${x} ${n.gray}${C}${n.reset}`);return}if(t==="Route added"&&r.method&&r.path){let f=Array.isArray(r.method)?r.method.join("|"):r.method;console.log(`${n.gray}${i}${n.reset} ${n.cyan}\u2192${n.reset} ${n.bold}${f.padEnd(6)}${n.reset} ${r.path}`);return}if(t==="\u2714 Database connected"){console.log(`${n.gray}${i}${n.reset} ${n.green}\u2713${n.reset} Database connected ${n.gray}(${r.name})${n.reset}`);return}if(t==="Server started"){console.log(`${n.gray}${i}${n.reset} ${n.green}\u2713${n.reset} Server started at ${n.cyan}${r.url}${n.reset}`);return}let o=this.getLevelIcon(e),a=this.getLevelColor(e),c=`${n.gray}${i}${n.reset} ${a}${o}${n.reset} `;t&&(c+=`${t} `);let h=Object.keys(r).filter(f=>!["timestamp","level","message"].includes(f));if(h.length>0){let f=h.map(x=>{let C=r[x];return typeof C=="string"||typeof C=="number"?`${n.gray}${x}:${n.reset}${C}`:null}).filter(Boolean);f.length>0&&(c+=n.gray+f.join(" ")+n.reset);}console.log(c);}colorizeMethod(e){let r=this.colors,t=e.toUpperCase();switch(t){case "GET":return `${r.green}${t}${r.reset}`;case "POST":return `${r.cyan}${t}${r.reset}`;case "PUT":return `${r.yellow}${t}${r.reset}`;case "DELETE":return `${r.red}${t}${r.reset}`;case "PATCH":return `${r.magenta}${t}${r.reset}`;default:return `${r.gray}${t}${r.reset}`}}colorizeStatus(e){if(!e)return "";let r=this.colors,t=e.toString();return e>=200&&e<300?`${r.green}${t}${r.reset}`:e>=300&&e<400?`${r.cyan}${t}${r.reset}`:e>=400&&e<500?`${r.yellow}${t}${r.reset}`:e>=500?`${r.red}${t}${r.reset}`:`${r.gray}${t}${r.reset}`}getLevelIcon(e){switch(e){case "debug":return "-";case "info":return "-";case "warn":return "-";case "error":return "-";case "fatal":return "-";default:return "-"}}getLevelColor(e){let r=this.colors;switch(e){case "debug":return r.gray;case "info":return r.cyan;case "warn":return r.yellow;case "error":return r.red;case "fatal":return r.red+r.bold;default:return r.reset}}};var A=class extends Error{constructor(r,t=500,n){super(r);this.message=r;this.statusCode=t;this.code=n;this.name="AppError";}},D=class extends A{constructor(r,t){super(r,400,"VALIDATION_ERROR");this.issues=t;this.name="ValidationError";}},Y=class extends A{constructor(e){super(e,500,"DATABASE_ERROR"),this.name="DatabaseError";}},H=class extends A{constructor(e="Request timeout"){super(e,408,"TIMEOUT_ERROR"),this.name="TimeoutError";}},Z=class extends A{constructor(e="Too many requests"){super(e,429,"RATE_LIMIT_ERROR"),this.name="RateLimitError";}};var I=class{constructor(e){this.fileCache=new Map;this.CACHE_MAX_SIZE=1e3;if(!fs.existsSync(e.directory))throw new Error(`Static directory does not exist: ${e.directory}`);if(!fs.statSync(e.directory).isDirectory())throw new Error(`Static path is not a directory: ${e.directory}`);this.resolvedDir=path.resolve(e.directory),this.config={path:e.path,directory:e.directory,maxAge:e.maxAge??3600,index:e.index??["index.html"],dotfiles:e.dotfiles??"deny",etag:e.etag??true,lastModified:e.lastModified??true,immutable:e.immutable??false,extensions:e.extensions??[],fallthrough:e.fallthrough??false,setHeaders:e.setHeaders};}handler(){return async e=>{let r=e.request.url,n=new URL(r).pathname;n.startsWith(this.config.path)&&(n=n.slice(this.config.path.length));try{n=decodeURIComponent(n);}catch{return e.json({error:"Invalid URL encoding"},400)}if(n.includes("..")||n.includes("\\"))return e.json({error:"Forbidden"},403);if(this.config.dotfiles!=="allow"&&n.split("/").some(a=>a.startsWith(".")))return this.config.dotfiles==="deny"?e.json({error:"Forbidden"},403):this.handleNotFound(e);let i=this.resolveFilePath(n);if(!i)return this.handleNotFound(e);if(!this.isPathSafe(i))return e.json({error:"Forbidden"},403);if(!fs.existsSync(i))return this.handleNotFound(e);let o=fs.statSync(i);return o.isDirectory()?this.serveDirectory(e,i,n):this.serveFile(e,i,o)}}getPathPattern(){return `${this.config.path}/*`}resolveFilePath(e){e.startsWith("/")&&(e=e.slice(1));let r=path.join(this.resolvedDir,e);if(!fs.existsSync(r)&&this.config.extensions.length>0)for(let t of this.config.extensions){let n=`${r}.${t}`;if(fs.existsSync(n))return n}return r}isPathSafe(e){return !path.relative(this.resolvedDir,path.resolve(e)).startsWith("..")&&!path.resolve(e).startsWith("..")}async serveDirectory(e,r,t){for(let n of this.config.index){let i=path.join(r,n);if(fs.existsSync(i)){let o=fs.statSync(i);if(o.isFile())return this.serveFile(e,i,o)}}return this.handleNotFound(e)}async serveFile(e,r,t){let n=e.request.method.toUpperCase();if(n!=="GET"&&n!=="HEAD")return e.json({error:"Method not allowed"},405);let i=r,o=this.fileCache.get(i);if(o&&o.mtime!==t.mtimeMs&&(o=void 0),!o){if(o={etag:this.generateEtag(t),lastModified:new Date(t.mtime),size:t.size,mtime:t.mtimeMs},this.fileCache.size>=this.CACHE_MAX_SIZE){let x=this.fileCache.keys().next().value;x&&this.fileCache.delete(x);}this.fileCache.set(i,o);}let a=e.request.headers.get("if-none-match"),c=e.request.headers.get("if-modified-since");if(this.config.etag&&a===o.etag)return new Response(null,{status:304,headers:this.buildHeaders(r,o)});if(this.config.lastModified&&c){let x=new Date(c);if(o.lastModified<=x)return new Response(null,{status:304,headers:this.buildHeaders(r,o)})}let h=Bun.file(r),f=this.buildHeaders(r,o);return this.config.setHeaders&&this.config.setHeaders(e,r),n==="HEAD"?new Response(null,{status:200,headers:f}):new Response(h,{status:200,headers:f})}buildHeaders(e,r){let t=new Headers,n=this.getMimeType(e);if(t.set("Content-Type",n),t.set("Content-Length",r.size.toString()),this.config.etag&&t.set("ETag",r.etag),this.config.lastModified&&t.set("Last-Modified",r.lastModified.toUTCString()),this.config.maxAge>0){let i=`public, max-age=${this.config.maxAge}`;this.config.immutable&&(i+=", immutable"),t.set("Cache-Control",i);}else t.set("Cache-Control","no-cache");return t.set("Accept-Ranges","bytes"),t}generateEtag(e){return `"${e.size.toString(16)}-${e.mtimeMs.toString(16)}"`}getMimeType(e){let r=path.extname(e).toLowerCase();return we[r]||"application/octet-stream"}handleNotFound(e){return this.config.fallthrough?e.json({error:"Not Found"},404):e.json({error:"Not Found"},404)}clearCache(){this.fileCache.clear();}getCacheStats(){return {entries:this.fileCache.size,maxSize:this.CACHE_MAX_SIZE}}};function Ce(s){return new I(s)}var we={".html":"text/html; charset=utf-8",".htm":"text/html; charset=utf-8",".css":"text/css; charset=utf-8",".txt":"text/plain; charset=utf-8",".xml":"text/xml; charset=utf-8",".csv":"text/csv; charset=utf-8",".md":"text/markdown; charset=utf-8",".js":"application/javascript; charset=utf-8",".mjs":"application/javascript; charset=utf-8",".json":"application/json; charset=utf-8",".jsonld":"application/ld+json",".map":"application/json; charset=utf-8",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".svg":"image/svg+xml",".ico":"image/x-icon",".webp":"image/webp",".avif":"image/avif",".bmp":"image/bmp",".tiff":"image/tiff",".woff":"font/woff",".woff2":"font/woff2",".ttf":"font/ttf",".otf":"font/otf",".eot":"application/vnd.ms-fontobject",".mp3":"audio/mpeg",".wav":"audio/wav",".ogg":"audio/ogg",".m4a":"audio/mp4",".aac":"audio/aac",".flac":"audio/flac",".mp4":"video/mp4",".webm":"video/webm",".ogv":"video/ogg",".mov":"video/quicktime",".avi":"video/x-msvideo",".mkv":"video/x-matroska",".pdf":"application/pdf",".doc":"application/msword",".docx":"application/vnd.openxmlformats-officedocument.wordprocessingml.document",".xls":"application/vnd.ms-excel",".xlsx":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",".ppt":"application/vnd.ms-powerpoint",".pptx":"application/vnd.openxmlformats-officedocument.presentationml.presentation",".zip":"application/zip",".rar":"application/x-rar-compressed",".7z":"application/x-7z-compressed",".tar":"application/x-tar",".gz":"application/gzip",".wasm":"application/wasm",".manifest":"text/cache-manifest",".webmanifest":"application/manifest+json"};var U=new j,v=new k;function Se(s={}){let e=Number(s.port)||3e3,r=s.hostname||"localhost",t=s.maxRequestSize||10*1024*1024,n=s.requestTimeout||3e4,i=s.gracefulShutdownTimeout||1e4,o=typeof s.logging=="object"?s.logging:{},a=s.logging?new P(o.level||"info",o.pretty):null,c=new Map,h=[],f=new Set,x=setInterval(()=>{U.cleanupRateLimit(),U.cleanupCsrfTokens();},120*1e3);async function C(u,d){let g=Date.now(),p=crypto.randomUUID(),L=new URL(u.url).pathname,$=u.method.toUpperCase(),R=$e(u,d);f.add(p);try{let w=u.headers.get("content-length");if(w&&parseInt(w)>t)return a?.warn({requestId:p,size:w,ip:R},"Request too large"),new Response(JSON.stringify({error:"Payload too large"}),{status:413,headers:{"Content-Type":"application/json"}});let M=Ee(u,s);if($==="OPTIONS")return new Response(null,{status:204,headers:M});if(s.security&&typeof s.security=="object"&&s.security.rateLimit){let E=typeof s.security.rateLimit=="object"?s.security.rateLimit:{},q=E.max||100,V=E.windowMs||6e4,J=E.keyGenerator?E.keyGenerator({request:u,ip:R}):R;if(!U.checkRateLimit(J,q,V))return a?.warn({requestId:p,ip:R,key:J},"Rate limit exceeded"),new Response(JSON.stringify({error:E.message||"Too many requests"}),{status:429,headers:{"Content-Type":"application/json"}})}let W=null;["POST","PUT","PATCH"].includes($)&&(W=await Re(u,a,t));let G=c.get("default"),B=v.match($,L);if(!B){let E=te(R,u,{},G,a,p);return a?.warn({requestId:p,method:$,path:L,ip:R},"Route not found"),E.json({error:"Not Found",path:L},404)}let z=te(R,u,B.params||{},G,a,p);z.body=W,z.request=u;let X=new AbortController,re=new Promise((E,q)=>{let V=setTimeout(()=>{X.abort(),q(new H("Request timeout"));},n);X.signal.addEventListener("abort",()=>clearTimeout(V));}),O=await Promise.race([B.handler(z),re]),T=new Headers(O.headers);M.forEach((E,q)=>{T.has(q)||T.set(q,E);}),T.set("X-Request-ID",p),T.set("X-Content-Type-Options","nosniff"),T.set("X-Frame-Options","DENY"),T.set("X-XSS-Protection","1; mode=block"),T.set("Referrer-Policy","strict-origin-when-cross-origin");let K=Date.now()-g;return U.logRequest(p,$,L,R,O.status,K),a?.info({requestId:p,method:$,path:L,status:O.status,duration:K,ip:R},"Request completed"),new Response(O.body,{status:O.status,headers:T})}catch(w){if(w instanceof A)return a?.warn({error:w.message,requestId:p,ip:R},`App error: ${w.message}`),new Response(JSON.stringify({error:w.message,code:w.code,requestId:p}),{status:w.statusCode,headers:{"Content-Type":"application/json"}});a?.error({error:String(w),requestId:p,ip:R},"Unhandled error");let M=process.env.NODE_ENV==="production"?"Internal Server Error":w.message;return new Response(JSON.stringify({error:M,requestId:p}),{status:500,headers:{"Content-Type":"application/json"}})}finally{f.delete(p);}}let l={method:"GET",path:"/health",handler:u=>u.json({status:"healthy",timestamp:new Date().toISOString(),uptime:process.uptime(),activeRequests:f.size})},m={method:"GET",path:"/readiness",handler:u=>{let d=c.size>0,g=d||c.size===0;return u.json({ready:g,checks:{database:d?"connected":"not configured",activeRequests:f.size},timestamp:new Date().toISOString()},g?200:503)}};if(s.routes&&s.routes.forEach(u=>{h.push(u),(Array.isArray(u.method)?u.method:[u.method]).forEach(g=>{v.register(g,u.path,u.handler,u);});}),s.static){let u=Array.isArray(s.static)?s.static:[s.static];for(let d of u)try{let p=new I(d).handler(),b={method:"GET",path:d.path==="/"?"/*":`${d.path}/*`,handler:p};h.push(b),d.path==="/"?(v.register("GET","/",p,b),v.register("HEAD","/",p,b),v.register("GET","/*",p,b),v.register("HEAD","/*",p,b)):(v.register("GET",`${d.path}/*`,p,b),v.register("HEAD",`${d.path}/*`,p,b));}catch(g){throw a?.error({error:String(g),path:d.path},"Failed to initialize static file server"),g}}h.push(l,m),v.register("GET","/health",l.handler,l),v.register("GET","/readiness",m.handler,m);let y=null,S={app:null,logger:a,db:c,bunServer:null,async start(){if(s.database){let d=Array.isArray(s.database)?s.database:[s.database];for(let g of d){let p=g.name||"default";try{if(typeof g.connection=="string"){let b=new _(g.connection);if(g.schema&&typeof g.schema=="object")for(let[L,$]of Object.entries(g.schema))$&&typeof $=="object"&&b.defineSchema($);c.set(p,b),a?.info({name:p,connection:g.connection},"\u2714 Database connected");}else throw new Error(`Database connection must be a string path (got ${typeof g.connection})`)}catch(b){throw a?.error({error:String(b),name:p},"Failed to connect to database"),b}}}y=Bun.serve({port:e,hostname:r,fetch:(d,g)=>C(d,g)}),S.bunServer=y;let u=`http://${r}:${e}`;a?.info({url:u},"Server started");},async stop(){if(a?.info("Stopping server..."),f.size>0){a?.info({count:f.size},"Waiting for active requests...");let u=Date.now()+i;for(;f.size>0&&Date.now()<u;)await new Promise(d=>setTimeout(d,100));f.size>0&&a?.warn({count:f.size},"Force closing with active requests");}if(clearInterval(x),s.onShutdown)try{await s.onShutdown();}catch(u){a?.error({error:String(u)},"Error in shutdown handler");}for(let[u,d]of c.entries())try{d&&typeof d.close=="function"&&d.close(),a?.info({name:u},"Database closed");}catch(g){a?.error({error:String(g),name:u},"Error closing database");}y&&(y.stop(),a?.info("Bun server stopped")),a?.info("Server stopped successfully");},addRoute(u){h.push(u),(Array.isArray(u.method)?u.method:[u.method]).forEach(g=>{v.register(g,u.path,u.handler,u);}),a?.info({method:u.method,path:u.path},"Route added");},addRoutes(u){u.forEach(d=>this.addRoute(d));},getRoutes(){return h}};return S}async function Re(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 D("Payload too large");if(!n.trim())return {};try{return JSON.parse(n)}catch(i){throw e?.warn({error:String(i),bodyPreview:n.substring(0,100)},"Invalid JSON in request body"),new D("Invalid JSON in request body")}}if(t.includes("application/x-www-form-urlencoded")){let n=await s.text();if(n.length>r)throw new D("Payload too large");return Object.fromEntries(new URLSearchParams(n))}if(t.includes("multipart/form-data"))return await s.formData()}catch(n){throw n instanceof D?n:(e?.error({error:String(n)},"Error parsing request body"),new D("Failed to parse request body"))}return {}}function ve(s){let e=new Map;if(!s)return e;let r=s.split(";");for(let t of r){let[n,...i]=t.trim().split("=");if(n){let o=i.join("=");e.set(n,o?decodeURIComponent(o):"");}}return e}function te(s,e,r,t,n,i){let o=new URL(e.url),a=Object.fromEntries(o.searchParams),c=e.headers,h=200,f=new Map,x=ve(c.get("cookie")||""),C={ip:s,request:e,params:r,query:a,headers:c,db:t,logger:n,requestId:i,get statusCode(){return h},set statusCode(l){h=l;},body:null,json(l,m){return new Response(JSON.stringify(l),{status:m??h,headers:{"Content-Type":"application/json",...this._setCookieHeaders()}})},text(l,m){return new Response(l,{status:m??h,headers:{"Content-Type":"text/plain",...this._setCookieHeaders()}})},html(l,m){return new Response(l,{status:m??h,headers:{"Content-Type":"text/html; charset=utf-8",...this._setCookieHeaders()}})},redirect(l,m=302){return new Response(null,{status:m,headers:{Location:l,...this._setCookieHeaders()}})},file(l,m="application/octet-stream"){let y=Bun.file(l);return new Response(y,{headers:{"Content-Type":m,...this._setCookieHeaders()}})},setCookie(l,m,y={}){let S=`${l}=${encodeURIComponent(m)}`;return y.maxAge!==void 0&&(S+=`; Max-Age=${y.maxAge}`),y.expires&&(S+=`; Expires=${y.expires.toUTCString()}`),y.path&&(S+=`; Path=${y.path}`),y.domain&&(S+=`; Domain=${y.domain}`),y.secure&&(S+="; Secure"),y.httpOnly&&(S+="; HttpOnly"),y.sameSite&&(S+=`; SameSite=${y.sameSite}`),f.set(l,S),C},getCookie(l){return x.get(l)},deleteCookie(l,m={}){return C.setCookie(l,"",{...m,maxAge:0,path:m.path||"/"})},setHeader(l,m){return c.set(l,m),C},getHeader(l){return c.get(l)||void 0},status(l){return h=l,C},_setCookieHeaders(){let l={};return f.size>0&&(l["Set-Cookie"]=Array.from(f.values())),l}};return C}function $e(s,e){let r=s.headers.get("x-forwarded-for");if(r)return r.split(",").map(i=>i.trim())[0]||"unknown";let t=s.headers.get("x-real-ip");if(t)return t;if(e)try{let n=e.requestIP(s);if(n?.address)return n.address}catch{}return "unknown"}function Ee(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 i=t.methods||["GET","POST","PUT","DELETE","PATCH","OPTIONS"];r.set("Access-Control-Allow-Methods",i.join(", "));let o=t.allowedHeaders||["Content-Type","Authorization","X-Requested-With"];r.set("Access-Control-Allow-Headers",o.join(", ")),t.credentials&&r.set("Access-Control-Allow-Credentials","true"),t.maxAge&&r.set("Access-Control-Max-Age",t.maxAge.toString());}return r}var Ue=Se;
|
|
2
|
+
exports.AppError=A;exports.DB=_;exports.DatabaseError=Y;exports.Logger=P;exports.RateLimitError=Z;exports.Router=k;exports.SecurityManager=j;exports.StaticFileServer=I;exports.TimeoutError=H;exports.ValidationError=D;exports.blob=le;exports.column=ie;exports.createStatic=Ce;exports.default=Ue;exports.defaultValue=ge;exports.integer=oe;exports.notNull=pe;exports.numeric=ce;exports.primaryKey=de;exports.real=ue;exports.references=he;exports.server=Se;exports.table=se;exports.text=ae;exports.unique=fe;//# sourceMappingURL=main.cjs.map
|
|
3
3
|
//# sourceMappingURL=main.cjs.map
|