elit 3.1.6 → 3.1.7
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/dist/build.d.mts +3 -1
- package/dist/cli.js +380 -218
- package/dist/database.d.mts +31 -0
- package/dist/database.d.ts +30 -0
- package/dist/database.d.ts.map +1 -0
- package/dist/database.js +1197 -0
- package/dist/database.mjs +1170 -0
- package/dist/hmr.d.ts.map +1 -1
- package/dist/hmr.js +4 -5
- package/dist/hmr.mjs +4 -5
- package/dist/index.js +4 -5
- package/dist/index.mjs +4 -5
- package/dist/{server-D8ktU14v.d.mts → server-CRNme9Bc.d.mts} +14 -1
- package/dist/{server-CkRUWELa.d.ts → server-R_AfcxRw.d.ts} +14 -1
- package/dist/server.d.mts +3 -1
- package/dist/server.d.ts +10 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +367 -209
- package/dist/server.mjs +365 -209
- package/dist/types.d.mts +14 -0
- package/dist/types.d.ts +7 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +8 -2
- package/src/cli.ts +2 -1
- package/src/database.ts +177 -0
- package/src/hmr.ts +7 -6
- package/src/server.ts +65 -25
- package/src/types.ts +7 -0
package/dist/server.js
CHANGED
|
@@ -709,205 +709,205 @@ async function processDenoEntriesAsync(iterator, withFileTypes) {
|
|
|
709
709
|
}
|
|
710
710
|
return entries;
|
|
711
711
|
}
|
|
712
|
-
async function readFile(
|
|
712
|
+
async function readFile(path2, options) {
|
|
713
713
|
const opts = parseOptions(options, {});
|
|
714
714
|
if (isNode) {
|
|
715
|
-
return fsPromises.readFile(
|
|
715
|
+
return fsPromises.readFile(path2, opts);
|
|
716
716
|
} else if (isBun) {
|
|
717
|
-
const file = Bun.file(
|
|
717
|
+
const file = Bun.file(path2);
|
|
718
718
|
const content = await file.arrayBuffer();
|
|
719
719
|
return decodeContent(content, opts.encoding);
|
|
720
720
|
} else if (isDeno) {
|
|
721
|
-
const content = await Deno.readFile(
|
|
721
|
+
const content = await Deno.readFile(path2);
|
|
722
722
|
return decodeContent(content, opts.encoding);
|
|
723
723
|
}
|
|
724
724
|
throw new Error("Unsupported runtime");
|
|
725
725
|
}
|
|
726
|
-
function readFileSync(
|
|
726
|
+
function readFileSync(path2, options) {
|
|
727
727
|
const opts = parseOptions(options, {});
|
|
728
728
|
if (isNode) {
|
|
729
|
-
return fs.readFileSync(
|
|
729
|
+
return fs.readFileSync(path2, opts);
|
|
730
730
|
} else if (isBun) {
|
|
731
|
-
const file = Bun.file(
|
|
731
|
+
const file = Bun.file(path2);
|
|
732
732
|
const content = file.arrayBuffer();
|
|
733
733
|
return decodeContent(content, opts.encoding);
|
|
734
734
|
} else if (isDeno) {
|
|
735
|
-
const content = Deno.readFileSync(
|
|
735
|
+
const content = Deno.readFileSync(path2);
|
|
736
736
|
return decodeContent(content, opts.encoding);
|
|
737
737
|
}
|
|
738
738
|
throw new Error("Unsupported runtime");
|
|
739
739
|
}
|
|
740
|
-
async function writeFile(
|
|
740
|
+
async function writeFile(path2, data, options) {
|
|
741
741
|
const opts = parseOptions(options, {});
|
|
742
742
|
if (isNode) {
|
|
743
|
-
return fsPromises.writeFile(
|
|
743
|
+
return fsPromises.writeFile(path2, data, opts);
|
|
744
744
|
} else if (isBun) {
|
|
745
|
-
await Bun.write(
|
|
745
|
+
await Bun.write(path2, data);
|
|
746
746
|
} else if (isDeno) {
|
|
747
|
-
await Deno.writeFile(
|
|
747
|
+
await Deno.writeFile(path2, dataToUint8Array(data));
|
|
748
748
|
}
|
|
749
749
|
}
|
|
750
|
-
function writeFileSync(
|
|
750
|
+
function writeFileSync(path2, data, options) {
|
|
751
751
|
const opts = parseOptions(options, {});
|
|
752
752
|
if (isNode) {
|
|
753
|
-
fs.writeFileSync(
|
|
753
|
+
fs.writeFileSync(path2, data, opts);
|
|
754
754
|
} else if (isBun) {
|
|
755
|
-
Bun.write(
|
|
755
|
+
Bun.write(path2, data);
|
|
756
756
|
} else if (isDeno) {
|
|
757
|
-
Deno.writeFileSync(
|
|
757
|
+
Deno.writeFileSync(path2, dataToUint8Array(data));
|
|
758
758
|
}
|
|
759
759
|
}
|
|
760
|
-
async function appendFile(
|
|
760
|
+
async function appendFile(path2, data, options) {
|
|
761
761
|
const opts = parseOptions(options, {});
|
|
762
762
|
if (isNode) {
|
|
763
|
-
return fsPromises.appendFile(
|
|
763
|
+
return fsPromises.appendFile(path2, data, opts);
|
|
764
764
|
} else {
|
|
765
|
-
if (await exists(
|
|
766
|
-
const existing = await readFile(
|
|
765
|
+
if (await exists(path2)) {
|
|
766
|
+
const existing = await readFile(path2);
|
|
767
767
|
const combined = Buffer.isBuffer(existing) ? Buffer.concat([existing, Buffer.isBuffer(data) ? data : Buffer.from(data)]) : existing + (Buffer.isBuffer(data) ? data.toString() : data);
|
|
768
|
-
await writeFile(
|
|
768
|
+
await writeFile(path2, combined, opts);
|
|
769
769
|
} else {
|
|
770
|
-
await writeFile(
|
|
770
|
+
await writeFile(path2, data, opts);
|
|
771
771
|
}
|
|
772
772
|
}
|
|
773
773
|
}
|
|
774
|
-
function appendFileSync(
|
|
774
|
+
function appendFileSync(path2, data, options) {
|
|
775
775
|
const opts = parseOptions(options, {});
|
|
776
776
|
if (isNode) {
|
|
777
|
-
fs.appendFileSync(
|
|
777
|
+
fs.appendFileSync(path2, data, opts);
|
|
778
778
|
} else {
|
|
779
|
-
if (existsSync(
|
|
780
|
-
const existing = readFileSync(
|
|
779
|
+
if (existsSync(path2)) {
|
|
780
|
+
const existing = readFileSync(path2);
|
|
781
781
|
const combined = Buffer.isBuffer(existing) ? Buffer.concat([existing, Buffer.isBuffer(data) ? data : Buffer.from(data)]) : existing + (Buffer.isBuffer(data) ? data.toString() : data);
|
|
782
|
-
writeFileSync(
|
|
782
|
+
writeFileSync(path2, combined, opts);
|
|
783
783
|
} else {
|
|
784
|
-
writeFileSync(
|
|
784
|
+
writeFileSync(path2, data, opts);
|
|
785
785
|
}
|
|
786
786
|
}
|
|
787
787
|
}
|
|
788
|
-
async function exists(
|
|
788
|
+
async function exists(path2) {
|
|
789
789
|
try {
|
|
790
|
-
await stat(
|
|
790
|
+
await stat(path2);
|
|
791
791
|
return true;
|
|
792
792
|
} catch {
|
|
793
793
|
return false;
|
|
794
794
|
}
|
|
795
795
|
}
|
|
796
|
-
function existsSync(
|
|
796
|
+
function existsSync(path2) {
|
|
797
797
|
try {
|
|
798
|
-
statSync(
|
|
798
|
+
statSync(path2);
|
|
799
799
|
return true;
|
|
800
800
|
} catch {
|
|
801
801
|
return false;
|
|
802
802
|
}
|
|
803
803
|
}
|
|
804
|
-
async function stat(
|
|
804
|
+
async function stat(path2) {
|
|
805
805
|
if (isNode) {
|
|
806
|
-
return fsPromises.stat(
|
|
806
|
+
return fsPromises.stat(path2);
|
|
807
807
|
} else if (isBun) {
|
|
808
|
-
const file = Bun.file(
|
|
808
|
+
const file = Bun.file(path2);
|
|
809
809
|
const size = file.size;
|
|
810
810
|
const exists2 = await file.exists();
|
|
811
811
|
if (!exists2) {
|
|
812
|
-
throw new Error(`ENOENT: no such file or directory, stat '${
|
|
812
|
+
throw new Error(`ENOENT: no such file or directory, stat '${path2}'`);
|
|
813
813
|
}
|
|
814
|
-
return createStatsObject(
|
|
814
|
+
return createStatsObject(path2, size, false);
|
|
815
815
|
} else if (isDeno) {
|
|
816
|
-
const info = await Deno.stat(
|
|
816
|
+
const info = await Deno.stat(path2);
|
|
817
817
|
return createStatsFromDenoFileInfo(info);
|
|
818
818
|
}
|
|
819
819
|
throw new Error("Unsupported runtime");
|
|
820
820
|
}
|
|
821
|
-
function statSync(
|
|
821
|
+
function statSync(path2) {
|
|
822
822
|
if (isNode) {
|
|
823
|
-
return fs.statSync(
|
|
823
|
+
return fs.statSync(path2);
|
|
824
824
|
} else if (isBun) {
|
|
825
|
-
const file = Bun.file(
|
|
825
|
+
const file = Bun.file(path2);
|
|
826
826
|
const size = file.size;
|
|
827
827
|
try {
|
|
828
828
|
file.arrayBuffer();
|
|
829
829
|
} catch {
|
|
830
|
-
throw new Error(`ENOENT: no such file or directory, stat '${
|
|
830
|
+
throw new Error(`ENOENT: no such file or directory, stat '${path2}'`);
|
|
831
831
|
}
|
|
832
|
-
return createStatsObject(
|
|
832
|
+
return createStatsObject(path2, size, false);
|
|
833
833
|
} else if (isDeno) {
|
|
834
|
-
const info = Deno.statSync(
|
|
834
|
+
const info = Deno.statSync(path2);
|
|
835
835
|
return createStatsFromDenoFileInfo(info);
|
|
836
836
|
}
|
|
837
837
|
throw new Error("Unsupported runtime");
|
|
838
838
|
}
|
|
839
|
-
async function mkdir(
|
|
839
|
+
async function mkdir(path2, options) {
|
|
840
840
|
const opts = typeof options === "number" ? { mode: options } : options || {};
|
|
841
841
|
if (isNode) {
|
|
842
|
-
await fsPromises.mkdir(
|
|
842
|
+
await fsPromises.mkdir(path2, opts);
|
|
843
843
|
} else if (isBun) {
|
|
844
|
-
await Deno.mkdir(
|
|
844
|
+
await Deno.mkdir(path2, { recursive: opts.recursive });
|
|
845
845
|
} else if (isDeno) {
|
|
846
|
-
await Deno.mkdir(
|
|
846
|
+
await Deno.mkdir(path2, { recursive: opts.recursive });
|
|
847
847
|
}
|
|
848
848
|
}
|
|
849
|
-
function mkdirSync(
|
|
849
|
+
function mkdirSync(path2, options) {
|
|
850
850
|
const opts = typeof options === "number" ? { mode: options } : options || {};
|
|
851
851
|
if (isNode) {
|
|
852
|
-
fs.mkdirSync(
|
|
852
|
+
fs.mkdirSync(path2, opts);
|
|
853
853
|
} else if (isBun) {
|
|
854
|
-
Deno.mkdirSync(
|
|
854
|
+
Deno.mkdirSync(path2, { recursive: opts.recursive });
|
|
855
855
|
} else if (isDeno) {
|
|
856
|
-
Deno.mkdirSync(
|
|
856
|
+
Deno.mkdirSync(path2, { recursive: opts.recursive });
|
|
857
857
|
}
|
|
858
858
|
}
|
|
859
|
-
async function readdir(
|
|
859
|
+
async function readdir(path2, options) {
|
|
860
860
|
const opts = parseOptions(options, {});
|
|
861
861
|
if (isNode) {
|
|
862
|
-
return fsPromises.readdir(
|
|
862
|
+
return fsPromises.readdir(path2, opts);
|
|
863
863
|
} else if (isBunOrDeno) {
|
|
864
|
-
return processDenoEntriesAsync(Deno.readDir(
|
|
864
|
+
return processDenoEntriesAsync(Deno.readDir(path2), opts.withFileTypes);
|
|
865
865
|
}
|
|
866
866
|
throw new Error("Unsupported runtime");
|
|
867
867
|
}
|
|
868
|
-
function readdirSync(
|
|
868
|
+
function readdirSync(path2, options) {
|
|
869
869
|
const opts = parseOptions(options, {});
|
|
870
870
|
if (isNode) {
|
|
871
|
-
return fs.readdirSync(
|
|
871
|
+
return fs.readdirSync(path2, opts);
|
|
872
872
|
} else if (isBunOrDeno) {
|
|
873
|
-
return processDenoEntries(Deno.readDirSync(
|
|
873
|
+
return processDenoEntries(Deno.readDirSync(path2), opts.withFileTypes);
|
|
874
874
|
}
|
|
875
875
|
throw new Error("Unsupported runtime");
|
|
876
876
|
}
|
|
877
|
-
async function unlink(
|
|
877
|
+
async function unlink(path2) {
|
|
878
878
|
if (isNode) {
|
|
879
|
-
return fsPromises.unlink(
|
|
879
|
+
return fsPromises.unlink(path2);
|
|
880
880
|
} else if (isBun) {
|
|
881
|
-
await Deno.remove(
|
|
881
|
+
await Deno.remove(path2);
|
|
882
882
|
} else if (isDeno) {
|
|
883
|
-
await Deno.remove(
|
|
883
|
+
await Deno.remove(path2);
|
|
884
884
|
}
|
|
885
885
|
}
|
|
886
|
-
function unlinkSync(
|
|
886
|
+
function unlinkSync(path2) {
|
|
887
887
|
if (isNode) {
|
|
888
|
-
fs.unlinkSync(
|
|
888
|
+
fs.unlinkSync(path2);
|
|
889
889
|
} else if (isBun) {
|
|
890
|
-
Deno.removeSync(
|
|
890
|
+
Deno.removeSync(path2);
|
|
891
891
|
} else if (isDeno) {
|
|
892
|
-
Deno.removeSync(
|
|
892
|
+
Deno.removeSync(path2);
|
|
893
893
|
}
|
|
894
894
|
}
|
|
895
|
-
async function rmdir(
|
|
895
|
+
async function rmdir(path2, options) {
|
|
896
896
|
if (isNode) {
|
|
897
|
-
return fsPromises.rmdir(
|
|
897
|
+
return fsPromises.rmdir(path2, options);
|
|
898
898
|
} else if (isBun) {
|
|
899
|
-
await Deno.remove(
|
|
899
|
+
await Deno.remove(path2, { recursive: options?.recursive });
|
|
900
900
|
} else if (isDeno) {
|
|
901
|
-
await Deno.remove(
|
|
901
|
+
await Deno.remove(path2, { recursive: options?.recursive });
|
|
902
902
|
}
|
|
903
903
|
}
|
|
904
|
-
function rmdirSync(
|
|
904
|
+
function rmdirSync(path2, options) {
|
|
905
905
|
if (isNode) {
|
|
906
|
-
fs.rmdirSync(
|
|
906
|
+
fs.rmdirSync(path2, options);
|
|
907
907
|
} else if (isBun) {
|
|
908
|
-
Deno.removeSync(
|
|
908
|
+
Deno.removeSync(path2, { recursive: options?.recursive });
|
|
909
909
|
} else if (isDeno) {
|
|
910
|
-
Deno.removeSync(
|
|
910
|
+
Deno.removeSync(path2, { recursive: options?.recursive });
|
|
911
911
|
}
|
|
912
912
|
}
|
|
913
913
|
async function rename(oldPath, newPath) {
|
|
@@ -946,27 +946,27 @@ function copyFileSync(src, dest, flags) {
|
|
|
946
946
|
Deno.copyFileSync(src, dest);
|
|
947
947
|
}
|
|
948
948
|
}
|
|
949
|
-
async function realpath(
|
|
949
|
+
async function realpath(path2, options) {
|
|
950
950
|
if (isNode) {
|
|
951
|
-
return fsPromises.realpath(
|
|
951
|
+
return fsPromises.realpath(path2, options);
|
|
952
952
|
} else if (isBun) {
|
|
953
|
-
const
|
|
954
|
-
return
|
|
953
|
+
const fs3 = require("fs/promises");
|
|
954
|
+
return fs3.realpath(path2, options);
|
|
955
955
|
} else if (isDeno) {
|
|
956
|
-
return await Deno.realPath(
|
|
956
|
+
return await Deno.realPath(path2);
|
|
957
957
|
}
|
|
958
|
-
return
|
|
958
|
+
return path2;
|
|
959
959
|
}
|
|
960
|
-
function realpathSync(
|
|
960
|
+
function realpathSync(path2, options) {
|
|
961
961
|
if (isNode) {
|
|
962
|
-
return fs.realpathSync(
|
|
962
|
+
return fs.realpathSync(path2, options);
|
|
963
963
|
} else if (isBun) {
|
|
964
|
-
const
|
|
965
|
-
return
|
|
964
|
+
const fs3 = require("fs");
|
|
965
|
+
return fs3.realpathSync(path2, options);
|
|
966
966
|
} else if (isDeno) {
|
|
967
|
-
return Deno.realPathSync(
|
|
967
|
+
return Deno.realPathSync(path2);
|
|
968
968
|
}
|
|
969
|
-
return
|
|
969
|
+
return path2;
|
|
970
970
|
}
|
|
971
971
|
function createStatsObject(_path, size, isDir) {
|
|
972
972
|
const now = Date.now();
|
|
@@ -1109,12 +1109,14 @@ __export(server_exports, {
|
|
|
1109
1109
|
cors: () => cors,
|
|
1110
1110
|
createDevServer: () => createDevServer,
|
|
1111
1111
|
createProxyHandler: () => createProxyHandler,
|
|
1112
|
+
database: () => database2,
|
|
1112
1113
|
errorHandler: () => errorHandler,
|
|
1113
1114
|
html: () => html,
|
|
1114
1115
|
json: () => json,
|
|
1115
1116
|
logger: () => logger,
|
|
1116
1117
|
rateLimit: () => rateLimit,
|
|
1117
1118
|
security: () => security,
|
|
1119
|
+
serverDatabase: () => serverDatabase,
|
|
1118
1120
|
status: () => status,
|
|
1119
1121
|
text: () => text
|
|
1120
1122
|
});
|
|
@@ -1503,32 +1505,32 @@ var WebSocketServer = class extends import_events2.EventEmitter {
|
|
|
1503
1505
|
// src/chokidar.ts
|
|
1504
1506
|
var import_events3 = require("events");
|
|
1505
1507
|
init_runtime();
|
|
1506
|
-
function normalizePath(
|
|
1507
|
-
return
|
|
1508
|
+
function normalizePath(path2) {
|
|
1509
|
+
return path2.replace(/\\/g, "/");
|
|
1508
1510
|
}
|
|
1509
|
-
function emitEvent(watcher, eventType,
|
|
1510
|
-
watcher.emit(eventType,
|
|
1511
|
-
watcher.emit("all", eventType,
|
|
1511
|
+
function emitEvent(watcher, eventType, path2) {
|
|
1512
|
+
watcher.emit(eventType, path2);
|
|
1513
|
+
watcher.emit("all", eventType, path2);
|
|
1512
1514
|
}
|
|
1513
|
-
function matchesAnyPattern(
|
|
1514
|
-
return patterns.some((pattern) => matchesPattern(
|
|
1515
|
+
function matchesAnyPattern(path2, patterns) {
|
|
1516
|
+
return patterns.some((pattern) => matchesPattern(path2, pattern));
|
|
1515
1517
|
}
|
|
1516
|
-
function handleRenameEvent(watcher, fullPath,
|
|
1518
|
+
function handleRenameEvent(watcher, fullPath, fs3) {
|
|
1517
1519
|
try {
|
|
1518
|
-
|
|
1520
|
+
fs3.statSync(fullPath);
|
|
1519
1521
|
emitEvent(watcher, "add", fullPath);
|
|
1520
1522
|
} catch {
|
|
1521
1523
|
emitEvent(watcher, "unlink", fullPath);
|
|
1522
1524
|
}
|
|
1523
1525
|
}
|
|
1524
|
-
function setupFsWatch(watcher, baseDir, patterns,
|
|
1526
|
+
function setupFsWatch(watcher, baseDir, patterns, fs3) {
|
|
1525
1527
|
try {
|
|
1526
|
-
const nativeWatcher =
|
|
1528
|
+
const nativeWatcher = fs3.watch(baseDir, { recursive: true }, (eventType, filename) => {
|
|
1527
1529
|
if (!filename) return;
|
|
1528
1530
|
const fullPath = normalizePath(`${baseDir}/${filename}`);
|
|
1529
1531
|
if (!matchesAnyPattern(fullPath, patterns)) return;
|
|
1530
1532
|
if (eventType === "rename") {
|
|
1531
|
-
handleRenameEvent(watcher, fullPath,
|
|
1533
|
+
handleRenameEvent(watcher, fullPath, fs3);
|
|
1532
1534
|
} else if (eventType === "change") {
|
|
1533
1535
|
emitEvent(watcher, "change", fullPath);
|
|
1534
1536
|
}
|
|
@@ -1560,7 +1562,7 @@ var FSWatcher = class extends import_events3.EventEmitter {
|
|
|
1560
1562
|
this._watcher.add(pathArray);
|
|
1561
1563
|
}
|
|
1562
1564
|
} else {
|
|
1563
|
-
pathArray.forEach((
|
|
1565
|
+
pathArray.forEach((path2) => this._watched.add(path2));
|
|
1564
1566
|
}
|
|
1565
1567
|
return this;
|
|
1566
1568
|
}
|
|
@@ -1577,7 +1579,7 @@ var FSWatcher = class extends import_events3.EventEmitter {
|
|
|
1577
1579
|
this._watcher.unwatch(pathArray);
|
|
1578
1580
|
}
|
|
1579
1581
|
} else {
|
|
1580
|
-
pathArray.forEach((
|
|
1582
|
+
pathArray.forEach((path2) => this._watched.delete(path2));
|
|
1581
1583
|
}
|
|
1582
1584
|
return this;
|
|
1583
1585
|
}
|
|
@@ -1604,9 +1606,9 @@ var FSWatcher = class extends import_events3.EventEmitter {
|
|
|
1604
1606
|
return this._watcher.getWatched();
|
|
1605
1607
|
}
|
|
1606
1608
|
const result = {};
|
|
1607
|
-
this._watched.forEach((
|
|
1608
|
-
const dir =
|
|
1609
|
-
const file =
|
|
1609
|
+
this._watched.forEach((path2) => {
|
|
1610
|
+
const dir = path2.substring(0, path2.lastIndexOf("/")) || ".";
|
|
1611
|
+
const file = path2.substring(path2.lastIndexOf("/") + 1);
|
|
1610
1612
|
if (!result[dir]) {
|
|
1611
1613
|
result[dir] = [];
|
|
1612
1614
|
}
|
|
@@ -1643,19 +1645,19 @@ function watch(paths, options) {
|
|
|
1643
1645
|
const watcher = new FSWatcher(options);
|
|
1644
1646
|
const pathArray = Array.isArray(paths) ? paths : [paths];
|
|
1645
1647
|
const watchMap = /* @__PURE__ */ new Map();
|
|
1646
|
-
pathArray.forEach((
|
|
1647
|
-
const baseDir = getBaseDirectory(
|
|
1648
|
+
pathArray.forEach((path2) => {
|
|
1649
|
+
const baseDir = getBaseDirectory(path2);
|
|
1648
1650
|
if (!watchMap.has(baseDir)) {
|
|
1649
1651
|
watchMap.set(baseDir, []);
|
|
1650
1652
|
}
|
|
1651
|
-
watchMap.get(baseDir).push(
|
|
1653
|
+
watchMap.get(baseDir).push(path2);
|
|
1652
1654
|
});
|
|
1653
1655
|
if (runtime === "node") {
|
|
1654
|
-
const
|
|
1655
|
-
watchMap.forEach((patterns, baseDir) => setupFsWatch(watcher, baseDir, patterns,
|
|
1656
|
+
const fs3 = require("fs");
|
|
1657
|
+
watchMap.forEach((patterns, baseDir) => setupFsWatch(watcher, baseDir, patterns, fs3));
|
|
1656
1658
|
} else if (runtime === "bun") {
|
|
1657
|
-
const
|
|
1658
|
-
watchMap.forEach((patterns, baseDir) => setupFsWatch(watcher, baseDir, patterns,
|
|
1659
|
+
const fs3 = require("fs");
|
|
1660
|
+
watchMap.forEach((patterns, baseDir) => setupFsWatch(watcher, baseDir, patterns, fs3));
|
|
1659
1661
|
} else if (runtime === "deno") {
|
|
1660
1662
|
const baseDirs = Array.from(watchMap.keys());
|
|
1661
1663
|
const allPatterns = Array.from(watchMap.values()).flat();
|
|
@@ -1664,18 +1666,18 @@ function watch(paths, options) {
|
|
|
1664
1666
|
const denoWatcher = Deno.watchFs(baseDirs);
|
|
1665
1667
|
for await (const event of denoWatcher) {
|
|
1666
1668
|
if (watcher["_closed"]) break;
|
|
1667
|
-
for (const
|
|
1668
|
-
const normalizedPath = normalizePath(
|
|
1669
|
+
for (const path2 of event.paths) {
|
|
1670
|
+
const normalizedPath = normalizePath(path2);
|
|
1669
1671
|
if (!matchesAnyPattern(normalizedPath, allPatterns)) continue;
|
|
1670
1672
|
switch (event.kind) {
|
|
1671
1673
|
case "create":
|
|
1672
|
-
emitEvent(watcher, "add",
|
|
1674
|
+
emitEvent(watcher, "add", path2);
|
|
1673
1675
|
break;
|
|
1674
1676
|
case "modify":
|
|
1675
|
-
emitEvent(watcher, "change",
|
|
1677
|
+
emitEvent(watcher, "change", path2);
|
|
1676
1678
|
break;
|
|
1677
1679
|
case "remove":
|
|
1678
|
-
emitEvent(watcher, "unlink",
|
|
1680
|
+
emitEvent(watcher, "unlink", path2);
|
|
1679
1681
|
break;
|
|
1680
1682
|
}
|
|
1681
1683
|
}
|
|
@@ -1686,7 +1688,7 @@ function watch(paths, options) {
|
|
|
1686
1688
|
}
|
|
1687
1689
|
}
|
|
1688
1690
|
})();
|
|
1689
|
-
pathArray.forEach((
|
|
1691
|
+
pathArray.forEach((path2) => watcher.add(path2));
|
|
1690
1692
|
queueMicrotask(() => watcher.emit("ready"));
|
|
1691
1693
|
}
|
|
1692
1694
|
return watcher;
|
|
@@ -1708,38 +1710,38 @@ function getCwd() {
|
|
|
1708
1710
|
}
|
|
1709
1711
|
return "/";
|
|
1710
1712
|
}
|
|
1711
|
-
function findLastSeparator(
|
|
1712
|
-
return Math.max(
|
|
1713
|
+
function findLastSeparator(path2) {
|
|
1714
|
+
return Math.max(path2.lastIndexOf("/"), path2.lastIndexOf("\\"));
|
|
1713
1715
|
}
|
|
1714
1716
|
function createPathOps(isWin) {
|
|
1715
1717
|
return {
|
|
1716
1718
|
sep: getSeparator(isWin),
|
|
1717
1719
|
delimiter: isWin ? ";" : ":",
|
|
1718
|
-
normalize: (
|
|
1720
|
+
normalize: (path2) => normalizePath2(path2, isWin),
|
|
1719
1721
|
join: (...paths) => joinPaths(paths, isWin),
|
|
1720
1722
|
resolve: (...paths) => resolvePaths(paths, isWin),
|
|
1721
|
-
isAbsolute: (
|
|
1723
|
+
isAbsolute: (path2) => isWin ? isAbsoluteWin(path2) : isAbsolutePosix(path2),
|
|
1722
1724
|
relative: (from, to) => relativePath(from, to, isWin),
|
|
1723
|
-
dirname: (
|
|
1724
|
-
basename: (
|
|
1725
|
-
extname: (
|
|
1726
|
-
parse: (
|
|
1725
|
+
dirname: (path2) => getDirname(path2, isWin),
|
|
1726
|
+
basename: (path2, ext) => getBasename(path2, ext, isWin),
|
|
1727
|
+
extname: (path2) => getExtname(path2),
|
|
1728
|
+
parse: (path2) => parsePath(path2, isWin),
|
|
1727
1729
|
format: (pathObject) => formatPath(pathObject, isWin)
|
|
1728
1730
|
};
|
|
1729
1731
|
}
|
|
1730
|
-
function isAbsolutePosix(
|
|
1731
|
-
return
|
|
1732
|
+
function isAbsolutePosix(path2) {
|
|
1733
|
+
return path2.length > 0 && path2[0] === "/";
|
|
1732
1734
|
}
|
|
1733
|
-
function isAbsoluteWin(
|
|
1734
|
-
const len =
|
|
1735
|
+
function isAbsoluteWin(path2) {
|
|
1736
|
+
const len = path2.length;
|
|
1735
1737
|
if (len === 0) return false;
|
|
1736
|
-
const code =
|
|
1738
|
+
const code = path2.charCodeAt(0);
|
|
1737
1739
|
if (code === 47 || code === 92) {
|
|
1738
1740
|
return true;
|
|
1739
1741
|
}
|
|
1740
1742
|
if (code >= 65 && code <= 90 || code >= 97 && code <= 122) {
|
|
1741
|
-
if (len > 2 &&
|
|
1742
|
-
const code2 =
|
|
1743
|
+
if (len > 2 && path2.charCodeAt(1) === 58) {
|
|
1744
|
+
const code2 = path2.charCodeAt(2);
|
|
1743
1745
|
if (code2 === 47 || code2 === 92) {
|
|
1744
1746
|
return true;
|
|
1745
1747
|
}
|
|
@@ -1758,12 +1760,12 @@ var isWindows = (() => {
|
|
|
1758
1760
|
var sep = isWindows ? "\\" : "/";
|
|
1759
1761
|
var posix = createPathOps(false);
|
|
1760
1762
|
var win32 = createPathOps(true);
|
|
1761
|
-
function normalizePath2(
|
|
1762
|
-
if (
|
|
1763
|
+
function normalizePath2(path2, isWin) {
|
|
1764
|
+
if (path2.length === 0) return ".";
|
|
1763
1765
|
const separator = getSeparator(isWin);
|
|
1764
|
-
const isAbsolute = isWin ? isAbsoluteWin(
|
|
1765
|
-
const trailingSeparator =
|
|
1766
|
-
let normalized =
|
|
1766
|
+
const isAbsolute = isWin ? isAbsoluteWin(path2) : isAbsolutePosix(path2);
|
|
1767
|
+
const trailingSeparator = path2[path2.length - 1] === separator || isWin && path2[path2.length - 1] === "/";
|
|
1768
|
+
let normalized = path2.replace(isWin ? /[\/\\]+/g : /\/+/g, separator);
|
|
1767
1769
|
const parts = normalized.split(separator);
|
|
1768
1770
|
const result = [];
|
|
1769
1771
|
for (let i = 0; i < parts.length; i++) {
|
|
@@ -1798,12 +1800,12 @@ function joinPaths(paths, isWin) {
|
|
|
1798
1800
|
const separator = getSeparator(isWin);
|
|
1799
1801
|
let joined = "";
|
|
1800
1802
|
for (let i = 0; i < paths.length; i++) {
|
|
1801
|
-
const
|
|
1802
|
-
if (
|
|
1803
|
+
const path2 = paths[i];
|
|
1804
|
+
if (path2 && path2.length > 0) {
|
|
1803
1805
|
if (joined.length === 0) {
|
|
1804
|
-
joined =
|
|
1806
|
+
joined = path2;
|
|
1805
1807
|
} else {
|
|
1806
|
-
joined += separator +
|
|
1808
|
+
joined += separator + path2;
|
|
1807
1809
|
}
|
|
1808
1810
|
}
|
|
1809
1811
|
}
|
|
@@ -1815,9 +1817,9 @@ function resolvePaths(paths, isWin) {
|
|
|
1815
1817
|
let resolved = "";
|
|
1816
1818
|
let isAbsolute = false;
|
|
1817
1819
|
for (let i = paths.length - 1; i >= 0 && !isAbsolute; i--) {
|
|
1818
|
-
const
|
|
1819
|
-
if (
|
|
1820
|
-
resolved =
|
|
1820
|
+
const path2 = paths[i];
|
|
1821
|
+
if (path2 && path2.length > 0) {
|
|
1822
|
+
resolved = path2 + (resolved.length > 0 ? separator + resolved : "");
|
|
1821
1823
|
isAbsolute = isWin ? isAbsoluteWin(resolved) : isAbsolutePosix(resolved);
|
|
1822
1824
|
}
|
|
1823
1825
|
}
|
|
@@ -1853,51 +1855,51 @@ function relativePath(from, to, isWin) {
|
|
|
1853
1855
|
}
|
|
1854
1856
|
return result.join(separator) || ".";
|
|
1855
1857
|
}
|
|
1856
|
-
function getDirname(
|
|
1857
|
-
if (
|
|
1858
|
+
function getDirname(path2, isWin) {
|
|
1859
|
+
if (path2.length === 0) return ".";
|
|
1858
1860
|
const separator = getSeparator(isWin);
|
|
1859
|
-
const normalized = normalizePath2(
|
|
1861
|
+
const normalized = normalizePath2(path2, isWin);
|
|
1860
1862
|
const lastSepIndex = normalized.lastIndexOf(separator);
|
|
1861
1863
|
if (lastSepIndex === -1) return ".";
|
|
1862
1864
|
if (lastSepIndex === 0) return separator;
|
|
1863
1865
|
return normalized.slice(0, lastSepIndex);
|
|
1864
1866
|
}
|
|
1865
|
-
function getBasename(
|
|
1866
|
-
if (
|
|
1867
|
-
const lastSepIndex = isWin ? findLastSeparator(
|
|
1868
|
-
let base = lastSepIndex === -1 ?
|
|
1867
|
+
function getBasename(path2, ext, isWin) {
|
|
1868
|
+
if (path2.length === 0) return "";
|
|
1869
|
+
const lastSepIndex = isWin ? findLastSeparator(path2) : path2.lastIndexOf("/");
|
|
1870
|
+
let base = lastSepIndex === -1 ? path2 : path2.slice(lastSepIndex + 1);
|
|
1869
1871
|
if (ext && base.endsWith(ext)) {
|
|
1870
1872
|
base = base.slice(0, base.length - ext.length);
|
|
1871
1873
|
}
|
|
1872
1874
|
return base;
|
|
1873
1875
|
}
|
|
1874
|
-
function getExtname(
|
|
1875
|
-
const lastDotIndex =
|
|
1876
|
-
const lastSepIndex = findLastSeparator(
|
|
1877
|
-
if (lastDotIndex === -1 || lastDotIndex < lastSepIndex || lastDotIndex ===
|
|
1876
|
+
function getExtname(path2) {
|
|
1877
|
+
const lastDotIndex = path2.lastIndexOf(".");
|
|
1878
|
+
const lastSepIndex = findLastSeparator(path2);
|
|
1879
|
+
if (lastDotIndex === -1 || lastDotIndex < lastSepIndex || lastDotIndex === path2.length - 1) {
|
|
1878
1880
|
return "";
|
|
1879
1881
|
}
|
|
1880
|
-
return
|
|
1882
|
+
return path2.slice(lastDotIndex);
|
|
1881
1883
|
}
|
|
1882
|
-
function parsePath(
|
|
1884
|
+
function parsePath(path2, isWin) {
|
|
1883
1885
|
let root = "";
|
|
1884
1886
|
if (isWin) {
|
|
1885
|
-
if (
|
|
1886
|
-
root =
|
|
1887
|
-
if (
|
|
1887
|
+
if (path2.length >= 2 && path2[1] === ":") {
|
|
1888
|
+
root = path2.slice(0, 2);
|
|
1889
|
+
if (path2.length > 2 && (path2[2] === "\\" || path2[2] === "/")) {
|
|
1888
1890
|
root += "\\";
|
|
1889
1891
|
}
|
|
1890
|
-
} else if (
|
|
1892
|
+
} else if (path2[0] === "\\" || path2[0] === "/") {
|
|
1891
1893
|
root = "\\";
|
|
1892
1894
|
}
|
|
1893
1895
|
} else {
|
|
1894
|
-
if (
|
|
1896
|
+
if (path2[0] === "/") {
|
|
1895
1897
|
root = "/";
|
|
1896
1898
|
}
|
|
1897
1899
|
}
|
|
1898
|
-
const dir = getDirname(
|
|
1899
|
-
const base = getBasename(
|
|
1900
|
-
const ext = getExtname(
|
|
1900
|
+
const dir = getDirname(path2, isWin);
|
|
1901
|
+
const base = getBasename(path2, void 0, isWin);
|
|
1902
|
+
const ext = getExtname(path2);
|
|
1901
1903
|
const name = ext ? base.slice(0, base.length - ext.length) : base;
|
|
1902
1904
|
return { root, dir, base, ext, name };
|
|
1903
1905
|
}
|
|
@@ -1909,8 +1911,8 @@ function formatPath(pathObject, isWin) {
|
|
|
1909
1911
|
if (dir === pathObject.root) return dir + base;
|
|
1910
1912
|
return dir + separator + base;
|
|
1911
1913
|
}
|
|
1912
|
-
function normalize(
|
|
1913
|
-
return normalizePath2(
|
|
1914
|
+
function normalize(path2) {
|
|
1915
|
+
return normalizePath2(path2, isWindows);
|
|
1914
1916
|
}
|
|
1915
1917
|
function join(...paths) {
|
|
1916
1918
|
return joinPaths(paths, isWindows);
|
|
@@ -1921,8 +1923,8 @@ function resolve(...paths) {
|
|
|
1921
1923
|
function relative(from, to) {
|
|
1922
1924
|
return relativePath(from, to, isWindows);
|
|
1923
1925
|
}
|
|
1924
|
-
function extname(
|
|
1925
|
-
return getExtname(
|
|
1926
|
+
function extname(path2) {
|
|
1927
|
+
return getExtname(path2);
|
|
1926
1928
|
}
|
|
1927
1929
|
|
|
1928
1930
|
// src/mime-types.ts
|
|
@@ -2005,12 +2007,12 @@ for (const ext in MIME_TYPES) {
|
|
|
2005
2007
|
}
|
|
2006
2008
|
TYPE_TO_EXTENSIONS[type].push(ext);
|
|
2007
2009
|
}
|
|
2008
|
-
function getExtension(
|
|
2009
|
-
const match = /\.([^./\\]+)$/.exec(
|
|
2010
|
+
function getExtension(path2) {
|
|
2011
|
+
const match = /\.([^./\\]+)$/.exec(path2);
|
|
2010
2012
|
return match ? match[1].toLowerCase() : "";
|
|
2011
2013
|
}
|
|
2012
|
-
function lookup(
|
|
2013
|
-
const ext = getExtension(
|
|
2014
|
+
function lookup(path2) {
|
|
2015
|
+
const ext = getExtension(path2) || path2.toLowerCase();
|
|
2014
2016
|
return MIME_TYPES[ext] || false;
|
|
2015
2017
|
}
|
|
2016
2018
|
|
|
@@ -2657,29 +2659,169 @@ var dom = new DomNode();
|
|
|
2657
2659
|
var render = dom.render.bind(dom);
|
|
2658
2660
|
var renderToString = dom.renderToString.bind(dom);
|
|
2659
2661
|
|
|
2662
|
+
// src/database.ts
|
|
2663
|
+
var import_node_vm = __toESM(require("vm"));
|
|
2664
|
+
var import_node_path = __toESM(require("path"));
|
|
2665
|
+
var import_node_fs = __toESM(require("fs"));
|
|
2666
|
+
var esbuild = __toESM(require("esbuild"));
|
|
2667
|
+
var Database = class {
|
|
2668
|
+
constructor(config) {
|
|
2669
|
+
this._config = {
|
|
2670
|
+
dir: resolve(process.cwd(), "databases")
|
|
2671
|
+
};
|
|
2672
|
+
this._config = { ...this._config, ...config };
|
|
2673
|
+
this._registerModules = config.registerModules || {};
|
|
2674
|
+
this._ctx = import_node_vm.default.createContext(this._registerModules);
|
|
2675
|
+
}
|
|
2676
|
+
set config(config) {
|
|
2677
|
+
this._config = { ...this._config, ...config };
|
|
2678
|
+
}
|
|
2679
|
+
register(context) {
|
|
2680
|
+
this._registerModules = { ...this._registerModules, ...context };
|
|
2681
|
+
this._ctx = import_node_vm.default.createContext(this._registerModules);
|
|
2682
|
+
}
|
|
2683
|
+
plugin(moduleName, moduleContent) {
|
|
2684
|
+
this.register({ [moduleName]: moduleContent });
|
|
2685
|
+
}
|
|
2686
|
+
resolvePath(fileList, query) {
|
|
2687
|
+
const aliases = { "@db": this._config.dir || resolve(process.cwd(), "databases") };
|
|
2688
|
+
let resolvedPath = query;
|
|
2689
|
+
for (const [alias, target] of Object.entries(aliases)) {
|
|
2690
|
+
if (resolvedPath.startsWith(alias + "/")) {
|
|
2691
|
+
resolvedPath = resolvedPath.replace(alias, target);
|
|
2692
|
+
break;
|
|
2693
|
+
}
|
|
2694
|
+
}
|
|
2695
|
+
resolvedPath = import_node_path.default.normalize(resolvedPath);
|
|
2696
|
+
return fileList.find((file) => {
|
|
2697
|
+
const normalizedFile = import_node_path.default.normalize(file);
|
|
2698
|
+
const fileWithoutExt = normalizedFile.replace(/\.[^/.]+$/, "");
|
|
2699
|
+
return normalizedFile === resolvedPath || fileWithoutExt === resolvedPath || normalizedFile === resolvedPath + ".ts" || normalizedFile === resolvedPath + ".js";
|
|
2700
|
+
});
|
|
2701
|
+
}
|
|
2702
|
+
async moduleLinker(specifier, referencingModule) {
|
|
2703
|
+
const dbFiles = import_node_fs.default.readdirSync(this._config.dir || resolve(process.cwd(), "databases")).filter((f) => f.endsWith(".ts")).map((f) => import_node_path.default.join(this._config.dir || resolve(process.cwd(), "databases"), f));
|
|
2704
|
+
const dbResult = this.resolvePath(dbFiles, specifier);
|
|
2705
|
+
if (dbResult) {
|
|
2706
|
+
try {
|
|
2707
|
+
const actualModule = await import(dbResult);
|
|
2708
|
+
const exportNames = Object.keys(actualModule);
|
|
2709
|
+
return new import_node_vm.default.SyntheticModule(
|
|
2710
|
+
exportNames,
|
|
2711
|
+
function() {
|
|
2712
|
+
exportNames.forEach((key) => {
|
|
2713
|
+
this.setExport(key, actualModule[key]);
|
|
2714
|
+
});
|
|
2715
|
+
},
|
|
2716
|
+
{ identifier: specifier, context: referencingModule.context }
|
|
2717
|
+
);
|
|
2718
|
+
} catch (err) {
|
|
2719
|
+
console.error(`Failed to load database module ${specifier}:`, err);
|
|
2720
|
+
throw err;
|
|
2721
|
+
}
|
|
2722
|
+
}
|
|
2723
|
+
throw new Error(`Module ${specifier} is not allowed or not found.`);
|
|
2724
|
+
}
|
|
2725
|
+
async vmRun(code, _options) {
|
|
2726
|
+
const logs = [];
|
|
2727
|
+
const customConsole = ["log", "error", "warn", "info", "debug", "trace"].reduce((acc, type) => {
|
|
2728
|
+
acc[type] = (...args) => logs.push({ type, args });
|
|
2729
|
+
return acc;
|
|
2730
|
+
}, {});
|
|
2731
|
+
this.register({
|
|
2732
|
+
console: customConsole
|
|
2733
|
+
});
|
|
2734
|
+
let stringCode;
|
|
2735
|
+
if (typeof code === "function") {
|
|
2736
|
+
const funcStr = code.toString();
|
|
2737
|
+
const arrowMatch = funcStr.match(/^[\s]*\(?\s*\)?\s*=>\s*{?/);
|
|
2738
|
+
const functionMatch = funcStr.match(/^[\s]*function\s*\(?[\w\s]*\)?\s*{/);
|
|
2739
|
+
const match = arrowMatch || functionMatch;
|
|
2740
|
+
const start = match ? match[0].length : 0;
|
|
2741
|
+
const end = funcStr.lastIndexOf("}");
|
|
2742
|
+
stringCode = funcStr.substring(start, end);
|
|
2743
|
+
stringCode = stringCode.replace(/^[\s\r\n]+/, "").replace(/[\s\r\n]+$/, "");
|
|
2744
|
+
stringCode = stringCode.replace(
|
|
2745
|
+
/import\s*\(\s*([^)]+?)\s*\)\s*\.from\s*\(\s*(['"])([^'"]+)\2\s*\)/g,
|
|
2746
|
+
(_, importArg, quote, modulePath) => {
|
|
2747
|
+
const trimmed = importArg.trim();
|
|
2748
|
+
if (trimmed.startsWith("{") && trimmed.endsWith("}")) {
|
|
2749
|
+
const inner = trimmed.slice(1, -1).trim();
|
|
2750
|
+
return `import { ${inner} } from ${quote}${modulePath}${quote}`;
|
|
2751
|
+
} else {
|
|
2752
|
+
return `import ${trimmed} from ${quote}${modulePath}${quote}`;
|
|
2753
|
+
}
|
|
2754
|
+
}
|
|
2755
|
+
);
|
|
2756
|
+
stringCode = stringCode.split("\n").map((line) => line.trim()).join("\n").trim();
|
|
2757
|
+
} else {
|
|
2758
|
+
stringCode = code;
|
|
2759
|
+
}
|
|
2760
|
+
const result = await esbuild.build({
|
|
2761
|
+
stdin: {
|
|
2762
|
+
contents: stringCode,
|
|
2763
|
+
loader: this._config.language || "ts"
|
|
2764
|
+
},
|
|
2765
|
+
format: "esm",
|
|
2766
|
+
target: "es2020",
|
|
2767
|
+
write: false,
|
|
2768
|
+
bundle: false,
|
|
2769
|
+
sourcemap: false
|
|
2770
|
+
});
|
|
2771
|
+
const js = result.outputFiles[0].text;
|
|
2772
|
+
const mod = new import_node_vm.default.SourceTextModule(js, { context: this._ctx, identifier: import_node_path.default.join(this._config.dir || resolve(process.cwd(), "databases"), "virtual-entry.js") });
|
|
2773
|
+
await mod.link(this.moduleLinker.bind(this));
|
|
2774
|
+
await mod.evaluate();
|
|
2775
|
+
return {
|
|
2776
|
+
namespace: mod.namespace,
|
|
2777
|
+
logs
|
|
2778
|
+
};
|
|
2779
|
+
}
|
|
2780
|
+
/**
|
|
2781
|
+
* Execute database code and return results
|
|
2782
|
+
*/
|
|
2783
|
+
async execute(code, options) {
|
|
2784
|
+
return await this.vmRun(code, options);
|
|
2785
|
+
}
|
|
2786
|
+
};
|
|
2787
|
+
var database = serverDatabase.database;
|
|
2788
|
+
|
|
2660
2789
|
// src/server.ts
|
|
2790
|
+
var ServerDatabase = class {
|
|
2791
|
+
constructor() {
|
|
2792
|
+
this._db = null;
|
|
2793
|
+
}
|
|
2794
|
+
async initialize(config) {
|
|
2795
|
+
this._db = new Database(config);
|
|
2796
|
+
}
|
|
2797
|
+
database() {
|
|
2798
|
+
return this._db;
|
|
2799
|
+
}
|
|
2800
|
+
};
|
|
2801
|
+
var serverDatabase = new ServerDatabase();
|
|
2802
|
+
var database2 = serverDatabase.database;
|
|
2661
2803
|
var ServerRouter = class {
|
|
2662
2804
|
constructor() {
|
|
2663
2805
|
this.routes = [];
|
|
2664
2806
|
this.middlewares = [];
|
|
2665
2807
|
// Express-like .all() method - matches all HTTP methods
|
|
2666
|
-
this.all = (
|
|
2808
|
+
this.all = (path2, ...handlers) => this.addRoute("ALL", path2, handlers);
|
|
2667
2809
|
// Support per-route middleware: accept middleware(s) before the final handler
|
|
2668
|
-
this.get = (
|
|
2669
|
-
this.post = (
|
|
2670
|
-
this.put = (
|
|
2671
|
-
this.delete = (
|
|
2672
|
-
this.patch = (
|
|
2673
|
-
this.options = (
|
|
2674
|
-
this.head = (
|
|
2810
|
+
this.get = (path2, ...handlers) => this.addRoute("GET", path2, handlers);
|
|
2811
|
+
this.post = (path2, ...handlers) => this.addRoute("POST", path2, handlers);
|
|
2812
|
+
this.put = (path2, ...handlers) => this.addRoute("PUT", path2, handlers);
|
|
2813
|
+
this.delete = (path2, ...handlers) => this.addRoute("DELETE", path2, handlers);
|
|
2814
|
+
this.patch = (path2, ...handlers) => this.addRoute("PATCH", path2, handlers);
|
|
2815
|
+
this.options = (path2, ...handlers) => this.addRoute("OPTIONS", path2, handlers);
|
|
2816
|
+
this.head = (path2, ...handlers) => this.addRoute("HEAD", path2, handlers);
|
|
2675
2817
|
}
|
|
2676
2818
|
// Accept both internal Middleware and Express-style `(req, res, next?)` functions
|
|
2677
2819
|
// Also support path-based middleware like Express: use(path, middleware)
|
|
2678
2820
|
use(...args) {
|
|
2679
2821
|
if (typeof args[0] === "string") {
|
|
2680
|
-
const
|
|
2822
|
+
const path2 = args[0];
|
|
2681
2823
|
const middlewares = args.slice(1);
|
|
2682
|
-
return this.addRoute("ALL",
|
|
2824
|
+
return this.addRoute("ALL", path2, middlewares);
|
|
2683
2825
|
}
|
|
2684
2826
|
const mw = args[0];
|
|
2685
2827
|
this.middlewares.push(this.toMiddleware(mw));
|
|
@@ -2710,8 +2852,8 @@ var ServerRouter = class {
|
|
|
2710
2852
|
await next();
|
|
2711
2853
|
};
|
|
2712
2854
|
}
|
|
2713
|
-
addRoute(method,
|
|
2714
|
-
const { pattern, paramNames } = this.pathToRegex(
|
|
2855
|
+
addRoute(method, path2, handlers) {
|
|
2856
|
+
const { pattern, paramNames } = this.pathToRegex(path2);
|
|
2715
2857
|
if (!handlers || handlers.length === 0) throw new Error("Route must include a handler");
|
|
2716
2858
|
const rawMiddlewares = handlers.slice(0, handlers.length - 1);
|
|
2717
2859
|
const rawLast = handlers[handlers.length - 1];
|
|
@@ -2740,9 +2882,9 @@ var ServerRouter = class {
|
|
|
2740
2882
|
this.routes.push({ method, pattern, paramNames, handler: last, middlewares });
|
|
2741
2883
|
return this;
|
|
2742
2884
|
}
|
|
2743
|
-
pathToRegex(
|
|
2885
|
+
pathToRegex(path2) {
|
|
2744
2886
|
const paramNames = [];
|
|
2745
|
-
const pattern =
|
|
2887
|
+
const pattern = path2.replace(/[.*+?^${}()|[\]\\]/g, "\\$&").replace(/\//g, "\\/").replace(/:(\w+)/g, (_, name) => (paramNames.push(name), "([^\\/]+)"));
|
|
2746
2888
|
return { pattern: new RegExp(`^${pattern}$`), paramNames };
|
|
2747
2889
|
}
|
|
2748
2890
|
parseQuery(url) {
|
|
@@ -2800,11 +2942,11 @@ var ServerRouter = class {
|
|
|
2800
2942
|
});
|
|
2801
2943
|
}
|
|
2802
2944
|
async handle(req, res) {
|
|
2803
|
-
const method = req.method, url = req.url || "/",
|
|
2945
|
+
const method = req.method, url = req.url || "/", path2 = url.split("?")[0];
|
|
2804
2946
|
for (const route of this.routes) {
|
|
2805
2947
|
if (route.method !== "ALL" && route.method !== method) continue;
|
|
2806
|
-
if (!route.pattern.test(
|
|
2807
|
-
const match =
|
|
2948
|
+
if (!route.pattern.test(path2)) continue;
|
|
2949
|
+
const match = path2.match(route.pattern);
|
|
2808
2950
|
const params = Object.fromEntries(route.paramNames.map((name, i2) => [name, match[i2 + 1]]));
|
|
2809
2951
|
let body = {};
|
|
2810
2952
|
if (["POST", "PUT", "PATCH"].includes(method)) {
|
|
@@ -3262,21 +3404,21 @@ function security() {
|
|
|
3262
3404
|
await next();
|
|
3263
3405
|
};
|
|
3264
3406
|
}
|
|
3265
|
-
function rewritePath(
|
|
3266
|
-
if (!pathRewrite) return
|
|
3407
|
+
function rewritePath(path2, pathRewrite) {
|
|
3408
|
+
if (!pathRewrite) return path2;
|
|
3267
3409
|
for (const [from, to] of Object.entries(pathRewrite)) {
|
|
3268
3410
|
const regex = new RegExp(from);
|
|
3269
|
-
if (regex.test(
|
|
3270
|
-
return
|
|
3411
|
+
if (regex.test(path2)) {
|
|
3412
|
+
return path2.replace(regex, to);
|
|
3271
3413
|
}
|
|
3272
3414
|
}
|
|
3273
|
-
return
|
|
3415
|
+
return path2;
|
|
3274
3416
|
}
|
|
3275
3417
|
function createProxyHandler(proxyConfigs) {
|
|
3276
3418
|
return async (req, res) => {
|
|
3277
3419
|
const url = req.url || "/";
|
|
3278
|
-
const
|
|
3279
|
-
const proxy = proxyConfigs.find((p) =>
|
|
3420
|
+
const path2 = url.split("?")[0];
|
|
3421
|
+
const proxy = proxyConfigs.find((p) => path2.startsWith(p.context));
|
|
3280
3422
|
if (!proxy) return false;
|
|
3281
3423
|
const { target, changeOrigin, pathRewrite, headers } = proxy;
|
|
3282
3424
|
try {
|
|
@@ -3328,7 +3470,7 @@ function createProxyHandler(proxyConfigs) {
|
|
|
3328
3470
|
req.on("end", () => proxyReq.end());
|
|
3329
3471
|
return true;
|
|
3330
3472
|
} catch (error) {
|
|
3331
|
-
console.error("[Proxy] Invalid proxy configuration for %s:",
|
|
3473
|
+
console.error("[Proxy] Invalid proxy configuration for %s:", path2, error);
|
|
3332
3474
|
return false;
|
|
3333
3475
|
}
|
|
3334
3476
|
};
|
|
@@ -3449,6 +3591,9 @@ function createDevServer(options) {
|
|
|
3449
3591
|
if (config.mode === "dev") {
|
|
3450
3592
|
clearImportMapCache();
|
|
3451
3593
|
}
|
|
3594
|
+
if (config.database) {
|
|
3595
|
+
serverDatabase.initialize(config.database);
|
|
3596
|
+
}
|
|
3452
3597
|
const clientsToNormalize = config.clients?.length ? config.clients : config.root ? [{ root: config.root, basePath: config.basePath || "", index: config.index, ssr: config.ssr, api: config.api, proxy: config.proxy, mode: config.mode }] : null;
|
|
3453
3598
|
if (!clientsToNormalize) throw new Error('DevServerOptions must include either "clients" array or "root" directory');
|
|
3454
3599
|
const normalizedClients = clientsToNormalize.map((client) => {
|
|
@@ -3478,6 +3623,17 @@ function createDevServer(options) {
|
|
|
3478
3623
|
const globalProxyHandler = config.proxy ? createProxyHandler(config.proxy) : null;
|
|
3479
3624
|
const server = createServer(async (req, res) => {
|
|
3480
3625
|
const originalUrl = req.url || "/";
|
|
3626
|
+
const hostHeader = req.headers.host;
|
|
3627
|
+
const hostName = hostHeader ? (Array.isArray(hostHeader) ? hostHeader[0] : hostHeader).split(":")[0] : "";
|
|
3628
|
+
if (config.domain && hostName === (config.host || "localhost")) {
|
|
3629
|
+
const redirectUrl = `http://${config.domain}${originalUrl}`;
|
|
3630
|
+
if (config.logging) {
|
|
3631
|
+
console.log(`[Domain Map] ${hostName}:${config.port}${originalUrl} -> ${redirectUrl}`);
|
|
3632
|
+
}
|
|
3633
|
+
res.writeHead(302, { Location: redirectUrl });
|
|
3634
|
+
res.end();
|
|
3635
|
+
return;
|
|
3636
|
+
}
|
|
3481
3637
|
const matchedClient = normalizedClients.find((c) => c.basePath && originalUrl.startsWith(c.basePath)) || normalizedClients.find((c) => !c.basePath);
|
|
3482
3638
|
if (!matchedClient) return send404(res, "404 Not Found");
|
|
3483
3639
|
if (matchedClient.proxyHandler) {
|
|
@@ -3729,8 +3885,8 @@ export default css;
|
|
|
3729
3885
|
});
|
|
3730
3886
|
transpiled = transpiler.transformSync(content.toString());
|
|
3731
3887
|
} else {
|
|
3732
|
-
const { build } = await import("esbuild");
|
|
3733
|
-
const result = await
|
|
3888
|
+
const { build: build2 } = await import("esbuild");
|
|
3889
|
+
const result = await build2({
|
|
3734
3890
|
stdin: {
|
|
3735
3891
|
contents: content.toString(),
|
|
3736
3892
|
loader: ext === ".tsx" ? "tsx" : "ts",
|
|
@@ -3747,19 +3903,19 @@ export default css;
|
|
|
3747
3903
|
}
|
|
3748
3904
|
transpiled = transpiled.replace(
|
|
3749
3905
|
/from\s+["']([^"']+)\.ts(x?)["']/g,
|
|
3750
|
-
(_,
|
|
3906
|
+
(_, path2, tsx) => `from "${path2}.js${tsx}"`
|
|
3751
3907
|
);
|
|
3752
3908
|
transpiled = transpiled.replace(
|
|
3753
3909
|
/import\s+["']([^"']+)\.ts(x?)["']/g,
|
|
3754
|
-
(_,
|
|
3910
|
+
(_, path2, tsx) => `import "${path2}.js${tsx}"`
|
|
3755
3911
|
);
|
|
3756
3912
|
transpiled = transpiled.replace(
|
|
3757
3913
|
/import\s+["']([^"']+\.css)["']/g,
|
|
3758
|
-
(_,
|
|
3914
|
+
(_, path2) => `import "${path2}?inline"`
|
|
3759
3915
|
);
|
|
3760
3916
|
transpiled = transpiled.replace(
|
|
3761
3917
|
/from\s+["']([^"']+\.css)["']/g,
|
|
3762
|
-
(_,
|
|
3918
|
+
(_, path2) => `from "${path2}?inline"`
|
|
3763
3919
|
);
|
|
3764
3920
|
content = Buffer.from(transpiled);
|
|
3765
3921
|
mimeType = "application/javascript";
|
|
@@ -3921,17 +4077,17 @@ ${elitImportMap}` : elitImportMap;
|
|
|
3921
4077
|
(client) => config.watch.map((pattern) => join(client.root, pattern))
|
|
3922
4078
|
);
|
|
3923
4079
|
const watcher = watch(watchPaths, {
|
|
3924
|
-
ignored: (
|
|
4080
|
+
ignored: (path2) => config.ignore.some((pattern) => path2.includes(pattern.replace("/**", "").replace("**/", ""))),
|
|
3925
4081
|
ignoreInitial: true,
|
|
3926
4082
|
persistent: true
|
|
3927
4083
|
});
|
|
3928
|
-
watcher.on("change", (
|
|
3929
|
-
if (config.logging) console.log(`[HMR] File changed: ${
|
|
3930
|
-
const message = JSON.stringify({ type: "update", path, timestamp: Date.now() });
|
|
4084
|
+
watcher.on("change", (path2) => {
|
|
4085
|
+
if (config.logging) console.log(`[HMR] File changed: ${path2}`);
|
|
4086
|
+
const message = JSON.stringify({ type: "update", path: path2, timestamp: Date.now() });
|
|
3931
4087
|
wsClients.forEach((client) => client.readyState === 1 /* OPEN */ && client.send(message));
|
|
3932
4088
|
});
|
|
3933
|
-
watcher.on("add", (
|
|
3934
|
-
watcher.on("unlink", (
|
|
4089
|
+
watcher.on("add", (path2) => config.logging && console.log(`[HMR] File added: ${path2}`));
|
|
4090
|
+
watcher.on("unlink", (path2) => config.logging && console.log(`[HMR] File removed: ${path2}`));
|
|
3935
4091
|
server.setMaxListeners(20);
|
|
3936
4092
|
server.listen(config.port, config.host, () => {
|
|
3937
4093
|
if (config.logging) {
|
|
@@ -4004,12 +4160,14 @@ ${elitImportMap}` : elitImportMap;
|
|
|
4004
4160
|
cors,
|
|
4005
4161
|
createDevServer,
|
|
4006
4162
|
createProxyHandler,
|
|
4163
|
+
database,
|
|
4007
4164
|
errorHandler,
|
|
4008
4165
|
html,
|
|
4009
4166
|
json,
|
|
4010
4167
|
logger,
|
|
4011
4168
|
rateLimit,
|
|
4012
4169
|
security,
|
|
4170
|
+
serverDatabase,
|
|
4013
4171
|
status,
|
|
4014
4172
|
text
|
|
4015
4173
|
});
|