@dbcube/schema-builder 1.0.15 → 1.0.17
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/index.cjs +397 -78
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +71 -3
- package/dist/index.d.ts +71 -3
- package/dist/index.js +394 -77
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -30,15 +30,17 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
|
+
CubeValidator: () => CubeValidator,
|
|
33
34
|
Schema: () => Schema,
|
|
35
|
+
UIUtils: () => UIUtils,
|
|
34
36
|
default: () => index_default
|
|
35
37
|
});
|
|
36
38
|
module.exports = __toCommonJS(index_exports);
|
|
37
39
|
|
|
38
40
|
// src/lib/Schema.ts
|
|
39
|
-
var
|
|
41
|
+
var import_fs3 = __toESM(require("fs"));
|
|
40
42
|
var import_core = require("@dbcube/core");
|
|
41
|
-
var
|
|
43
|
+
var import_path2 = __toESM(require("path"));
|
|
42
44
|
|
|
43
45
|
// src/lib/FileUtils.ts
|
|
44
46
|
var fs = __toESM(require("fs"));
|
|
@@ -162,9 +164,13 @@ var FileUtils = class {
|
|
|
162
164
|
};
|
|
163
165
|
var FileUtils_default = FileUtils;
|
|
164
166
|
|
|
167
|
+
// src/lib/Schema.ts
|
|
168
|
+
var import_chalk2 = __toESM(require("chalk"));
|
|
169
|
+
|
|
165
170
|
// src/lib/UIUtils.ts
|
|
166
171
|
var import_chalk = __toESM(require("chalk"));
|
|
167
|
-
var
|
|
172
|
+
var import_fs = __toESM(require("fs"));
|
|
173
|
+
var UIUtils = class _UIUtils {
|
|
168
174
|
/**
|
|
169
175
|
* Shows animated progress for processing items
|
|
170
176
|
*/
|
|
@@ -243,20 +249,349 @@ ${import_chalk.default.cyan("\u{1F4CA}")} ${import_chalk.default.bold.green(`SUM
|
|
|
243
249
|
${import_chalk.default.red("\u{1F6AB}")} ${import_chalk.default.bold.red("ERRORS FOUND")}`);
|
|
244
250
|
console.log(import_chalk.default.red("\u2500".repeat(60)));
|
|
245
251
|
summary.errors.forEach((error, index) => {
|
|
246
|
-
console.log(`${import_chalk.default.red("
|
|
247
|
-
console.log(
|
|
252
|
+
console.log(`${import_chalk.default.red("[error]")} ${import_chalk.default.red(error.error)}`);
|
|
253
|
+
console.log("");
|
|
248
254
|
if (error.filePath) {
|
|
249
|
-
const
|
|
250
|
-
|
|
251
|
-
|
|
255
|
+
const location = error.lineNumber ? `${error.filePath}:${error.lineNumber}:7` : error.filePath;
|
|
256
|
+
console.log(`${import_chalk.default.cyan("[code]")} ${import_chalk.default.yellow(location)}`);
|
|
257
|
+
_UIUtils.showCodeContext(error.filePath, error.lineNumber || 1);
|
|
252
258
|
}
|
|
253
259
|
if (index < summary.errors.length - 1) {
|
|
254
|
-
console.log(
|
|
260
|
+
console.log("");
|
|
261
|
+
}
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Shows code context around an error location
|
|
267
|
+
*/
|
|
268
|
+
static showCodeContext(filePath, lineNumber, contextLines = 2) {
|
|
269
|
+
try {
|
|
270
|
+
const content = import_fs.default.readFileSync(filePath, "utf8");
|
|
271
|
+
const lines = content.split("\n");
|
|
272
|
+
const startLine = Math.max(0, lineNumber - contextLines - 1);
|
|
273
|
+
const endLine = Math.min(lines.length, lineNumber + contextLines);
|
|
274
|
+
for (let i = startLine; i < endLine; i++) {
|
|
275
|
+
const currentLineNum = i + 1;
|
|
276
|
+
const line = lines[i];
|
|
277
|
+
const lineNumStr = currentLineNum.toString().padStart(4, " ");
|
|
278
|
+
if (currentLineNum === lineNumber) {
|
|
279
|
+
console.log(`${import_chalk.default.gray(lineNumStr)} ${import_chalk.default.red("<-")} ${import_chalk.default.white(line)}`);
|
|
280
|
+
} else {
|
|
281
|
+
console.log(`${import_chalk.default.gray(lineNumStr)} ${import_chalk.default.white(line)}`);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
} catch (error) {
|
|
285
|
+
console.log(import_chalk.default.gray(" (unable to show code context)"));
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
};
|
|
289
|
+
|
|
290
|
+
// src/lib/CubeValidator.ts
|
|
291
|
+
var import_fs2 = __toESM(require("fs"));
|
|
292
|
+
var import_path = __toESM(require("path"));
|
|
293
|
+
var CubeValidator = class {
|
|
294
|
+
validTypes = ["varchar", "int", "string", "text", "boolean", "date", "datetime", "timestamp", "decimal", "float", "double", "enum", "json"];
|
|
295
|
+
validOptions = ["not null", "primary", "autoincrement", "unique", "zerofill", "index", "required", "unsigned"];
|
|
296
|
+
validProperties = ["type", "length", "options", "value", "defaultValue", "foreign", "enumValues", "description"];
|
|
297
|
+
knownAnnotations = ["database", "table", "meta", "columns", "fields", "dataset", "beforeAdd", "afterAdd", "beforeUpdate", "afterUpdate", "beforeDelete", "afterDelete", "compute", "column"];
|
|
298
|
+
/**
|
|
299
|
+
* Validates a cube file comprehensively
|
|
300
|
+
*/
|
|
301
|
+
validateCubeFile(filePath) {
|
|
302
|
+
const errors = [];
|
|
303
|
+
try {
|
|
304
|
+
const content = import_fs2.default.readFileSync(filePath, "utf8");
|
|
305
|
+
const lines = content.split("\n");
|
|
306
|
+
const fileName = import_path.default.basename(filePath, import_path.default.extname(filePath));
|
|
307
|
+
for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {
|
|
308
|
+
const line = lines[lineIndex];
|
|
309
|
+
if (line.trim() === "" || line.trim().startsWith("//")) {
|
|
310
|
+
continue;
|
|
311
|
+
}
|
|
312
|
+
this.validateAnnotations(line, lineIndex + 1, filePath, fileName, errors);
|
|
313
|
+
this.validateDataTypes(line, lineIndex + 1, filePath, fileName, errors, content);
|
|
314
|
+
this.validateColumnOptions(line, lineIndex + 1, filePath, fileName, errors, lines);
|
|
315
|
+
this.validateColumnProperties(line, lineIndex + 1, filePath, fileName, errors, content);
|
|
316
|
+
this.validateRequiredColumnProperties(lines, lineIndex + 1, filePath, fileName, errors);
|
|
317
|
+
this.validateGeneralSyntax(line, lineIndex + 1, filePath, fileName, errors);
|
|
318
|
+
}
|
|
319
|
+
this.validateOverallStructure(content, filePath, fileName, errors);
|
|
320
|
+
} catch (error) {
|
|
321
|
+
errors.push({
|
|
322
|
+
itemName: import_path.default.basename(filePath, import_path.default.extname(filePath)),
|
|
323
|
+
error: `Failed to read cube file: ${error.message}`,
|
|
324
|
+
filePath,
|
|
325
|
+
lineNumber: 1
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
return {
|
|
329
|
+
isValid: errors.length === 0,
|
|
330
|
+
errors
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
validateAnnotations(line, lineNumber, filePath, fileName, errors) {
|
|
334
|
+
const annotationRegex = /@(\w+)/g;
|
|
335
|
+
let match;
|
|
336
|
+
while ((match = annotationRegex.exec(line)) !== null) {
|
|
337
|
+
const annotation = match[1];
|
|
338
|
+
if (!this.knownAnnotations.includes(annotation)) {
|
|
339
|
+
errors.push({
|
|
340
|
+
itemName: fileName,
|
|
341
|
+
error: `Unknown annotation '@${annotation}'. Valid annotations: ${this.knownAnnotations.join(", ")}`,
|
|
342
|
+
filePath,
|
|
343
|
+
lineNumber
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
validateDataTypes(line, lineNumber, filePath, fileName, errors, content) {
|
|
349
|
+
const typeRegex = /type:\s*["'](\w+)["']/g;
|
|
350
|
+
let match;
|
|
351
|
+
while ((match = typeRegex.exec(line)) !== null) {
|
|
352
|
+
const type = match[1];
|
|
353
|
+
if (!this.validTypes.includes(type)) {
|
|
354
|
+
errors.push({
|
|
355
|
+
itemName: fileName,
|
|
356
|
+
error: `Invalid data type '${type}'. Valid types: ${this.validTypes.join(", ")}`,
|
|
357
|
+
filePath,
|
|
358
|
+
lineNumber
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
if (line.includes('type: "varchar"')) {
|
|
363
|
+
const lines = content.split("\n");
|
|
364
|
+
const hasLengthNearby = lines.slice(Math.max(0, lineNumber - 1), Math.min(lineNumber + 4, lines.length)).some((nextLine) => nextLine.includes("length:"));
|
|
365
|
+
if (!hasLengthNearby) {
|
|
366
|
+
errors.push({
|
|
367
|
+
itemName: fileName,
|
|
368
|
+
error: "VARCHAR type requires a length specification",
|
|
369
|
+
filePath,
|
|
370
|
+
lineNumber
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
validateColumnOptions(line, lineNumber, filePath, fileName, errors, lines) {
|
|
376
|
+
const optionsMatch = line.match(/^\s*options\s*:\s*\[(.*)\]\s*;?\s*$/);
|
|
377
|
+
if (!optionsMatch) return;
|
|
378
|
+
const optionsContent = optionsMatch[1].trim();
|
|
379
|
+
const invalidSyntaxMatch = optionsContent.match(/[^",\s]+(?![^"]*")/);
|
|
380
|
+
if (invalidSyntaxMatch) {
|
|
381
|
+
errors.push({
|
|
382
|
+
itemName: fileName,
|
|
383
|
+
error: `Invalid syntax '${invalidSyntaxMatch[0]}' in options array. All values must be quoted strings`,
|
|
384
|
+
filePath,
|
|
385
|
+
lineNumber
|
|
386
|
+
});
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
389
|
+
const optionMatches = optionsContent.match(/"([^"]*)"/g);
|
|
390
|
+
if (optionMatches) {
|
|
391
|
+
const columnType = this.getColumnTypeForOptions(lines, lineNumber - 1);
|
|
392
|
+
optionMatches.forEach((optionMatch) => {
|
|
393
|
+
const option = optionMatch.replace(/"/g, "");
|
|
394
|
+
if (option.trim() === "") {
|
|
395
|
+
errors.push({
|
|
396
|
+
itemName: fileName,
|
|
397
|
+
error: "Empty option found in options array. All options must have a value",
|
|
398
|
+
filePath,
|
|
399
|
+
lineNumber
|
|
400
|
+
});
|
|
401
|
+
} else if (!this.validOptions.includes(option)) {
|
|
402
|
+
errors.push({
|
|
403
|
+
itemName: fileName,
|
|
404
|
+
error: `Invalid option '${option}'. Valid options: ${this.validOptions.join(", ")}`,
|
|
405
|
+
filePath,
|
|
406
|
+
lineNumber
|
|
407
|
+
});
|
|
408
|
+
} else if (!this.isOptionCompatibleWithType(option, columnType)) {
|
|
409
|
+
errors.push({
|
|
410
|
+
itemName: fileName,
|
|
411
|
+
error: `Option '${option}' is not compatible with type '${columnType}'`,
|
|
412
|
+
filePath,
|
|
413
|
+
lineNumber
|
|
414
|
+
});
|
|
255
415
|
}
|
|
256
416
|
});
|
|
257
|
-
console.log("");
|
|
258
417
|
}
|
|
259
418
|
}
|
|
419
|
+
validateColumnProperties(line, lineNumber, filePath, fileName, errors, content) {
|
|
420
|
+
const propertyKeyRegex = /^\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*:/;
|
|
421
|
+
const propMatch = propertyKeyRegex.exec(line);
|
|
422
|
+
if (!propMatch) return;
|
|
423
|
+
const propertyName = propMatch[1];
|
|
424
|
+
if (/^\s*[a-zA-Z_][a-zA-Z0-9_]*\s*:\s*\{/.test(line)) {
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
if (this.isInsideColumnsBlock(content, lineNumber - 1)) {
|
|
428
|
+
if (!this.validProperties.includes(propertyName)) {
|
|
429
|
+
errors.push({
|
|
430
|
+
itemName: fileName,
|
|
431
|
+
error: `Invalid property '${propertyName}'. Valid properties: ${this.validProperties.join(", ")}`,
|
|
432
|
+
filePath,
|
|
433
|
+
lineNumber
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
if (/^\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*:\s*$/.test(line)) {
|
|
438
|
+
errors.push({
|
|
439
|
+
itemName: fileName,
|
|
440
|
+
error: `Property '${propertyName}' is missing a value`,
|
|
441
|
+
filePath,
|
|
442
|
+
lineNumber
|
|
443
|
+
});
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
validateRequiredColumnProperties(lines, lineNumber, filePath, fileName, errors) {
|
|
447
|
+
const line = lines[lineNumber - 1];
|
|
448
|
+
if (!/^\s*\}\s*;?\s*$/.test(line)) {
|
|
449
|
+
return;
|
|
450
|
+
}
|
|
451
|
+
let columnStartLine = -1;
|
|
452
|
+
let columnName = "";
|
|
453
|
+
for (let i = lineNumber - 2; i >= 0; i--) {
|
|
454
|
+
const currentLine = lines[i];
|
|
455
|
+
const columnDefMatch = currentLine.match(/^\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*:\s*\{/);
|
|
456
|
+
if (columnDefMatch) {
|
|
457
|
+
let openBraces = 0;
|
|
458
|
+
let closeBraces = 0;
|
|
459
|
+
for (let j = i; j < lineNumber; j++) {
|
|
460
|
+
openBraces += (lines[j].match(/\{/g) || []).length;
|
|
461
|
+
closeBraces += (lines[j].match(/\}/g) || []).length;
|
|
462
|
+
}
|
|
463
|
+
if (openBraces === closeBraces) {
|
|
464
|
+
columnStartLine = i;
|
|
465
|
+
columnName = columnDefMatch[1];
|
|
466
|
+
break;
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
if (columnStartLine === -1 || !columnName) return;
|
|
471
|
+
let hasType = false;
|
|
472
|
+
for (let i = columnStartLine + 1; i < lineNumber - 1; i++) {
|
|
473
|
+
if (lines[i].match(/^\s*type\s*:/)) {
|
|
474
|
+
hasType = true;
|
|
475
|
+
break;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
if (!hasType && columnName !== "foreign" && columnName !== "defaultValue") {
|
|
479
|
+
errors.push({
|
|
480
|
+
itemName: fileName,
|
|
481
|
+
error: `Column '${columnName}' is missing required 'type' property`,
|
|
482
|
+
filePath,
|
|
483
|
+
lineNumber: columnStartLine + 1
|
|
484
|
+
});
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
validateGeneralSyntax(line, lineNumber, filePath, fileName, errors) {
|
|
488
|
+
const quotes = line.match(/["']/g);
|
|
489
|
+
if (quotes && quotes.length % 2 !== 0) {
|
|
490
|
+
errors.push({
|
|
491
|
+
itemName: fileName,
|
|
492
|
+
error: "Mismatched quotes detected",
|
|
493
|
+
filePath,
|
|
494
|
+
lineNumber
|
|
495
|
+
});
|
|
496
|
+
}
|
|
497
|
+
if (line.includes("@database") || line.includes("@table")) {
|
|
498
|
+
const stringAnnotationRegex = /@(database|table)\s*\(\s*"([^"]*)"\s*\)/;
|
|
499
|
+
if (!stringAnnotationRegex.test(line)) {
|
|
500
|
+
errors.push({
|
|
501
|
+
itemName: fileName,
|
|
502
|
+
error: 'Invalid annotation syntax. Expected format: @annotation("value")',
|
|
503
|
+
filePath,
|
|
504
|
+
lineNumber
|
|
505
|
+
});
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
if (line.includes("@meta")) {
|
|
509
|
+
const metaObjectRegex = /@meta\s*\(\s*\{/;
|
|
510
|
+
if (!metaObjectRegex.test(line)) {
|
|
511
|
+
errors.push({
|
|
512
|
+
itemName: fileName,
|
|
513
|
+
error: "Invalid @meta syntax. Expected format: @meta({ ... })",
|
|
514
|
+
filePath,
|
|
515
|
+
lineNumber
|
|
516
|
+
});
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
validateOverallStructure(content, filePath, fileName, errors) {
|
|
521
|
+
const lines = content.split("\n");
|
|
522
|
+
const hasDatabase = lines.some((line) => line.includes("@database"));
|
|
523
|
+
if (!hasDatabase) {
|
|
524
|
+
errors.push({
|
|
525
|
+
itemName: fileName,
|
|
526
|
+
error: "Missing required @database annotation",
|
|
527
|
+
filePath,
|
|
528
|
+
lineNumber: 1
|
|
529
|
+
});
|
|
530
|
+
}
|
|
531
|
+
if (filePath.includes(".table.cube")) {
|
|
532
|
+
const hasColumns = lines.some((line) => line.includes("@columns"));
|
|
533
|
+
if (!hasColumns) {
|
|
534
|
+
errors.push({
|
|
535
|
+
itemName: fileName,
|
|
536
|
+
error: "Table cube files require @columns annotation",
|
|
537
|
+
filePath,
|
|
538
|
+
lineNumber: 1
|
|
539
|
+
});
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
getColumnTypeForOptions(lines, optionsLineIndex) {
|
|
544
|
+
for (let i = optionsLineIndex - 1; i >= 0; i--) {
|
|
545
|
+
const line = lines[i];
|
|
546
|
+
const typeMatch = line.match(/^\s*type\s*:\s*"([^"]+)"/);
|
|
547
|
+
if (typeMatch) {
|
|
548
|
+
return typeMatch[1];
|
|
549
|
+
}
|
|
550
|
+
if (/^\s*[a-zA-Z_][a-zA-Z0-9_]*\s*:\s*\{/.test(line)) {
|
|
551
|
+
break;
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
return "unknown";
|
|
555
|
+
}
|
|
556
|
+
isOptionCompatibleWithType(option, type) {
|
|
557
|
+
const compatibilityRules = {
|
|
558
|
+
"zerofill": ["int", "decimal", "float", "double"],
|
|
559
|
+
"unsigned": ["int", "decimal", "float", "double"],
|
|
560
|
+
"autoincrement": ["int"],
|
|
561
|
+
"primary": ["int", "varchar", "string"],
|
|
562
|
+
"not null": ["int", "varchar", "string", "text", "boolean", "date", "datetime", "timestamp", "decimal", "float", "double"],
|
|
563
|
+
"unique": ["int", "varchar", "string", "text"],
|
|
564
|
+
"index": ["int", "varchar", "string", "text", "date", "datetime", "timestamp"],
|
|
565
|
+
"required": ["int", "varchar", "string", "text", "boolean", "date", "datetime", "timestamp", "decimal", "float", "double"]
|
|
566
|
+
};
|
|
567
|
+
const compatibleTypes = compatibilityRules[option];
|
|
568
|
+
if (!compatibleTypes) {
|
|
569
|
+
return true;
|
|
570
|
+
}
|
|
571
|
+
return compatibleTypes.includes(type);
|
|
572
|
+
}
|
|
573
|
+
isInsideColumnsBlock(content, lineIndex) {
|
|
574
|
+
const lines = content.split("\n");
|
|
575
|
+
let columnsStartLine = -1;
|
|
576
|
+
let columnsEndLine = -1;
|
|
577
|
+
for (let i = 0; i < lines.length; i++) {
|
|
578
|
+
if (lines[i].includes("@columns")) {
|
|
579
|
+
columnsStartLine = i;
|
|
580
|
+
let braceCount = 0;
|
|
581
|
+
for (let j = i; j < lines.length; j++) {
|
|
582
|
+
const currentLine = lines[j];
|
|
583
|
+
braceCount += (currentLine.match(/\{/g) || []).length;
|
|
584
|
+
braceCount -= (currentLine.match(/\}/g) || []).length;
|
|
585
|
+
if (braceCount === 0 && j > i) {
|
|
586
|
+
columnsEndLine = j;
|
|
587
|
+
break;
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
break;
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
return columnsStartLine !== -1 && columnsEndLine !== -1 && lineIndex > columnsStartLine && lineIndex < columnsEndLine;
|
|
594
|
+
}
|
|
260
595
|
};
|
|
261
596
|
|
|
262
597
|
// src/lib/Schema.ts
|
|
@@ -268,18 +603,27 @@ var Schema = class {
|
|
|
268
603
|
this.engine = new import_core.Engine(name);
|
|
269
604
|
}
|
|
270
605
|
/**
|
|
271
|
-
* Validates
|
|
606
|
+
* Validates cube file comprehensively including syntax, database configuration, and structure
|
|
272
607
|
* @param filePath - Path to the cube file
|
|
273
|
-
* @returns
|
|
608
|
+
* @returns validation result with any errors found
|
|
274
609
|
*/
|
|
275
610
|
validateDatabaseConfiguration(filePath) {
|
|
276
611
|
try {
|
|
612
|
+
const cubeValidator = new CubeValidator();
|
|
613
|
+
const cubeValidation = cubeValidator.validateCubeFile(filePath);
|
|
614
|
+
if (!cubeValidation.isValid && cubeValidation.errors.length > 0) {
|
|
615
|
+
return {
|
|
616
|
+
isValid: false,
|
|
617
|
+
error: cubeValidation.errors[0]
|
|
618
|
+
// Return the first error found
|
|
619
|
+
};
|
|
620
|
+
}
|
|
277
621
|
const dbResult = FileUtils_default.extractDatabaseNameFromCube(filePath);
|
|
278
622
|
if (dbResult.status !== 200) {
|
|
279
623
|
return {
|
|
280
624
|
isValid: false,
|
|
281
625
|
error: {
|
|
282
|
-
itemName:
|
|
626
|
+
itemName: import_path2.default.basename(filePath, import_path2.default.extname(filePath)),
|
|
283
627
|
error: `Error reading database directive: ${dbResult.message}`,
|
|
284
628
|
filePath,
|
|
285
629
|
lineNumber: this.findDatabaseLineNumber(filePath)
|
|
@@ -288,7 +632,7 @@ var Schema = class {
|
|
|
288
632
|
}
|
|
289
633
|
const cubeDbName = dbResult.message;
|
|
290
634
|
const configInstance = new import_core.Config();
|
|
291
|
-
const configFilePath =
|
|
635
|
+
const configFilePath = import_path2.default.resolve(process.cwd(), "dbcube.config.js");
|
|
292
636
|
const configFn = require(configFilePath);
|
|
293
637
|
if (typeof configFn === "function") {
|
|
294
638
|
configFn(configInstance);
|
|
@@ -315,7 +659,7 @@ var Schema = class {
|
|
|
315
659
|
return {
|
|
316
660
|
isValid: false,
|
|
317
661
|
error: {
|
|
318
|
-
itemName:
|
|
662
|
+
itemName: import_path2.default.basename(filePath, import_path2.default.extname(filePath)),
|
|
319
663
|
error: `Database configuration '${cubeDbName}' not found in dbcube.config.js. Available: ${availableText}`,
|
|
320
664
|
filePath,
|
|
321
665
|
lineNumber: this.findDatabaseLineNumber(filePath)
|
|
@@ -327,7 +671,7 @@ var Schema = class {
|
|
|
327
671
|
return {
|
|
328
672
|
isValid: false,
|
|
329
673
|
error: {
|
|
330
|
-
itemName:
|
|
674
|
+
itemName: import_path2.default.basename(filePath, import_path2.default.extname(filePath)),
|
|
331
675
|
error: `Database configuration validation failed: ${error.message}`,
|
|
332
676
|
filePath,
|
|
333
677
|
lineNumber: this.findDatabaseLineNumber(filePath)
|
|
@@ -340,7 +684,7 @@ var Schema = class {
|
|
|
340
684
|
*/
|
|
341
685
|
findDatabaseLineNumber(filePath) {
|
|
342
686
|
try {
|
|
343
|
-
const content =
|
|
687
|
+
const content = import_fs3.default.readFileSync(filePath, "utf8");
|
|
344
688
|
const lines = content.split("\n");
|
|
345
689
|
for (let i = 0; i < lines.length; i++) {
|
|
346
690
|
if (lines[i].includes("@database")) {
|
|
@@ -354,7 +698,7 @@ var Schema = class {
|
|
|
354
698
|
}
|
|
355
699
|
async createDatabase() {
|
|
356
700
|
const startTime = Date.now();
|
|
357
|
-
const rootPath =
|
|
701
|
+
const rootPath = import_path2.default.resolve(process.cwd());
|
|
358
702
|
UIUtils.showOperationHeader(" CREATING DATABASE", this.name, "\u{1F5C4}\uFE0F");
|
|
359
703
|
await UIUtils.showItemProgress("Preparando e instalando base de datos", 1, 1);
|
|
360
704
|
try {
|
|
@@ -398,8 +742,8 @@ var Schema = class {
|
|
|
398
742
|
}
|
|
399
743
|
async refreshTables() {
|
|
400
744
|
const startTime = Date.now();
|
|
401
|
-
const cubesDir =
|
|
402
|
-
if (!
|
|
745
|
+
const cubesDir = import_path2.default.join(process.cwd(), "dbcube", "cubes");
|
|
746
|
+
if (!import_fs3.default.existsSync(cubesDir)) {
|
|
403
747
|
throw new Error("\u274C The cubes folder does not exist");
|
|
404
748
|
}
|
|
405
749
|
const cubeFiles = FileUtils_default.getCubeFilesRecursively("dbcube", "table.cube");
|
|
@@ -414,11 +758,11 @@ var Schema = class {
|
|
|
414
758
|
const errors = [];
|
|
415
759
|
for (let index = 0; index < cubeFiles.length; index++) {
|
|
416
760
|
const file = cubeFiles[index];
|
|
417
|
-
const filePath =
|
|
418
|
-
const stats =
|
|
761
|
+
const filePath = import_path2.default.isAbsolute(file) ? file : import_path2.default.join(cubesDir, file);
|
|
762
|
+
const stats = import_fs3.default.statSync(filePath);
|
|
419
763
|
if (stats.isFile()) {
|
|
420
764
|
const getTableName = FileUtils_default.extracTableNameFromCube(filePath);
|
|
421
|
-
const tableName = getTableName.status === 200 ? getTableName.message :
|
|
765
|
+
const tableName = getTableName.status === 200 ? getTableName.message : import_path2.default.basename(file, ".table.cube");
|
|
422
766
|
await UIUtils.showItemProgress(tableName, index + 1, cubeFiles.length);
|
|
423
767
|
try {
|
|
424
768
|
const validation = this.validateDatabaseConfiguration(filePath);
|
|
@@ -500,8 +844,8 @@ var Schema = class {
|
|
|
500
844
|
}
|
|
501
845
|
async freshTables() {
|
|
502
846
|
const startTime = Date.now();
|
|
503
|
-
const cubesDir =
|
|
504
|
-
if (!
|
|
847
|
+
const cubesDir = import_path2.default.join(process.cwd(), "dbcube", "cubes");
|
|
848
|
+
if (!import_fs3.default.existsSync(cubesDir)) {
|
|
505
849
|
throw new Error("\u274C The cubes folder does not exist");
|
|
506
850
|
}
|
|
507
851
|
const cubeFiles = FileUtils_default.getCubeFilesRecursively("dbcube", "table.cube");
|
|
@@ -516,11 +860,11 @@ var Schema = class {
|
|
|
516
860
|
const errors = [];
|
|
517
861
|
for (let index = 0; index < cubeFiles.length; index++) {
|
|
518
862
|
const file = cubeFiles[index];
|
|
519
|
-
const filePath =
|
|
520
|
-
const stats =
|
|
863
|
+
const filePath = import_path2.default.isAbsolute(file) ? file : import_path2.default.join(cubesDir, file);
|
|
864
|
+
const stats = import_fs3.default.statSync(filePath);
|
|
521
865
|
if (stats.isFile()) {
|
|
522
866
|
const getTableName = FileUtils_default.extracTableNameFromCube(filePath);
|
|
523
|
-
const tableName = getTableName.status === 200 ? getTableName.message :
|
|
867
|
+
const tableName = getTableName.status === 200 ? getTableName.message : import_path2.default.basename(file, ".table.cube");
|
|
524
868
|
await UIUtils.showItemProgress(tableName, index + 1, cubeFiles.length);
|
|
525
869
|
try {
|
|
526
870
|
const validation = this.validateDatabaseConfiguration(filePath);
|
|
@@ -600,8 +944,8 @@ var Schema = class {
|
|
|
600
944
|
}
|
|
601
945
|
async executeSeeders() {
|
|
602
946
|
const startTime = Date.now();
|
|
603
|
-
const cubesDir =
|
|
604
|
-
if (!
|
|
947
|
+
const cubesDir = import_path2.default.join(process.cwd(), "dbcube", "cubes");
|
|
948
|
+
if (!import_fs3.default.existsSync(cubesDir)) {
|
|
605
949
|
throw new Error("\u274C The cubes folder does not exist");
|
|
606
950
|
}
|
|
607
951
|
const cubeFiles = FileUtils_default.getCubeFilesRecursively("dbcube", "seeder.cube");
|
|
@@ -616,11 +960,11 @@ var Schema = class {
|
|
|
616
960
|
const errors = [];
|
|
617
961
|
for (let index = 0; index < cubeFiles.length; index++) {
|
|
618
962
|
const file = cubeFiles[index];
|
|
619
|
-
const filePath =
|
|
620
|
-
const stats =
|
|
963
|
+
const filePath = import_path2.default.isAbsolute(file) ? file : import_path2.default.join(cubesDir, file);
|
|
964
|
+
const stats = import_fs3.default.statSync(filePath);
|
|
621
965
|
if (stats.isFile()) {
|
|
622
966
|
const getSeederName = FileUtils_default.extracTableNameFromCube(filePath);
|
|
623
|
-
const seederName = getSeederName.status === 200 ? getSeederName.message :
|
|
967
|
+
const seederName = getSeederName.status === 200 ? getSeederName.message : import_path2.default.basename(file, ".seeder.cube");
|
|
624
968
|
await UIUtils.showItemProgress(seederName, index + 1, cubeFiles.length);
|
|
625
969
|
try {
|
|
626
970
|
const validation = this.validateDatabaseConfiguration(filePath);
|
|
@@ -671,9 +1015,9 @@ var Schema = class {
|
|
|
671
1015
|
}
|
|
672
1016
|
async executeTriggers() {
|
|
673
1017
|
const startTime = Date.now();
|
|
674
|
-
const cubesDir =
|
|
675
|
-
const triggersDirExit =
|
|
676
|
-
if (!
|
|
1018
|
+
const cubesDir = import_path2.default.join(process.cwd(), "dbcube", "cubes");
|
|
1019
|
+
const triggersDirExit = import_path2.default.join(process.cwd(), "dbcube", "triggers");
|
|
1020
|
+
if (!import_fs3.default.existsSync(cubesDir)) {
|
|
677
1021
|
throw new Error("\u274C The cubes folder does not exist");
|
|
678
1022
|
}
|
|
679
1023
|
const cubeFiles = FileUtils_default.getCubeFilesRecursively("dbcube", "trigger.cube");
|
|
@@ -688,11 +1032,11 @@ var Schema = class {
|
|
|
688
1032
|
const errors = [];
|
|
689
1033
|
for (let index = 0; index < cubeFiles.length; index++) {
|
|
690
1034
|
const file = cubeFiles[index];
|
|
691
|
-
const filePath =
|
|
692
|
-
const stats =
|
|
1035
|
+
const filePath = import_path2.default.isAbsolute(file) ? file : import_path2.default.join(cubesDir, file);
|
|
1036
|
+
const stats = import_fs3.default.statSync(filePath);
|
|
693
1037
|
if (stats.isFile()) {
|
|
694
1038
|
const getTriggerName = FileUtils_default.extracTableNameFromCube(filePath);
|
|
695
|
-
const triggerName = getTriggerName.status === 200 ? getTriggerName.message :
|
|
1039
|
+
const triggerName = getTriggerName.status === 200 ? getTriggerName.message : import_path2.default.basename(file, ".trigger.cube");
|
|
696
1040
|
await UIUtils.showItemProgress(triggerName, index + 1, cubeFiles.length);
|
|
697
1041
|
try {
|
|
698
1042
|
const validation = this.validateDatabaseConfiguration(filePath);
|
|
@@ -745,29 +1089,11 @@ var Schema = class {
|
|
|
745
1089
|
}
|
|
746
1090
|
};
|
|
747
1091
|
function returnFormattedError(status, message) {
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
const GRAY = "\x1B[90m";
|
|
754
|
-
const UNDERLINE = "\x1B[4m";
|
|
755
|
-
const MAGENTA = "\x1B[35m";
|
|
756
|
-
let output = "";
|
|
757
|
-
let help = "";
|
|
758
|
-
const color = status === 600 ? YELLOW : RED;
|
|
759
|
-
if (message.includes("[help]")) {
|
|
760
|
-
const parts = message.split("[help]");
|
|
761
|
-
output += `
|
|
762
|
-
${RED}${BOLD}${parts[0]}${RESET}`;
|
|
763
|
-
help += `
|
|
764
|
-
${MAGENTA}${BOLD}[help]${RESET} ${GRAY}${parts[1]}${RESET}
|
|
765
|
-
`;
|
|
766
|
-
} else {
|
|
767
|
-
output += `
|
|
768
|
-
${color}${BOLD}${message}${RESET}
|
|
769
|
-
`;
|
|
770
|
-
}
|
|
1092
|
+
console.log(`
|
|
1093
|
+
${import_chalk2.default.red("\u{1F6AB}")} ${import_chalk2.default.bold.red("ERRORS FOUND")}`);
|
|
1094
|
+
console.log(import_chalk2.default.red("\u2500".repeat(60)));
|
|
1095
|
+
console.log(`${import_chalk2.default.red("[error]")} ${import_chalk2.default.red(message)}`);
|
|
1096
|
+
console.log("");
|
|
771
1097
|
const err = new Error();
|
|
772
1098
|
const stackLines = err.stack?.split("\n") || [];
|
|
773
1099
|
const relevantStackLine = stackLines.find(
|
|
@@ -779,32 +1105,23 @@ ${color}${BOLD}${message}${RESET}
|
|
|
779
1105
|
const [, filePath, lineStr, columnStr] = match;
|
|
780
1106
|
const lineNum = parseInt(lineStr, 10);
|
|
781
1107
|
const errorLocation = `${filePath}:${lineStr}:${columnStr}`;
|
|
1108
|
+
console.log(`${import_chalk2.default.cyan("[code]")} ${import_chalk2.default.yellow(errorLocation)}`);
|
|
782
1109
|
try {
|
|
783
|
-
const codeLines =
|
|
1110
|
+
const codeLines = import_fs3.default.readFileSync(filePath, "utf-8").split("\n");
|
|
784
1111
|
const start = Math.max(0, lineNum - 3);
|
|
785
1112
|
const end = Math.min(codeLines.length, lineNum + 2);
|
|
786
|
-
output += `
|
|
787
|
-
${CYAN}${BOLD}[code] ${RESET}${YELLOW} ${UNDERLINE}${errorLocation}${RESET}
|
|
788
|
-
`;
|
|
789
1113
|
for (let i = start; i < end; i++) {
|
|
790
1114
|
const line = codeLines[i];
|
|
791
1115
|
const lineLabel = `${i + 1}`.padStart(4, " ");
|
|
792
|
-
const pointer = i + 1 === lineNum ? `${
|
|
793
|
-
|
|
794
|
-
`;
|
|
1116
|
+
const pointer = i + 1 === lineNum ? `${import_chalk2.default.red("<-")}` : " ";
|
|
1117
|
+
console.log(`${import_chalk2.default.gray(lineLabel)} ${pointer} ${import_chalk2.default.white(line)}`);
|
|
795
1118
|
}
|
|
796
1119
|
} catch (err2) {
|
|
797
|
-
|
|
798
|
-
`;
|
|
799
|
-
output += `
|
|
800
|
-
${CYAN}${BOLD}Stack Trace:${RESET}
|
|
801
|
-
${stackLines.slice(2).join("\n")}
|
|
802
|
-
`;
|
|
1120
|
+
console.log(import_chalk2.default.gray(" (unable to show code context)"));
|
|
803
1121
|
}
|
|
804
1122
|
}
|
|
805
1123
|
}
|
|
806
|
-
|
|
807
|
-
console.error(output);
|
|
1124
|
+
console.log("");
|
|
808
1125
|
process.exit(1);
|
|
809
1126
|
}
|
|
810
1127
|
|
|
@@ -812,6 +1129,8 @@ ${stackLines.slice(2).join("\n")}
|
|
|
812
1129
|
var index_default = Schema;
|
|
813
1130
|
// Annotate the CommonJS export names for ESM import in node:
|
|
814
1131
|
0 && (module.exports = {
|
|
815
|
-
|
|
1132
|
+
CubeValidator,
|
|
1133
|
+
Schema,
|
|
1134
|
+
UIUtils
|
|
816
1135
|
});
|
|
817
1136
|
//# sourceMappingURL=index.cjs.map
|