@dbcube/core 5.2.3 → 5.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.cjs +2 -3
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +2 -3
- package/dist/bin.js.map +1 -1
- package/dist/index.cjs +150 -357
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +36 -33
- package/dist/index.d.ts +36 -33
- package/dist/index.js +166 -373
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6,7 +6,8 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
6
6
|
});
|
|
7
7
|
|
|
8
8
|
// src/lib/Engine.ts
|
|
9
|
-
import
|
|
9
|
+
import path5 from "path";
|
|
10
|
+
import * as fs5 from "fs";
|
|
10
11
|
|
|
11
12
|
// src/lib/Arquitecture.ts
|
|
12
13
|
import * as os from "os";
|
|
@@ -146,8 +147,7 @@ var Downloader = class {
|
|
|
146
147
|
static currentSpinner = null;
|
|
147
148
|
static VERSION_URLS = {
|
|
148
149
|
query: "https://raw.githubusercontent.com/Dbcube/binaries/main/query-engines.json",
|
|
149
|
-
schema: "https://raw.githubusercontent.com/Dbcube/binaries/main/schema-engines.json"
|
|
150
|
-
sqlite: "https://raw.githubusercontent.com/Dbcube/binaries/main/sqlite-engines.json"
|
|
150
|
+
schema: "https://raw.githubusercontent.com/Dbcube/binaries/main/schema-engines.json"
|
|
151
151
|
};
|
|
152
152
|
/**
|
|
153
153
|
* Fetch latest version from GitHub
|
|
@@ -317,7 +317,7 @@ var Downloader = class {
|
|
|
317
317
|
spinner: "dots12"
|
|
318
318
|
}).start();
|
|
319
319
|
const binariesToProcess = [];
|
|
320
|
-
for (const prefix of ["query", "schema"
|
|
320
|
+
for (const prefix of ["query", "schema"]) {
|
|
321
321
|
try {
|
|
322
322
|
const localVersion = this.getLocalVersion(binDir, prefix);
|
|
323
323
|
const remoteVersion = await this.fetchLatestVersion(prefix);
|
|
@@ -706,14 +706,75 @@ var Config = class {
|
|
|
706
706
|
}
|
|
707
707
|
};
|
|
708
708
|
|
|
709
|
+
// src/lib/EnvLoader.ts
|
|
710
|
+
import * as fs3 from "fs";
|
|
711
|
+
import * as path3 from "path";
|
|
712
|
+
var EnvLoader = class _EnvLoader {
|
|
713
|
+
/**
|
|
714
|
+
* Carga el archivo .env indicado (o ./.env del cwd) en process.env.
|
|
715
|
+
* Silencioso si el archivo no existe. Devuelve true si cargó algo.
|
|
716
|
+
*/
|
|
717
|
+
static load(envPath) {
|
|
718
|
+
const file = envPath || path3.resolve(process.cwd(), ".env");
|
|
719
|
+
if (!fs3.existsSync(file)) return false;
|
|
720
|
+
const proc = process;
|
|
721
|
+
if (typeof proc.loadEnvFile === "function") {
|
|
722
|
+
try {
|
|
723
|
+
proc.loadEnvFile(file);
|
|
724
|
+
return true;
|
|
725
|
+
} catch {
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
try {
|
|
729
|
+
const parsed = _EnvLoader.parse(fs3.readFileSync(file, "utf8"));
|
|
730
|
+
for (const [key, value] of Object.entries(parsed)) {
|
|
731
|
+
if (process.env[key] === void 0) {
|
|
732
|
+
process.env[key] = value;
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
return true;
|
|
736
|
+
} catch {
|
|
737
|
+
return false;
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
/**
|
|
741
|
+
* Parser mínimo de formato .env. Soporta:
|
|
742
|
+
* KEY=value · KEY="value con espacios" · KEY='literal' · export KEY=value
|
|
743
|
+
* comentarios con # · líneas en blanco · \n \t en comillas dobles.
|
|
744
|
+
*/
|
|
745
|
+
static parse(content) {
|
|
746
|
+
const out = {};
|
|
747
|
+
for (const rawLine of content.split(/\r?\n/)) {
|
|
748
|
+
const line = rawLine.trim();
|
|
749
|
+
if (!line || line.startsWith("#")) continue;
|
|
750
|
+
const withoutExport = line.startsWith("export ") ? line.slice(7).trim() : line;
|
|
751
|
+
const eq = withoutExport.indexOf("=");
|
|
752
|
+
if (eq === -1) continue;
|
|
753
|
+
const key = withoutExport.slice(0, eq).trim();
|
|
754
|
+
if (!key) continue;
|
|
755
|
+
let value = withoutExport.slice(eq + 1).trim();
|
|
756
|
+
if (value.length >= 2 && value[0] === '"' && value[value.length - 1] === '"') {
|
|
757
|
+
value = value.slice(1, -1).replace(/\\n/g, "\n").replace(/\\t/g, " ").replace(/\\"/g, '"');
|
|
758
|
+
} else if (value.length >= 2 && value[0] === "'" && value[value.length - 1] === "'") {
|
|
759
|
+
value = value.slice(1, -1);
|
|
760
|
+
} else {
|
|
761
|
+
const hash = value.indexOf(" #");
|
|
762
|
+
if (hash !== -1) value = value.slice(0, hash).trim();
|
|
763
|
+
}
|
|
764
|
+
out[key] = value;
|
|
765
|
+
}
|
|
766
|
+
return out;
|
|
767
|
+
}
|
|
768
|
+
};
|
|
769
|
+
|
|
709
770
|
// src/lib/Engine.ts
|
|
710
771
|
import { spawn as spawn2 } from "child_process";
|
|
711
772
|
import { createRequire } from "module";
|
|
712
773
|
|
|
713
774
|
// src/lib/DaemonClient.ts
|
|
714
775
|
import net from "net";
|
|
715
|
-
import
|
|
716
|
-
import
|
|
776
|
+
import fs4 from "fs";
|
|
777
|
+
import path4 from "path";
|
|
717
778
|
import { spawn } from "child_process";
|
|
718
779
|
var DaemonClient = class _DaemonClient {
|
|
719
780
|
static registry = /* @__PURE__ */ new Map();
|
|
@@ -745,10 +806,10 @@ var DaemonClient = class _DaemonClient {
|
|
|
745
806
|
return true;
|
|
746
807
|
}
|
|
747
808
|
portfilePath() {
|
|
748
|
-
return
|
|
809
|
+
return path4.join(process.cwd(), ".dbcube", "daemon", `${this.name}.json`);
|
|
749
810
|
}
|
|
750
811
|
lockfilePath() {
|
|
751
|
-
return
|
|
812
|
+
return path4.join(process.cwd(), ".dbcube", "daemon", `${this.name}.lock`);
|
|
752
813
|
}
|
|
753
814
|
/**
|
|
754
815
|
* Exclusive-create lock so two processes never spawn two daemons for the
|
|
@@ -757,16 +818,16 @@ var DaemonClient = class _DaemonClient {
|
|
|
757
818
|
acquireSpawnLock() {
|
|
758
819
|
const lockPath = this.lockfilePath();
|
|
759
820
|
try {
|
|
760
|
-
|
|
761
|
-
const fd =
|
|
762
|
-
|
|
763
|
-
|
|
821
|
+
fs4.mkdirSync(path4.dirname(lockPath), { recursive: true });
|
|
822
|
+
const fd = fs4.openSync(lockPath, "wx");
|
|
823
|
+
fs4.writeSync(fd, String(process.pid));
|
|
824
|
+
fs4.closeSync(fd);
|
|
764
825
|
return true;
|
|
765
826
|
} catch {
|
|
766
827
|
try {
|
|
767
|
-
const age = Date.now() -
|
|
828
|
+
const age = Date.now() - fs4.statSync(lockPath).mtimeMs;
|
|
768
829
|
if (age > 15e3) {
|
|
769
|
-
|
|
830
|
+
fs4.unlinkSync(lockPath);
|
|
770
831
|
return this.acquireSpawnLock();
|
|
771
832
|
}
|
|
772
833
|
} catch {
|
|
@@ -776,7 +837,7 @@ var DaemonClient = class _DaemonClient {
|
|
|
776
837
|
}
|
|
777
838
|
releaseSpawnLock() {
|
|
778
839
|
try {
|
|
779
|
-
|
|
840
|
+
fs4.unlinkSync(this.lockfilePath());
|
|
780
841
|
} catch {
|
|
781
842
|
}
|
|
782
843
|
}
|
|
@@ -800,7 +861,7 @@ var DaemonClient = class _DaemonClient {
|
|
|
800
861
|
try {
|
|
801
862
|
if (gotLock) {
|
|
802
863
|
try {
|
|
803
|
-
|
|
864
|
+
fs4.unlinkSync(this.portfilePath());
|
|
804
865
|
} catch {
|
|
805
866
|
}
|
|
806
867
|
this.spawnDaemon();
|
|
@@ -818,7 +879,7 @@ var DaemonClient = class _DaemonClient {
|
|
|
818
879
|
}
|
|
819
880
|
readPortfile() {
|
|
820
881
|
try {
|
|
821
|
-
const raw =
|
|
882
|
+
const raw = fs4.readFileSync(this.portfilePath(), "utf8");
|
|
822
883
|
const info = JSON.parse(raw);
|
|
823
884
|
const port = info?.port;
|
|
824
885
|
return Number.isInteger(port) && port > 0 && port <= 65535 ? port : null;
|
|
@@ -945,7 +1006,7 @@ var DaemonClient = class _DaemonClient {
|
|
|
945
1006
|
}
|
|
946
1007
|
this.detach();
|
|
947
1008
|
try {
|
|
948
|
-
|
|
1009
|
+
fs4.unlinkSync(this.portfilePath());
|
|
949
1010
|
} catch {
|
|
950
1011
|
}
|
|
951
1012
|
}
|
|
@@ -1043,6 +1104,7 @@ var Engine = class {
|
|
|
1043
1104
|
}
|
|
1044
1105
|
setArguments() {
|
|
1045
1106
|
let args = [];
|
|
1107
|
+
const motor = this.config.type === "postgres" ? "postgresql" : this.config.type;
|
|
1046
1108
|
if (this.config.type == "sqlite") {
|
|
1047
1109
|
args = [
|
|
1048
1110
|
"--id",
|
|
@@ -1052,7 +1114,7 @@ var Engine = class {
|
|
|
1052
1114
|
"--database",
|
|
1053
1115
|
this.config.config.DATABASE + ".db",
|
|
1054
1116
|
"--motor",
|
|
1055
|
-
|
|
1117
|
+
motor
|
|
1056
1118
|
];
|
|
1057
1119
|
} else {
|
|
1058
1120
|
args = [
|
|
@@ -1067,7 +1129,7 @@ var Engine = class {
|
|
|
1067
1129
|
"--port",
|
|
1068
1130
|
String(this.config.config.PORT),
|
|
1069
1131
|
"--motor",
|
|
1070
|
-
|
|
1132
|
+
motor
|
|
1071
1133
|
];
|
|
1072
1134
|
if (this.config.config.USER != null && this.config.config.USER !== "") {
|
|
1073
1135
|
args.push("--user", this.config.config.USER);
|
|
@@ -1080,8 +1142,10 @@ var Engine = class {
|
|
|
1080
1142
|
}
|
|
1081
1143
|
setConfig(name) {
|
|
1082
1144
|
const configInstance = new Config();
|
|
1145
|
+
EnvLoader.load();
|
|
1083
1146
|
try {
|
|
1084
|
-
const
|
|
1147
|
+
const cjsPath = path5.resolve(process.cwd(), "dbcube.config.cjs");
|
|
1148
|
+
const configFilePath = fs5.existsSync(cjsPath) ? cjsPath : path5.resolve(process.cwd(), "dbcube.config.js");
|
|
1085
1149
|
const requireUrl = typeof __filename !== "undefined" ? __filename : process.cwd();
|
|
1086
1150
|
const require2 = createRequire(requireUrl);
|
|
1087
1151
|
if (require2.cache && require2.resolve) {
|
|
@@ -1194,11 +1258,12 @@ var Engine = class {
|
|
|
1194
1258
|
};
|
|
1195
1259
|
|
|
1196
1260
|
// src/lib/QueryEngine.ts
|
|
1197
|
-
import
|
|
1261
|
+
import path7 from "path";
|
|
1262
|
+
import * as fs7 from "fs";
|
|
1198
1263
|
|
|
1199
1264
|
// src/lib/EmbeddedEngine.ts
|
|
1200
|
-
import * as
|
|
1201
|
-
import * as
|
|
1265
|
+
import * as fs6 from "fs";
|
|
1266
|
+
import * as path6 from "path";
|
|
1202
1267
|
if (!process.env.UV_THREADPOOL_SIZE) {
|
|
1203
1268
|
process.env.UV_THREADPOOL_SIZE = "16";
|
|
1204
1269
|
}
|
|
@@ -1214,11 +1279,11 @@ function platTag() {
|
|
|
1214
1279
|
}
|
|
1215
1280
|
function findFile(name) {
|
|
1216
1281
|
const candidates = [
|
|
1217
|
-
|
|
1218
|
-
|
|
1282
|
+
path6.resolve(process.cwd(), ".dbcube", "bin", name),
|
|
1283
|
+
path6.resolve(process.cwd(), "node_modules", ".dbcube", "bin", name)
|
|
1219
1284
|
];
|
|
1220
1285
|
for (const c of candidates) {
|
|
1221
|
-
if (
|
|
1286
|
+
if (fs6.existsSync(c)) return c;
|
|
1222
1287
|
}
|
|
1223
1288
|
return null;
|
|
1224
1289
|
}
|
|
@@ -1463,9 +1528,9 @@ var QueryEngine = class {
|
|
|
1463
1528
|
timeout;
|
|
1464
1529
|
connectionId;
|
|
1465
1530
|
tcpPort;
|
|
1466
|
-
constructor(name, timeout = 3e4) {
|
|
1531
|
+
constructor(name, timeout = 3e4, explicitConfig) {
|
|
1467
1532
|
this.name = name;
|
|
1468
|
-
this.config = this.setConfig(name);
|
|
1533
|
+
this.config = explicitConfig ?? this.setConfig(name);
|
|
1469
1534
|
this.arguments = this.setArguments();
|
|
1470
1535
|
this.timeout = this.config?.daemon?.requestTimeoutMs ?? timeout;
|
|
1471
1536
|
this.connectionId = `${name}_query_engine_${this.config.type}_${this.config.config.DATABASE}_${this.config.config.HOST || "localhost"}`;
|
|
@@ -1500,6 +1565,7 @@ var QueryEngine = class {
|
|
|
1500
1565
|
}
|
|
1501
1566
|
setArguments() {
|
|
1502
1567
|
let args = [];
|
|
1568
|
+
const motor = this.config.type === "postgres" ? "postgresql" : this.config.type;
|
|
1503
1569
|
if (this.config.type == "sqlite") {
|
|
1504
1570
|
args = [
|
|
1505
1571
|
"--id",
|
|
@@ -1509,7 +1575,7 @@ var QueryEngine = class {
|
|
|
1509
1575
|
"--database",
|
|
1510
1576
|
this.config.config.DATABASE + ".db",
|
|
1511
1577
|
"--motor",
|
|
1512
|
-
|
|
1578
|
+
motor
|
|
1513
1579
|
];
|
|
1514
1580
|
} else {
|
|
1515
1581
|
args = [
|
|
@@ -1524,7 +1590,7 @@ var QueryEngine = class {
|
|
|
1524
1590
|
"--port",
|
|
1525
1591
|
String(this.config.config.PORT),
|
|
1526
1592
|
"--motor",
|
|
1527
|
-
|
|
1593
|
+
motor
|
|
1528
1594
|
];
|
|
1529
1595
|
if (this.config.config.USER != null && this.config.config.USER !== "") {
|
|
1530
1596
|
args.push("--user", this.config.config.USER);
|
|
@@ -1548,8 +1614,10 @@ var QueryEngine = class {
|
|
|
1548
1614
|
}
|
|
1549
1615
|
setConfig(name) {
|
|
1550
1616
|
const configInstance = new Config();
|
|
1617
|
+
EnvLoader.load();
|
|
1551
1618
|
try {
|
|
1552
|
-
const
|
|
1619
|
+
const cjsPath = path7.resolve(process.cwd(), "dbcube.config.cjs");
|
|
1620
|
+
const configFilePath = fs7.existsSync(cjsPath) ? cjsPath : path7.resolve(process.cwd(), "dbcube.config.js");
|
|
1553
1621
|
const requireUrl = typeof __filename !== "undefined" ? __filename : process.cwd();
|
|
1554
1622
|
const require2 = createRequire2(requireUrl);
|
|
1555
1623
|
if (require2.cache && require2.resolve) {
|
|
@@ -2012,346 +2080,70 @@ var QueryEngine = class {
|
|
|
2012
2080
|
}
|
|
2013
2081
|
};
|
|
2014
2082
|
|
|
2015
|
-
// src/lib/SqliteExecutor.ts
|
|
2016
|
-
import { exec } from "child_process";
|
|
2017
|
-
import * as path7 from "path";
|
|
2018
|
-
import * as fs5 from "fs";
|
|
2019
|
-
import { promisify } from "util";
|
|
2020
|
-
import { createRequire as createRequire3 } from "module";
|
|
2021
|
-
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
2022
|
-
import { dirname as dirname4 } from "path";
|
|
2023
|
-
var execAsync = promisify(exec);
|
|
2024
|
-
var SqliteExecutor = class {
|
|
2025
|
-
binaryPath;
|
|
2026
|
-
dbPath;
|
|
2027
|
-
constructor(dbPath) {
|
|
2028
|
-
this.dbPath = dbPath;
|
|
2029
|
-
this.binaryPath = this.getBinaryPath();
|
|
2030
|
-
}
|
|
2031
|
-
findVersionedBinary(binDir, platform2) {
|
|
2032
|
-
try {
|
|
2033
|
-
const files = fs5.readdirSync(binDir);
|
|
2034
|
-
const extension = platform2 === "win32" ? ".exe" : "";
|
|
2035
|
-
const platformName = platform2 === "win32" ? "windows" : platform2 === "darwin" ? "macos" : "linux";
|
|
2036
|
-
const pattern = new RegExp(`^sqlite-engine-v\\d+\\.\\d+\\.\\d+-${platformName}-x64${extension.replace(".", "\\.")}$`);
|
|
2037
|
-
const matchingFile = files.find((f) => pattern.test(f));
|
|
2038
|
-
if (matchingFile) {
|
|
2039
|
-
return path7.join(binDir, matchingFile);
|
|
2040
|
-
}
|
|
2041
|
-
} catch (error) {
|
|
2042
|
-
}
|
|
2043
|
-
return null;
|
|
2044
|
-
}
|
|
2045
|
-
getBinaryPath() {
|
|
2046
|
-
const __filename2 = typeof import.meta !== "undefined" && import.meta.url ? fileURLToPath3(import.meta.url) : "";
|
|
2047
|
-
const __dirname = __filename2 ? dirname4(__filename2) : process.cwd();
|
|
2048
|
-
const possibleDirs = [
|
|
2049
|
-
path7.resolve(process.cwd(), ".dbcube", "bin"),
|
|
2050
|
-
path7.resolve(process.cwd(), "node_modules", ".dbcube", "bin"),
|
|
2051
|
-
path7.resolve(__dirname, "..", "bin")
|
|
2052
|
-
];
|
|
2053
|
-
const platform2 = process.platform;
|
|
2054
|
-
const extension = platform2 === "win32" ? ".exe" : "";
|
|
2055
|
-
const platformName = platform2 === "win32" ? "windows" : platform2 === "darwin" ? "macos" : "linux";
|
|
2056
|
-
for (const dir of possibleDirs) {
|
|
2057
|
-
const versionedPath = this.findVersionedBinary(dir, platform2);
|
|
2058
|
-
if (versionedPath && fs5.existsSync(versionedPath)) {
|
|
2059
|
-
return versionedPath;
|
|
2060
|
-
}
|
|
2061
|
-
}
|
|
2062
|
-
const binaryName = `sqlite-engine-${platformName}-x64${extension}`;
|
|
2063
|
-
for (const dir of possibleDirs) {
|
|
2064
|
-
const fullPath = path7.join(dir, binaryName);
|
|
2065
|
-
if (fs5.existsSync(fullPath)) {
|
|
2066
|
-
return fullPath;
|
|
2067
|
-
}
|
|
2068
|
-
}
|
|
2069
|
-
const fallbackName = `sqlite-engine${extension}`;
|
|
2070
|
-
for (const dir of possibleDirs) {
|
|
2071
|
-
const fullPath = path7.join(dir, fallbackName);
|
|
2072
|
-
if (fs5.existsSync(fullPath)) {
|
|
2073
|
-
return fullPath;
|
|
2074
|
-
}
|
|
2075
|
-
}
|
|
2076
|
-
return path7.join(possibleDirs[0], binaryName);
|
|
2077
|
-
}
|
|
2078
|
-
async executeBinary(args) {
|
|
2079
|
-
const escapedArgs = args.map((arg) => {
|
|
2080
|
-
if (arg.includes(" ") || arg.includes('"') || arg.includes("(") || arg.includes(")")) {
|
|
2081
|
-
return `"${arg.replace(/"/g, '\\"')}"`;
|
|
2082
|
-
}
|
|
2083
|
-
return arg;
|
|
2084
|
-
});
|
|
2085
|
-
const command = `"${this.binaryPath}" ${escapedArgs.join(" ")}`;
|
|
2086
|
-
try {
|
|
2087
|
-
const { stdout, stderr } = await execAsync(command, {
|
|
2088
|
-
maxBuffer: 10 * 1024 * 1024,
|
|
2089
|
-
// 10MB buffer
|
|
2090
|
-
timeout: 3e4
|
|
2091
|
-
// 30s timeout
|
|
2092
|
-
});
|
|
2093
|
-
if (stderr && stderr.trim()) {
|
|
2094
|
-
console.warn("SQLite Engine Warning:", stderr);
|
|
2095
|
-
}
|
|
2096
|
-
const result = JSON.parse(stdout.trim());
|
|
2097
|
-
return result;
|
|
2098
|
-
} catch (error) {
|
|
2099
|
-
if (error.stdout) {
|
|
2100
|
-
try {
|
|
2101
|
-
const result = JSON.parse(error.stdout.trim());
|
|
2102
|
-
return result;
|
|
2103
|
-
} catch (parseError) {
|
|
2104
|
-
}
|
|
2105
|
-
}
|
|
2106
|
-
throw new Error(`SQLite execution failed: ${error.message}`);
|
|
2107
|
-
}
|
|
2108
|
-
}
|
|
2109
|
-
async connect() {
|
|
2110
|
-
try {
|
|
2111
|
-
const result = await this.executeBinary([
|
|
2112
|
-
"--action",
|
|
2113
|
-
"connect",
|
|
2114
|
-
"--database",
|
|
2115
|
-
this.dbPath
|
|
2116
|
-
]);
|
|
2117
|
-
return result.status === "success";
|
|
2118
|
-
} catch (error) {
|
|
2119
|
-
return false;
|
|
2120
|
-
}
|
|
2121
|
-
}
|
|
2122
|
-
async exists() {
|
|
2123
|
-
try {
|
|
2124
|
-
const result = await this.executeBinary([
|
|
2125
|
-
"--action",
|
|
2126
|
-
"exists",
|
|
2127
|
-
"--database",
|
|
2128
|
-
this.dbPath
|
|
2129
|
-
]);
|
|
2130
|
-
return result.status === "success" && result.data === true;
|
|
2131
|
-
} catch (error) {
|
|
2132
|
-
return false;
|
|
2133
|
-
}
|
|
2134
|
-
}
|
|
2135
|
-
async query(sql, params) {
|
|
2136
|
-
const args = [
|
|
2137
|
-
"--action",
|
|
2138
|
-
"query",
|
|
2139
|
-
"--database",
|
|
2140
|
-
this.dbPath,
|
|
2141
|
-
"--query",
|
|
2142
|
-
sql
|
|
2143
|
-
];
|
|
2144
|
-
if (params && params.length > 0) {
|
|
2145
|
-
args.push("--params", JSON.stringify(params));
|
|
2146
|
-
}
|
|
2147
|
-
return this.executeBinary(args);
|
|
2148
|
-
}
|
|
2149
|
-
// Método para múltiples queries (como lo hace better-sqlite3)
|
|
2150
|
-
async queryMultiple(sql) {
|
|
2151
|
-
return this.query(sql);
|
|
2152
|
-
}
|
|
2153
|
-
// Método prepare que simula prepared statements
|
|
2154
|
-
prepare(sql) {
|
|
2155
|
-
return {
|
|
2156
|
-
all: async (...params) => {
|
|
2157
|
-
const result = await this.query(sql, params);
|
|
2158
|
-
if (result.status === "error") {
|
|
2159
|
-
throw new Error(result.message);
|
|
2160
|
-
}
|
|
2161
|
-
return Array.isArray(result.data) ? result.data : [];
|
|
2162
|
-
},
|
|
2163
|
-
run: async (...params) => {
|
|
2164
|
-
const result = await this.query(sql, params);
|
|
2165
|
-
if (result.status === "error") {
|
|
2166
|
-
throw new Error(result.message);
|
|
2167
|
-
}
|
|
2168
|
-
if (typeof result.data === "object" && result.data.hasOwnProperty("changes") && result.data.hasOwnProperty("lastID")) {
|
|
2169
|
-
return result.data;
|
|
2170
|
-
}
|
|
2171
|
-
return { changes: 0, lastID: 0 };
|
|
2172
|
-
}
|
|
2173
|
-
};
|
|
2174
|
-
}
|
|
2175
|
-
// Para compatibilidad con better-sqlite3 API sincrona usando deasync si es necesario
|
|
2176
|
-
prepareSync(sql) {
|
|
2177
|
-
const __filename2 = typeof import.meta !== "undefined" && import.meta.url ? fileURLToPath3(import.meta.url) : "";
|
|
2178
|
-
const requireUrl = __filename2 || import.meta.url;
|
|
2179
|
-
const require2 = createRequire3(requireUrl);
|
|
2180
|
-
const deasync = require2("deasync");
|
|
2181
|
-
return {
|
|
2182
|
-
all: (...params) => {
|
|
2183
|
-
let result;
|
|
2184
|
-
let done = false;
|
|
2185
|
-
let error;
|
|
2186
|
-
this.query(sql, params).then((res) => {
|
|
2187
|
-
if (res.status === "error") {
|
|
2188
|
-
error = new Error(res.message);
|
|
2189
|
-
} else {
|
|
2190
|
-
result = Array.isArray(res.data) ? res.data : [];
|
|
2191
|
-
}
|
|
2192
|
-
done = true;
|
|
2193
|
-
}).catch((err) => {
|
|
2194
|
-
error = err;
|
|
2195
|
-
done = true;
|
|
2196
|
-
});
|
|
2197
|
-
deasync.loopWhile(() => !done);
|
|
2198
|
-
if (error) throw error;
|
|
2199
|
-
return result;
|
|
2200
|
-
},
|
|
2201
|
-
run: (...params) => {
|
|
2202
|
-
let result;
|
|
2203
|
-
let done = false;
|
|
2204
|
-
let error;
|
|
2205
|
-
this.query(sql, params).then((res) => {
|
|
2206
|
-
if (res.status === "error") {
|
|
2207
|
-
error = new Error(res.message);
|
|
2208
|
-
} else if (typeof res.data === "object" && res.data.hasOwnProperty("changes") && res.data.hasOwnProperty("lastID")) {
|
|
2209
|
-
result = res.data;
|
|
2210
|
-
} else {
|
|
2211
|
-
result = { changes: 0, lastID: 0 };
|
|
2212
|
-
}
|
|
2213
|
-
done = true;
|
|
2214
|
-
}).catch((err) => {
|
|
2215
|
-
error = err;
|
|
2216
|
-
done = true;
|
|
2217
|
-
});
|
|
2218
|
-
deasync.loopWhile(() => !done);
|
|
2219
|
-
if (error) throw error;
|
|
2220
|
-
return result;
|
|
2221
|
-
}
|
|
2222
|
-
};
|
|
2223
|
-
}
|
|
2224
|
-
};
|
|
2225
|
-
|
|
2226
2083
|
// src/lib/DbConfig.ts
|
|
2227
2084
|
import * as path8 from "path";
|
|
2228
|
-
import
|
|
2085
|
+
import fs8 from "fs";
|
|
2229
2086
|
var rootPath = path8.resolve(process.cwd(), ".dbcube");
|
|
2230
2087
|
var SQLite = class {
|
|
2231
|
-
executor = null;
|
|
2232
2088
|
database;
|
|
2089
|
+
engine = null;
|
|
2233
2090
|
constructor(config) {
|
|
2234
|
-
this.database = config.DATABASE;
|
|
2091
|
+
this.database = config.DATABASE || "config";
|
|
2092
|
+
}
|
|
2093
|
+
/** Ruta del archivo SQLite interno (.dbcube/<database>.db). */
|
|
2094
|
+
dbFilePath() {
|
|
2095
|
+
return path8.join(rootPath, this.database + ".db");
|
|
2096
|
+
}
|
|
2097
|
+
/** QueryEngine sqlite apuntando al archivo interno, con config explícito
|
|
2098
|
+
* (no vive en dbcube.config.js). La ruta relativa `.dbcube/<db>` deja que
|
|
2099
|
+
* QueryEngine le añada `.db` → `.dbcube/<db>.db`, relativo al CWD. */
|
|
2100
|
+
getEngine() {
|
|
2101
|
+
if (!this.engine) {
|
|
2102
|
+
const relativeDb = path8.join(".dbcube", this.database).replace(/\\/g, "/");
|
|
2103
|
+
this.engine = new QueryEngine(`dbcube-internal-${this.database}`, 3e4, {
|
|
2104
|
+
type: "sqlite",
|
|
2105
|
+
config: { DATABASE: relativeDb }
|
|
2106
|
+
});
|
|
2107
|
+
}
|
|
2108
|
+
return this.engine;
|
|
2235
2109
|
}
|
|
2236
2110
|
async ifExist() {
|
|
2237
|
-
if (
|
|
2238
|
-
|
|
2239
|
-
const configPath = path8.join(rootPath, dbPath + ".db");
|
|
2240
|
-
if (!fs6.existsSync(rootPath)) {
|
|
2241
|
-
fs6.mkdirSync(rootPath, { recursive: true });
|
|
2242
|
-
}
|
|
2243
|
-
if (fs6.existsSync(configPath)) {
|
|
2244
|
-
return true;
|
|
2245
|
-
}
|
|
2246
|
-
if (!this.executor) {
|
|
2247
|
-
this.executor = new SqliteExecutor(configPath);
|
|
2248
|
-
}
|
|
2249
|
-
return await this.executor.exists();
|
|
2111
|
+
if (!fs8.existsSync(rootPath)) {
|
|
2112
|
+
fs8.mkdirSync(rootPath, { recursive: true });
|
|
2250
2113
|
}
|
|
2251
|
-
return
|
|
2114
|
+
return fs8.existsSync(this.dbFilePath());
|
|
2252
2115
|
}
|
|
2253
2116
|
async connect() {
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
const configPath = path8.join(rootPath, dbPath + ".db");
|
|
2259
|
-
if (!fs6.existsSync(rootPath)) {
|
|
2260
|
-
fs6.mkdirSync(rootPath, { recursive: true });
|
|
2261
|
-
}
|
|
2262
|
-
this.executor = new SqliteExecutor(configPath);
|
|
2263
|
-
const connected = await this.executor.connect();
|
|
2264
|
-
if (!connected) {
|
|
2265
|
-
throw new Error("Failed to connect to SQLite database");
|
|
2266
|
-
}
|
|
2267
|
-
}
|
|
2268
|
-
resolve6(this.executor);
|
|
2269
|
-
} catch (error) {
|
|
2270
|
-
reject(error);
|
|
2271
|
-
}
|
|
2272
|
-
});
|
|
2117
|
+
if (!fs8.existsSync(rootPath)) {
|
|
2118
|
+
fs8.mkdirSync(rootPath, { recursive: true });
|
|
2119
|
+
}
|
|
2120
|
+
return this.getEngine();
|
|
2273
2121
|
}
|
|
2274
2122
|
async disconnect() {
|
|
2275
|
-
return new Promise((resolve6) => {
|
|
2276
|
-
if (this.executor) {
|
|
2277
|
-
this.executor = null;
|
|
2278
|
-
}
|
|
2279
|
-
resolve6();
|
|
2280
|
-
});
|
|
2281
2123
|
}
|
|
2282
2124
|
async query(sqlQuery) {
|
|
2283
|
-
return
|
|
2284
|
-
try {
|
|
2285
|
-
if (typeof sqlQuery !== "string") {
|
|
2286
|
-
throw new Error("The SQL query must be a string.");
|
|
2287
|
-
}
|
|
2288
|
-
if (!this.executor) {
|
|
2289
|
-
await this.connect();
|
|
2290
|
-
}
|
|
2291
|
-
if (!this.executor) {
|
|
2292
|
-
throw new Error("Database connection is not available.");
|
|
2293
|
-
}
|
|
2294
|
-
const result = await this.executor.queryMultiple(sqlQuery);
|
|
2295
|
-
if (result.status === "error") {
|
|
2296
|
-
resolve6({
|
|
2297
|
-
status: "error",
|
|
2298
|
-
message: result.message,
|
|
2299
|
-
data: null
|
|
2300
|
-
});
|
|
2301
|
-
} else {
|
|
2302
|
-
resolve6({
|
|
2303
|
-
status: "success",
|
|
2304
|
-
message: "Query executed successfully",
|
|
2305
|
-
data: result.data
|
|
2306
|
-
});
|
|
2307
|
-
}
|
|
2308
|
-
} catch (error) {
|
|
2309
|
-
resolve6({
|
|
2310
|
-
status: "error",
|
|
2311
|
-
message: error.message || "An error occurred while executing the query.",
|
|
2312
|
-
data: null
|
|
2313
|
-
});
|
|
2314
|
-
}
|
|
2315
|
-
});
|
|
2125
|
+
return this.queryWithParameters(sqlQuery, []);
|
|
2316
2126
|
}
|
|
2317
2127
|
async queryWithParameters(sqlQuery, params = []) {
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
throw new Error("The SQL query must be a string.");
|
|
2322
|
-
}
|
|
2323
|
-
if (!Array.isArray(params)) {
|
|
2324
|
-
throw new Error("Parameters must be an array.");
|
|
2325
|
-
}
|
|
2326
|
-
if (!this.executor) {
|
|
2327
|
-
await this.connect();
|
|
2328
|
-
}
|
|
2329
|
-
if (!this.executor) {
|
|
2330
|
-
throw new Error("Database connection is not available.");
|
|
2331
|
-
}
|
|
2332
|
-
const result = await this.executor.query(sqlQuery, params);
|
|
2333
|
-
if (result.status === "error") {
|
|
2334
|
-
resolve6({
|
|
2335
|
-
status: "error",
|
|
2336
|
-
message: result.message,
|
|
2337
|
-
data: null
|
|
2338
|
-
});
|
|
2339
|
-
} else {
|
|
2340
|
-
resolve6({
|
|
2341
|
-
status: "success",
|
|
2342
|
-
message: "Query executed successfully",
|
|
2343
|
-
data: result.data
|
|
2344
|
-
});
|
|
2345
|
-
}
|
|
2346
|
-
} catch (error) {
|
|
2347
|
-
console.log(error);
|
|
2348
|
-
resolve6({
|
|
2349
|
-
status: "error",
|
|
2350
|
-
message: error.message || "An error occurred while executing the query.",
|
|
2351
|
-
data: null
|
|
2352
|
-
});
|
|
2128
|
+
try {
|
|
2129
|
+
if (typeof sqlQuery !== "string") {
|
|
2130
|
+
throw new Error("The SQL query must be a string.");
|
|
2353
2131
|
}
|
|
2354
|
-
|
|
2132
|
+
if (!Array.isArray(params)) {
|
|
2133
|
+
throw new Error("Parameters must be an array.");
|
|
2134
|
+
}
|
|
2135
|
+
const response = await this.getEngine().rawQuery(sqlQuery, params);
|
|
2136
|
+
if (response.status !== 200) {
|
|
2137
|
+
return { status: "error", message: response.message || "Query failed", data: null };
|
|
2138
|
+
}
|
|
2139
|
+
return { status: "success", message: "Query executed successfully", data: response.data };
|
|
2140
|
+
} catch (error) {
|
|
2141
|
+
return {
|
|
2142
|
+
status: "error",
|
|
2143
|
+
message: error.message || "An error occurred while executing the query.",
|
|
2144
|
+
data: null
|
|
2145
|
+
};
|
|
2146
|
+
}
|
|
2355
2147
|
}
|
|
2356
2148
|
convertToParameterizedQuery(sql) {
|
|
2357
2149
|
const normalizedSql = sql.replace(/\s+/g, " ").trim();
|
|
@@ -2439,7 +2231,7 @@ var DbConfig = new SQLite({ DATABASE: "config" });
|
|
|
2439
2231
|
var DbConfig_default = DbConfig;
|
|
2440
2232
|
|
|
2441
2233
|
// src/lib/FileLogger.ts
|
|
2442
|
-
import * as
|
|
2234
|
+
import * as fs9 from "fs";
|
|
2443
2235
|
import * as path9 from "path";
|
|
2444
2236
|
import { EventEmitter } from "events";
|
|
2445
2237
|
var FileLogger = class _FileLogger extends EventEmitter {
|
|
@@ -2456,8 +2248,8 @@ var FileLogger = class _FileLogger extends EventEmitter {
|
|
|
2456
2248
|
static async write(filePath, message, level = "INFO", append = true) {
|
|
2457
2249
|
try {
|
|
2458
2250
|
const dir = path9.dirname(filePath);
|
|
2459
|
-
if (!
|
|
2460
|
-
|
|
2251
|
+
if (!fs9.existsSync(dir)) {
|
|
2252
|
+
fs9.mkdirSync(dir, { recursive: true });
|
|
2461
2253
|
}
|
|
2462
2254
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
2463
2255
|
const formattedMessage = `[${timestamp}] [${level}] ${message}
|
|
@@ -2467,9 +2259,9 @@ var FileLogger = class _FileLogger extends EventEmitter {
|
|
|
2467
2259
|
return true;
|
|
2468
2260
|
}
|
|
2469
2261
|
if (append) {
|
|
2470
|
-
await
|
|
2262
|
+
await fs9.promises.appendFile(filePath, formattedMessage, "utf8");
|
|
2471
2263
|
} else {
|
|
2472
|
-
await
|
|
2264
|
+
await fs9.promises.writeFile(filePath, formattedMessage, "utf8");
|
|
2473
2265
|
}
|
|
2474
2266
|
return true;
|
|
2475
2267
|
} catch (error) {
|
|
@@ -2495,11 +2287,11 @@ var FileLogger = class _FileLogger extends EventEmitter {
|
|
|
2495
2287
|
if (buffer && buffer.length > 0) {
|
|
2496
2288
|
try {
|
|
2497
2289
|
const dir = path9.dirname(filePath);
|
|
2498
|
-
if (!
|
|
2499
|
-
|
|
2290
|
+
if (!fs9.existsSync(dir)) {
|
|
2291
|
+
fs9.mkdirSync(dir, { recursive: true });
|
|
2500
2292
|
}
|
|
2501
2293
|
const content = buffer.join("");
|
|
2502
|
-
await
|
|
2294
|
+
await fs9.promises.appendFile(filePath, content, "utf8");
|
|
2503
2295
|
_FileLogger.buffers.delete(filePath);
|
|
2504
2296
|
return true;
|
|
2505
2297
|
} catch (error) {
|
|
@@ -2635,10 +2427,10 @@ var FileLogger = class _FileLogger extends EventEmitter {
|
|
|
2635
2427
|
// Si debe retornar como array de líneas
|
|
2636
2428
|
} = options;
|
|
2637
2429
|
try {
|
|
2638
|
-
if (!
|
|
2430
|
+
if (!fs9.existsSync(filePath)) {
|
|
2639
2431
|
return asArray ? [] : "";
|
|
2640
2432
|
}
|
|
2641
|
-
let content = await
|
|
2433
|
+
let content = await fs9.promises.readFile(filePath, "utf8");
|
|
2642
2434
|
if (asArray) {
|
|
2643
2435
|
let linesArray = content.split("\n").filter((line) => line.trim() !== "");
|
|
2644
2436
|
if (lines !== null) {
|
|
@@ -2681,15 +2473,15 @@ var FileLogger = class _FileLogger extends EventEmitter {
|
|
|
2681
2473
|
} = options;
|
|
2682
2474
|
let lastSize = 0;
|
|
2683
2475
|
let lastPosition = 0;
|
|
2684
|
-
if (
|
|
2685
|
-
const stats =
|
|
2476
|
+
if (fs9.existsSync(filePath)) {
|
|
2477
|
+
const stats = fs9.statSync(filePath);
|
|
2686
2478
|
lastSize = stats.size;
|
|
2687
2479
|
lastPosition = fromEnd ? stats.size : 0;
|
|
2688
2480
|
}
|
|
2689
2481
|
const listener = async (curr, prev) => {
|
|
2690
2482
|
try {
|
|
2691
2483
|
if (curr.size > lastSize) {
|
|
2692
|
-
const stream =
|
|
2484
|
+
const stream = fs9.createReadStream(filePath, {
|
|
2693
2485
|
start: lastPosition,
|
|
2694
2486
|
end: curr.size - 1,
|
|
2695
2487
|
encoding: "utf8"
|
|
@@ -2717,7 +2509,7 @@ var FileLogger = class _FileLogger extends EventEmitter {
|
|
|
2717
2509
|
console.error("Error en watcher:", error);
|
|
2718
2510
|
}
|
|
2719
2511
|
};
|
|
2720
|
-
|
|
2512
|
+
fs9.watchFile(filePath, { persistent, interval }, listener);
|
|
2721
2513
|
const watcherId = `${filePath}_${Date.now()}`;
|
|
2722
2514
|
_FileLogger.watchers.set(watcherId, listener);
|
|
2723
2515
|
return {
|
|
@@ -2725,7 +2517,7 @@ var FileLogger = class _FileLogger extends EventEmitter {
|
|
|
2725
2517
|
stop: () => {
|
|
2726
2518
|
const storedListener = _FileLogger.watchers.get(watcherId);
|
|
2727
2519
|
if (storedListener) {
|
|
2728
|
-
|
|
2520
|
+
fs9.unwatchFile(filePath, storedListener);
|
|
2729
2521
|
_FileLogger.watchers.delete(watcherId);
|
|
2730
2522
|
}
|
|
2731
2523
|
},
|
|
@@ -2738,7 +2530,7 @@ var FileLogger = class _FileLogger extends EventEmitter {
|
|
|
2738
2530
|
static stopAllWatchers() {
|
|
2739
2531
|
for (const [watcherId] of _FileLogger.watchers) {
|
|
2740
2532
|
const filePath = watcherId.split("_")[0];
|
|
2741
|
-
|
|
2533
|
+
fs9.unwatchFile(filePath);
|
|
2742
2534
|
}
|
|
2743
2535
|
_FileLogger.watchers.clear();
|
|
2744
2536
|
}
|
|
@@ -2768,7 +2560,7 @@ var FileLogger = class _FileLogger extends EventEmitter {
|
|
|
2768
2560
|
if (lines.length > maxLines) {
|
|
2769
2561
|
const keepLines = lines.slice(-maxLines);
|
|
2770
2562
|
const content = keepLines.join("\n") + "\n";
|
|
2771
|
-
await
|
|
2563
|
+
await fs9.promises.writeFile(filePath, content, "utf8");
|
|
2772
2564
|
return lines.length - maxLines;
|
|
2773
2565
|
}
|
|
2774
2566
|
return 0;
|
|
@@ -2783,8 +2575,8 @@ var FileLogger = class _FileLogger extends EventEmitter {
|
|
|
2783
2575
|
*/
|
|
2784
2576
|
static async deleteLogFile(filePath) {
|
|
2785
2577
|
try {
|
|
2786
|
-
if (
|
|
2787
|
-
await
|
|
2578
|
+
if (fs9.existsSync(filePath)) {
|
|
2579
|
+
await fs9.promises.unlink(filePath);
|
|
2788
2580
|
return true;
|
|
2789
2581
|
}
|
|
2790
2582
|
return false;
|
|
@@ -3199,6 +2991,7 @@ export {
|
|
|
3199
2991
|
DaemonClient,
|
|
3200
2992
|
DbConfig,
|
|
3201
2993
|
Engine,
|
|
2994
|
+
EnvLoader,
|
|
3202
2995
|
FileLogger,
|
|
3203
2996
|
QueryEngine,
|
|
3204
2997
|
TableProcessor,
|