@dbcube/core 4.1.4 → 4.1.6
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 +180 -32
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +180 -32
- package/dist/bin.js.map +1 -1
- package/dist/index.cjs +218 -87
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +218 -87
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.mts
CHANGED
|
@@ -104,9 +104,11 @@ interface BinaryType {
|
|
|
104
104
|
declare class Binary {
|
|
105
105
|
private static isDownloading;
|
|
106
106
|
private static downloadPromise;
|
|
107
|
+
private static cachedBinaries;
|
|
107
108
|
static ensureBinariesExist(): Promise<void>;
|
|
108
109
|
private static downloadBinaries;
|
|
109
110
|
private static getBinDir;
|
|
111
|
+
private static findVersionedBinary;
|
|
110
112
|
static get(): Promise<BinaryType>;
|
|
111
113
|
}
|
|
112
114
|
|
package/dist/index.d.ts
CHANGED
|
@@ -104,9 +104,11 @@ interface BinaryType {
|
|
|
104
104
|
declare class Binary {
|
|
105
105
|
private static isDownloading;
|
|
106
106
|
private static downloadPromise;
|
|
107
|
+
private static cachedBinaries;
|
|
107
108
|
static ensureBinariesExist(): Promise<void>;
|
|
108
109
|
private static downloadBinaries;
|
|
109
110
|
private static getBinDir;
|
|
111
|
+
private static findVersionedBinary;
|
|
110
112
|
static get(): Promise<BinaryType>;
|
|
111
113
|
}
|
|
112
114
|
|
package/dist/index.js
CHANGED
|
@@ -137,6 +137,97 @@ var { https } = followRedirects;
|
|
|
137
137
|
var Downloader = class {
|
|
138
138
|
static mainSpinner = null;
|
|
139
139
|
static currentSpinner = null;
|
|
140
|
+
static VERSION_URLS = {
|
|
141
|
+
query: "https://raw.githubusercontent.com/Dbcube/binaries/main/query-engines.json",
|
|
142
|
+
schema: "https://raw.githubusercontent.com/Dbcube/binaries/main/schema-engines.json",
|
|
143
|
+
sqlite: "https://raw.githubusercontent.com/Dbcube/binaries/main/sqlite-engines.json"
|
|
144
|
+
};
|
|
145
|
+
/**
|
|
146
|
+
* Fetch latest version from GitHub
|
|
147
|
+
*/
|
|
148
|
+
static async fetchLatestVersion(prefix) {
|
|
149
|
+
const url = this.VERSION_URLS[prefix];
|
|
150
|
+
return new Promise((resolve5, reject) => {
|
|
151
|
+
https.get(url, (response) => {
|
|
152
|
+
let data = "";
|
|
153
|
+
response.on("data", (chunk) => {
|
|
154
|
+
data += chunk;
|
|
155
|
+
});
|
|
156
|
+
response.on("end", () => {
|
|
157
|
+
try {
|
|
158
|
+
const versions = JSON.parse(data);
|
|
159
|
+
if (versions && versions.length > 0) {
|
|
160
|
+
resolve5(versions[0].version);
|
|
161
|
+
} else {
|
|
162
|
+
reject(new Error("No versions found"));
|
|
163
|
+
}
|
|
164
|
+
} catch (error) {
|
|
165
|
+
reject(error);
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
response.on("error", reject);
|
|
169
|
+
}).on("error", reject);
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Extract version from binary filename
|
|
174
|
+
* Example: schema-engine-v1.0.0-windows-x64.exe -> v1.0.0
|
|
175
|
+
*/
|
|
176
|
+
static extractVersionFromFilename(filename) {
|
|
177
|
+
const match = filename.match(/-(v\d+\.\d+\.\d+)-/);
|
|
178
|
+
return match ? match[1] : null;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Get local version of installed binary
|
|
182
|
+
*/
|
|
183
|
+
static getLocalVersion(binDir, prefix) {
|
|
184
|
+
try {
|
|
185
|
+
const files = fs.readdirSync(binDir);
|
|
186
|
+
const binaryPattern = new RegExp(`^${prefix}-engine-v`);
|
|
187
|
+
const binaryFile = files.find((f) => binaryPattern.test(f));
|
|
188
|
+
if (binaryFile) {
|
|
189
|
+
return this.extractVersionFromFilename(binaryFile);
|
|
190
|
+
}
|
|
191
|
+
} catch (error) {
|
|
192
|
+
}
|
|
193
|
+
return null;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Compare versions (returns true if remote is newer)
|
|
197
|
+
*/
|
|
198
|
+
static isNewerVersion(localVersion, remoteVersion) {
|
|
199
|
+
if (!localVersion) return true;
|
|
200
|
+
const cleanLocal = localVersion.replace(/^v/, "");
|
|
201
|
+
const cleanRemote = remoteVersion.replace(/^v/, "");
|
|
202
|
+
const localParts = cleanLocal.split(".").map(Number);
|
|
203
|
+
const remoteParts = cleanRemote.split(".").map(Number);
|
|
204
|
+
for (let i = 0; i < 3; i++) {
|
|
205
|
+
if (remoteParts[i] > localParts[i]) return true;
|
|
206
|
+
if (remoteParts[i] < localParts[i]) return false;
|
|
207
|
+
}
|
|
208
|
+
return false;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Delete old binary files
|
|
212
|
+
*/
|
|
213
|
+
static deleteOldBinary(binDir, prefix) {
|
|
214
|
+
try {
|
|
215
|
+
const files = fs.readdirSync(binDir);
|
|
216
|
+
const binaryPattern = new RegExp(`^${prefix}-engine-`);
|
|
217
|
+
files.forEach((file) => {
|
|
218
|
+
if (binaryPattern.test(file)) {
|
|
219
|
+
const filePath = path.join(binDir, file);
|
|
220
|
+
try {
|
|
221
|
+
fs.unlinkSync(filePath);
|
|
222
|
+
console.log(`\u{1F5D1}\uFE0F Deleted old binary: ${file}`);
|
|
223
|
+
} catch (err) {
|
|
224
|
+
console.warn(`\u26A0\uFE0F Could not delete: ${file}`);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
} catch (error) {
|
|
229
|
+
}
|
|
230
|
+
}
|
|
140
231
|
static get(prefix) {
|
|
141
232
|
const arch2 = new Arquitecture();
|
|
142
233
|
const platform2 = arch2.getPlatform();
|
|
@@ -159,6 +250,7 @@ var Downloader = class {
|
|
|
159
250
|
return {
|
|
160
251
|
name: binaryName,
|
|
161
252
|
url,
|
|
253
|
+
version: "latest",
|
|
162
254
|
query_engine: binaryName,
|
|
163
255
|
schema_engine: `${prefix}-engine-${plat}-${archSuffix}${platform2 === "windows" ? ".exe" : ""}`
|
|
164
256
|
};
|
|
@@ -166,69 +258,125 @@ var Downloader = class {
|
|
|
166
258
|
return {
|
|
167
259
|
name: "",
|
|
168
260
|
url: "",
|
|
261
|
+
version: "",
|
|
262
|
+
query_engine: "",
|
|
263
|
+
schema_engine: ""
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Get binary info with actual version from GitHub
|
|
268
|
+
*/
|
|
269
|
+
static async getWithVersion(prefix) {
|
|
270
|
+
const arch2 = new Arquitecture();
|
|
271
|
+
const platform2 = arch2.getPlatform();
|
|
272
|
+
const architecture = arch2.getArchitecture();
|
|
273
|
+
const platformMap = {
|
|
274
|
+
windows: "windows",
|
|
275
|
+
linux: "linux",
|
|
276
|
+
darwin: "macos"
|
|
277
|
+
};
|
|
278
|
+
const archMap = {
|
|
279
|
+
x86_64: "x64",
|
|
280
|
+
aarch64: "arm64"
|
|
281
|
+
};
|
|
282
|
+
const plat = platformMap[platform2];
|
|
283
|
+
const archSuffix = archMap[architecture];
|
|
284
|
+
if (plat && archSuffix) {
|
|
285
|
+
const version = await this.fetchLatestVersion(prefix);
|
|
286
|
+
const baseName = `${prefix}-engine-${version}-${plat}-${archSuffix}`;
|
|
287
|
+
const binaryName = platform2 === "windows" ? `${baseName}.exe` : baseName;
|
|
288
|
+
const url = `https://github.com/Dbcube/binaries/releases/download/${prefix}-engine/${prefix}-engine-${version}-${plat}-${archSuffix}.zip`;
|
|
289
|
+
return {
|
|
290
|
+
name: binaryName,
|
|
291
|
+
url,
|
|
292
|
+
version,
|
|
293
|
+
query_engine: binaryName,
|
|
294
|
+
schema_engine: binaryName
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
return {
|
|
298
|
+
name: "",
|
|
299
|
+
url: "",
|
|
300
|
+
version: "",
|
|
169
301
|
query_engine: "",
|
|
170
302
|
schema_engine: ""
|
|
171
303
|
};
|
|
172
304
|
}
|
|
173
305
|
static async download(targetDir) {
|
|
174
|
-
const binaries = ["schema", "query", "sqlite"];
|
|
175
306
|
const binDir = targetDir || this.getDefaultBinDir();
|
|
176
307
|
fs.mkdirSync(binDir, { recursive: true });
|
|
177
308
|
this.mainSpinner = ora({
|
|
178
|
-
text: chalk.blue("
|
|
309
|
+
text: chalk.blue("Verificando versiones de binarios..."),
|
|
179
310
|
spinner: "dots12"
|
|
180
311
|
}).start();
|
|
181
|
-
const
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
312
|
+
const binariesToProcess = [];
|
|
313
|
+
for (const prefix of ["query", "schema", "sqlite"]) {
|
|
314
|
+
try {
|
|
315
|
+
const localVersion = this.getLocalVersion(binDir, prefix);
|
|
316
|
+
const remoteVersion = await this.fetchLatestVersion(prefix);
|
|
317
|
+
const needsUpdate = this.isNewerVersion(localVersion, remoteVersion);
|
|
318
|
+
binariesToProcess.push({
|
|
319
|
+
prefix,
|
|
320
|
+
needsUpdate,
|
|
321
|
+
localVersion,
|
|
322
|
+
remoteVersion
|
|
323
|
+
});
|
|
324
|
+
if (needsUpdate) {
|
|
325
|
+
console.log(`
|
|
326
|
+
\u{1F4E6} ${prefix}-engine: ${localVersion || "not installed"} \u2192 ${remoteVersion}`);
|
|
327
|
+
} else if (localVersion) {
|
|
328
|
+
console.log(`
|
|
329
|
+
\u2705 ${prefix}-engine: ${localVersion} (up to date)`);
|
|
330
|
+
}
|
|
331
|
+
} catch (error) {
|
|
332
|
+
console.warn(`\u26A0\uFE0F Could not check version for ${prefix}-engine, will attempt download`);
|
|
333
|
+
binariesToProcess.push({
|
|
334
|
+
prefix,
|
|
335
|
+
needsUpdate: true,
|
|
336
|
+
localVersion: null,
|
|
337
|
+
remoteVersion: "latest"
|
|
338
|
+
});
|
|
192
339
|
}
|
|
193
|
-
binariesToDownload.push({
|
|
194
|
-
prefix,
|
|
195
|
-
binaryInfo,
|
|
196
|
-
tempZipPath: path.join(os2.tmpdir(), `dbcube-${prefix}-${Date.now()}.zip`),
|
|
197
|
-
finalBinaryPath
|
|
198
|
-
});
|
|
199
340
|
}
|
|
341
|
+
const binariesToDownload = binariesToProcess.filter((b) => b.needsUpdate);
|
|
200
342
|
if (binariesToDownload.length === 0) {
|
|
201
|
-
this.mainSpinner.succeed(chalk.green("
|
|
343
|
+
this.mainSpinner.succeed(chalk.green("All binaries are up to date"));
|
|
202
344
|
return;
|
|
203
345
|
}
|
|
204
|
-
this.
|
|
346
|
+
this.mainSpinner.text = chalk.blue(`Updating ${binariesToDownload.length} binary(ies)...`);
|
|
205
347
|
try {
|
|
206
|
-
await Promise.all(binariesToDownload.map(async (binary
|
|
348
|
+
await Promise.all(binariesToDownload.map(async (binary) => {
|
|
207
349
|
const maxRetries = 3;
|
|
208
350
|
let attempt = 0;
|
|
209
351
|
while (attempt <= maxRetries) {
|
|
210
352
|
try {
|
|
211
|
-
await this.
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
353
|
+
const binaryInfo = await this.getWithVersion(binary.prefix);
|
|
354
|
+
if (!binaryInfo.name || !binaryInfo.url) {
|
|
355
|
+
throw new Error(`Platform or architecture not supported for ${binary.prefix}`);
|
|
356
|
+
}
|
|
357
|
+
const tempZipPath = path.join(os2.tmpdir(), `dbcube-${binary.prefix}-${Date.now()}.zip`);
|
|
358
|
+
const finalBinaryPath = path.join(binDir, binaryInfo.name);
|
|
359
|
+
this.deleteOldBinary(binDir, binary.prefix);
|
|
360
|
+
await this.downloadFileWithProgress(binaryInfo.url, tempZipPath, binary.prefix);
|
|
361
|
+
await this.extractBinary(tempZipPath, finalBinaryPath, binary.prefix);
|
|
362
|
+
console.log(`\u2705 ${binary.prefix}-engine updated to ${binary.remoteVersion}`);
|
|
215
363
|
break;
|
|
216
364
|
} catch (error) {
|
|
217
|
-
const errorMessage = error instanceof Error ? error.message : "
|
|
365
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
218
366
|
if (attempt < maxRetries && (errorMessage.includes("ECONNRESET") || errorMessage.includes("timeout") || errorMessage.includes("ETIMEDOUT") || errorMessage.includes("ENOTFOUND"))) {
|
|
219
367
|
attempt++;
|
|
220
|
-
|
|
368
|
+
console.log(`\u{1F504} Retrying ${binary.prefix}-engine (${attempt}/${maxRetries})...`);
|
|
221
369
|
await new Promise((resolve5) => setTimeout(resolve5, 1e3 + Math.random() * 1e3));
|
|
222
370
|
} else {
|
|
223
|
-
throw new Error(`Error
|
|
371
|
+
throw new Error(`Error downloading ${binary.prefix}: ${errorMessage}`);
|
|
224
372
|
}
|
|
225
373
|
}
|
|
226
374
|
}
|
|
227
375
|
}));
|
|
228
|
-
this.mainSpinner.succeed(chalk.green("
|
|
376
|
+
this.mainSpinner.succeed(chalk.green("Binaries updated successfully"));
|
|
229
377
|
} catch (error) {
|
|
230
|
-
const errorMessage = error instanceof Error ? error.message : "
|
|
231
|
-
this.mainSpinner.fail(chalk.red(`Error
|
|
378
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
379
|
+
this.mainSpinner.fail(chalk.red(`Error updating binaries: ${errorMessage}`));
|
|
232
380
|
throw error;
|
|
233
381
|
}
|
|
234
382
|
}
|
|
@@ -398,22 +546,13 @@ import { dirname as dirname2 } from "path";
|
|
|
398
546
|
var Binary = class {
|
|
399
547
|
static isDownloading = false;
|
|
400
548
|
static downloadPromise = null;
|
|
549
|
+
static cachedBinaries = {};
|
|
401
550
|
static async ensureBinariesExist() {
|
|
402
551
|
if (this.isDownloading && this.downloadPromise) {
|
|
403
552
|
await this.downloadPromise;
|
|
404
553
|
return;
|
|
405
554
|
}
|
|
406
555
|
const binDir = this.getBinDir();
|
|
407
|
-
const binaries = ["schema", "query", "sqlite"];
|
|
408
|
-
const allExist = binaries.every((prefix) => {
|
|
409
|
-
const binaryInfo = Downloader.get(prefix);
|
|
410
|
-
if (!binaryInfo.name) return false;
|
|
411
|
-
const binaryPath = path2.join(binDir, binaryInfo.name);
|
|
412
|
-
return fs2.existsSync(binaryPath);
|
|
413
|
-
});
|
|
414
|
-
if (allExist) {
|
|
415
|
-
return;
|
|
416
|
-
}
|
|
417
556
|
if (!this.isDownloading) {
|
|
418
557
|
this.isDownloading = true;
|
|
419
558
|
this.downloadPromise = this.downloadBinaries();
|
|
@@ -456,58 +595,50 @@ var Binary = class {
|
|
|
456
595
|
fs2.mkdirSync(tempDir, { recursive: true });
|
|
457
596
|
return tempDir;
|
|
458
597
|
}
|
|
598
|
+
static findVersionedBinary(binDir, prefix, platform2, arch2) {
|
|
599
|
+
const cacheKey = `${prefix}-${platform2}-${arch2}`;
|
|
600
|
+
if (this.cachedBinaries[cacheKey]) {
|
|
601
|
+
const cachedPath = path2.join(binDir, this.cachedBinaries[cacheKey]);
|
|
602
|
+
if (fs2.existsSync(cachedPath)) {
|
|
603
|
+
return cachedPath;
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
try {
|
|
607
|
+
const files = fs2.readdirSync(binDir);
|
|
608
|
+
const extension = platform2 === "windows" ? ".exe" : "";
|
|
609
|
+
const pattern = new RegExp(`^${prefix}-engine-v\\d+\\.\\d+\\.\\d+-${platform2}-${arch2}${extension.replace(".", "\\.")}$`);
|
|
610
|
+
const matchingFile = files.find((f) => pattern.test(f));
|
|
611
|
+
if (matchingFile) {
|
|
612
|
+
this.cachedBinaries[cacheKey] = matchingFile;
|
|
613
|
+
return path2.join(binDir, matchingFile);
|
|
614
|
+
}
|
|
615
|
+
} catch (error) {
|
|
616
|
+
}
|
|
617
|
+
const fallbackName = `${prefix}-engine-${platform2}-${arch2}${platform2 === "windows" ? ".exe" : ""}`;
|
|
618
|
+
return path2.join(binDir, fallbackName);
|
|
619
|
+
}
|
|
459
620
|
static async get() {
|
|
460
621
|
await this.ensureBinariesExist();
|
|
461
622
|
const arch2 = new Arquitecture();
|
|
462
623
|
const platform2 = arch2.getPlatform();
|
|
463
624
|
const architecture = arch2.getArchitecture();
|
|
464
625
|
const binDir = this.getBinDir();
|
|
465
|
-
const
|
|
466
|
-
|
|
626
|
+
const platformMap = {
|
|
627
|
+
windows: "windows",
|
|
628
|
+
linux: "linux",
|
|
629
|
+
darwin: "macos"
|
|
467
630
|
};
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
schema_engine: getFullPath("schema-engine-windows-arm64.exe")
|
|
480
|
-
};
|
|
481
|
-
}
|
|
482
|
-
break;
|
|
483
|
-
case "linux":
|
|
484
|
-
if (architecture == "x86_64") {
|
|
485
|
-
return {
|
|
486
|
-
query_engine: getFullPath("query-engine-linux-x64"),
|
|
487
|
-
schema_engine: getFullPath("schema-engine-linux-x64")
|
|
488
|
-
};
|
|
489
|
-
}
|
|
490
|
-
if (architecture == "aarch64") {
|
|
491
|
-
return {
|
|
492
|
-
query_engine: getFullPath("query-engine-linux-arm64"),
|
|
493
|
-
schema_engine: getFullPath("schema-engine-linux-arm64")
|
|
494
|
-
};
|
|
495
|
-
}
|
|
496
|
-
break;
|
|
497
|
-
case "macos":
|
|
498
|
-
if (architecture == "x86_64") {
|
|
499
|
-
return {
|
|
500
|
-
query_engine: getFullPath("query-engine-macos-x64"),
|
|
501
|
-
schema_engine: getFullPath("schema-engine-macos-x64")
|
|
502
|
-
};
|
|
503
|
-
}
|
|
504
|
-
if (architecture == "aarch64") {
|
|
505
|
-
return {
|
|
506
|
-
query_engine: getFullPath("query-engine-macos-arm64"),
|
|
507
|
-
schema_engine: getFullPath("schema-engine-macos-arm64")
|
|
508
|
-
};
|
|
509
|
-
}
|
|
510
|
-
break;
|
|
631
|
+
const archMap = {
|
|
632
|
+
x86_64: "x64",
|
|
633
|
+
aarch64: "arm64"
|
|
634
|
+
};
|
|
635
|
+
const plat = platformMap[platform2];
|
|
636
|
+
const archSuffix = archMap[architecture];
|
|
637
|
+
if (plat && archSuffix) {
|
|
638
|
+
return {
|
|
639
|
+
query_engine: this.findVersionedBinary(binDir, "query", plat, archSuffix),
|
|
640
|
+
schema_engine: this.findVersionedBinary(binDir, "schema", plat, archSuffix)
|
|
641
|
+
};
|
|
511
642
|
}
|
|
512
643
|
return {
|
|
513
644
|
query_engine: "",
|