@dbcube/schema-builder 1.0.16 → 1.0.18
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 +609 -42
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +108 -3
- package/dist/index.d.ts +108 -3
- package/dist/index.js +605 -41
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -30,15 +30,18 @@ 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,
|
|
34
|
+
DependencyResolver: () => DependencyResolver,
|
|
33
35
|
Schema: () => Schema,
|
|
36
|
+
UIUtils: () => UIUtils,
|
|
34
37
|
default: () => index_default
|
|
35
38
|
});
|
|
36
39
|
module.exports = __toCommonJS(index_exports);
|
|
37
40
|
|
|
38
41
|
// src/lib/Schema.ts
|
|
39
|
-
var
|
|
42
|
+
var import_fs4 = __toESM(require("fs"));
|
|
40
43
|
var import_core = require("@dbcube/core");
|
|
41
|
-
var
|
|
44
|
+
var import_path3 = __toESM(require("path"));
|
|
42
45
|
|
|
43
46
|
// src/lib/FileUtils.ts
|
|
44
47
|
var fs = __toESM(require("fs"));
|
|
@@ -285,6 +288,550 @@ ${import_chalk.default.red("\u{1F6AB}")} ${import_chalk.default.bold.red("ERRORS
|
|
|
285
288
|
}
|
|
286
289
|
};
|
|
287
290
|
|
|
291
|
+
// src/lib/CubeValidator.ts
|
|
292
|
+
var import_fs2 = __toESM(require("fs"));
|
|
293
|
+
var import_path = __toESM(require("path"));
|
|
294
|
+
var CubeValidator = class {
|
|
295
|
+
validTypes = ["varchar", "int", "string", "text", "boolean", "date", "datetime", "timestamp", "decimal", "float", "double", "enum", "json"];
|
|
296
|
+
validOptions = ["not null", "primary", "autoincrement", "unique", "zerofill", "index", "required", "unsigned"];
|
|
297
|
+
validProperties = ["type", "length", "options", "value", "defaultValue", "foreign", "enumValues", "description"];
|
|
298
|
+
knownAnnotations = ["database", "table", "meta", "columns", "fields", "dataset", "beforeAdd", "afterAdd", "beforeUpdate", "afterUpdate", "beforeDelete", "afterDelete", "compute", "column"];
|
|
299
|
+
/**
|
|
300
|
+
* Validates a cube file comprehensively
|
|
301
|
+
*/
|
|
302
|
+
validateCubeFile(filePath) {
|
|
303
|
+
const errors = [];
|
|
304
|
+
try {
|
|
305
|
+
const content = import_fs2.default.readFileSync(filePath, "utf8");
|
|
306
|
+
const lines = content.split("\n");
|
|
307
|
+
const fileName = import_path.default.basename(filePath, import_path.default.extname(filePath));
|
|
308
|
+
for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {
|
|
309
|
+
const line = lines[lineIndex];
|
|
310
|
+
if (line.trim() === "" || line.trim().startsWith("//")) {
|
|
311
|
+
continue;
|
|
312
|
+
}
|
|
313
|
+
this.validateAnnotations(line, lineIndex + 1, filePath, fileName, errors);
|
|
314
|
+
this.validateDataTypes(line, lineIndex + 1, filePath, fileName, errors, content);
|
|
315
|
+
this.validateColumnOptions(line, lineIndex + 1, filePath, fileName, errors, lines);
|
|
316
|
+
this.validateColumnProperties(line, lineIndex + 1, filePath, fileName, errors, content);
|
|
317
|
+
this.validateRequiredColumnProperties(lines, lineIndex + 1, filePath, fileName, errors);
|
|
318
|
+
this.validateGeneralSyntax(line, lineIndex + 1, filePath, fileName, errors);
|
|
319
|
+
}
|
|
320
|
+
this.validateOverallStructure(content, filePath, fileName, errors);
|
|
321
|
+
} catch (error) {
|
|
322
|
+
errors.push({
|
|
323
|
+
itemName: import_path.default.basename(filePath, import_path.default.extname(filePath)),
|
|
324
|
+
error: `Failed to read cube file: ${error.message}`,
|
|
325
|
+
filePath,
|
|
326
|
+
lineNumber: 1
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
return {
|
|
330
|
+
isValid: errors.length === 0,
|
|
331
|
+
errors
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
validateAnnotations(line, lineNumber, filePath, fileName, errors) {
|
|
335
|
+
const annotationRegex = /@(\w+)/g;
|
|
336
|
+
let match;
|
|
337
|
+
while ((match = annotationRegex.exec(line)) !== null) {
|
|
338
|
+
const annotation = match[1];
|
|
339
|
+
if (!this.knownAnnotations.includes(annotation)) {
|
|
340
|
+
errors.push({
|
|
341
|
+
itemName: fileName,
|
|
342
|
+
error: `Unknown annotation '@${annotation}'. Valid annotations: ${this.knownAnnotations.join(", ")}`,
|
|
343
|
+
filePath,
|
|
344
|
+
lineNumber
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
validateDataTypes(line, lineNumber, filePath, fileName, errors, content) {
|
|
350
|
+
const typeRegex = /type:\s*["'](\w+)["']/g;
|
|
351
|
+
let match;
|
|
352
|
+
while ((match = typeRegex.exec(line)) !== null) {
|
|
353
|
+
const type = match[1];
|
|
354
|
+
if (!this.validTypes.includes(type)) {
|
|
355
|
+
errors.push({
|
|
356
|
+
itemName: fileName,
|
|
357
|
+
error: `Invalid data type '${type}'. Valid types: ${this.validTypes.join(", ")}`,
|
|
358
|
+
filePath,
|
|
359
|
+
lineNumber
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
if (line.includes('type: "varchar"')) {
|
|
364
|
+
const lines = content.split("\n");
|
|
365
|
+
const hasLengthNearby = lines.slice(Math.max(0, lineNumber - 1), Math.min(lineNumber + 4, lines.length)).some((nextLine) => nextLine.includes("length:"));
|
|
366
|
+
if (!hasLengthNearby) {
|
|
367
|
+
errors.push({
|
|
368
|
+
itemName: fileName,
|
|
369
|
+
error: "VARCHAR type requires a length specification",
|
|
370
|
+
filePath,
|
|
371
|
+
lineNumber
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
validateColumnOptions(line, lineNumber, filePath, fileName, errors, lines) {
|
|
377
|
+
const optionsMatch = line.match(/^\s*options\s*:\s*\[(.*)\]\s*;?\s*$/);
|
|
378
|
+
if (!optionsMatch) return;
|
|
379
|
+
const optionsContent = optionsMatch[1].trim();
|
|
380
|
+
const invalidSyntaxMatch = optionsContent.match(/[^",\s]+(?![^"]*")/);
|
|
381
|
+
if (invalidSyntaxMatch) {
|
|
382
|
+
errors.push({
|
|
383
|
+
itemName: fileName,
|
|
384
|
+
error: `Invalid syntax '${invalidSyntaxMatch[0]}' in options array. All values must be quoted strings`,
|
|
385
|
+
filePath,
|
|
386
|
+
lineNumber
|
|
387
|
+
});
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
390
|
+
const optionMatches = optionsContent.match(/"([^"]*)"/g);
|
|
391
|
+
if (optionMatches) {
|
|
392
|
+
const columnType = this.getColumnTypeForOptions(lines, lineNumber - 1);
|
|
393
|
+
optionMatches.forEach((optionMatch) => {
|
|
394
|
+
const option = optionMatch.replace(/"/g, "");
|
|
395
|
+
if (option.trim() === "") {
|
|
396
|
+
errors.push({
|
|
397
|
+
itemName: fileName,
|
|
398
|
+
error: "Empty option found in options array. All options must have a value",
|
|
399
|
+
filePath,
|
|
400
|
+
lineNumber
|
|
401
|
+
});
|
|
402
|
+
} else if (!this.validOptions.includes(option)) {
|
|
403
|
+
errors.push({
|
|
404
|
+
itemName: fileName,
|
|
405
|
+
error: `Invalid option '${option}'. Valid options: ${this.validOptions.join(", ")}`,
|
|
406
|
+
filePath,
|
|
407
|
+
lineNumber
|
|
408
|
+
});
|
|
409
|
+
} else if (columnType !== "unknown" && !this.isOptionCompatibleWithType(option, columnType)) {
|
|
410
|
+
errors.push({
|
|
411
|
+
itemName: fileName,
|
|
412
|
+
error: `Option '${option}' is not compatible with type '${columnType}'`,
|
|
413
|
+
filePath,
|
|
414
|
+
lineNumber
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
validateColumnProperties(line, lineNumber, filePath, fileName, errors, content) {
|
|
421
|
+
const propertyKeyRegex = /^\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*:/;
|
|
422
|
+
const propMatch = propertyKeyRegex.exec(line);
|
|
423
|
+
if (!propMatch) return;
|
|
424
|
+
const propertyName = propMatch[1];
|
|
425
|
+
if (/^\s*[a-zA-Z_][a-zA-Z0-9_]*\s*:\s*\{/.test(line)) {
|
|
426
|
+
return;
|
|
427
|
+
}
|
|
428
|
+
if (this.isInsideForeignKeyObject(content, lineNumber - 1)) {
|
|
429
|
+
const validForeignKeyProperties = ["table", "column"];
|
|
430
|
+
if (!validForeignKeyProperties.includes(propertyName)) {
|
|
431
|
+
errors.push({
|
|
432
|
+
itemName: fileName,
|
|
433
|
+
error: `Invalid foreign key property '${propertyName}'. Valid foreign key properties: ${validForeignKeyProperties.join(", ")}`,
|
|
434
|
+
filePath,
|
|
435
|
+
lineNumber
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
return;
|
|
439
|
+
}
|
|
440
|
+
if (this.isInsideColumnsBlock(content, lineNumber - 1)) {
|
|
441
|
+
if (!this.validProperties.includes(propertyName)) {
|
|
442
|
+
errors.push({
|
|
443
|
+
itemName: fileName,
|
|
444
|
+
error: `Invalid property '${propertyName}'. Valid properties: ${this.validProperties.join(", ")}`,
|
|
445
|
+
filePath,
|
|
446
|
+
lineNumber
|
|
447
|
+
});
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
if (/^\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*:\s*$/.test(line)) {
|
|
451
|
+
errors.push({
|
|
452
|
+
itemName: fileName,
|
|
453
|
+
error: `Property '${propertyName}' is missing a value`,
|
|
454
|
+
filePath,
|
|
455
|
+
lineNumber
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
validateRequiredColumnProperties(lines, lineNumber, filePath, fileName, errors) {
|
|
460
|
+
const line = lines[lineNumber - 1];
|
|
461
|
+
if (!/^\s*\}\s*;?\s*$/.test(line)) {
|
|
462
|
+
return;
|
|
463
|
+
}
|
|
464
|
+
let columnStartLine = -1;
|
|
465
|
+
let columnName = "";
|
|
466
|
+
for (let i = lineNumber - 2; i >= 0; i--) {
|
|
467
|
+
const currentLine = lines[i];
|
|
468
|
+
const columnDefMatch = currentLine.match(/^\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*:\s*\{/);
|
|
469
|
+
if (columnDefMatch) {
|
|
470
|
+
let openBraces = 0;
|
|
471
|
+
let closeBraces = 0;
|
|
472
|
+
for (let j = i; j < lineNumber; j++) {
|
|
473
|
+
openBraces += (lines[j].match(/\{/g) || []).length;
|
|
474
|
+
closeBraces += (lines[j].match(/\}/g) || []).length;
|
|
475
|
+
}
|
|
476
|
+
if (openBraces === closeBraces) {
|
|
477
|
+
columnStartLine = i;
|
|
478
|
+
columnName = columnDefMatch[1];
|
|
479
|
+
break;
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
if (columnStartLine === -1 || !columnName) return;
|
|
484
|
+
let hasType = false;
|
|
485
|
+
for (let i = columnStartLine + 1; i < lineNumber - 1; i++) {
|
|
486
|
+
if (lines[i].match(/^\s*type\s*:/)) {
|
|
487
|
+
hasType = true;
|
|
488
|
+
break;
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
if (!hasType && columnName !== "foreign" && columnName !== "defaultValue") {
|
|
492
|
+
errors.push({
|
|
493
|
+
itemName: fileName,
|
|
494
|
+
error: `Column '${columnName}' is missing required 'type' property`,
|
|
495
|
+
filePath,
|
|
496
|
+
lineNumber: columnStartLine + 1
|
|
497
|
+
});
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
validateGeneralSyntax(line, lineNumber, filePath, fileName, errors) {
|
|
501
|
+
const quotes = line.match(/["']/g);
|
|
502
|
+
if (quotes && quotes.length % 2 !== 0) {
|
|
503
|
+
errors.push({
|
|
504
|
+
itemName: fileName,
|
|
505
|
+
error: "Mismatched quotes detected",
|
|
506
|
+
filePath,
|
|
507
|
+
lineNumber
|
|
508
|
+
});
|
|
509
|
+
}
|
|
510
|
+
if (line.includes("@database") || line.includes("@table")) {
|
|
511
|
+
const stringAnnotationRegex = /@(database|table)\s*\(\s*"([^"]*)"\s*\)/;
|
|
512
|
+
if (!stringAnnotationRegex.test(line)) {
|
|
513
|
+
errors.push({
|
|
514
|
+
itemName: fileName,
|
|
515
|
+
error: 'Invalid annotation syntax. Expected format: @annotation("value")',
|
|
516
|
+
filePath,
|
|
517
|
+
lineNumber
|
|
518
|
+
});
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
if (line.includes("@meta")) {
|
|
522
|
+
const metaObjectRegex = /@meta\s*\(\s*\{/;
|
|
523
|
+
if (!metaObjectRegex.test(line)) {
|
|
524
|
+
errors.push({
|
|
525
|
+
itemName: fileName,
|
|
526
|
+
error: "Invalid @meta syntax. Expected format: @meta({ ... })",
|
|
527
|
+
filePath,
|
|
528
|
+
lineNumber
|
|
529
|
+
});
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
validateOverallStructure(content, filePath, fileName, errors) {
|
|
534
|
+
const lines = content.split("\n");
|
|
535
|
+
const hasDatabase = lines.some((line) => line.includes("@database"));
|
|
536
|
+
if (!hasDatabase) {
|
|
537
|
+
errors.push({
|
|
538
|
+
itemName: fileName,
|
|
539
|
+
error: "Missing required @database annotation",
|
|
540
|
+
filePath,
|
|
541
|
+
lineNumber: 1
|
|
542
|
+
});
|
|
543
|
+
}
|
|
544
|
+
if (filePath.includes(".table.cube")) {
|
|
545
|
+
const hasColumns = lines.some((line) => line.includes("@columns"));
|
|
546
|
+
if (!hasColumns) {
|
|
547
|
+
errors.push({
|
|
548
|
+
itemName: fileName,
|
|
549
|
+
error: "Table cube files require @columns annotation",
|
|
550
|
+
filePath,
|
|
551
|
+
lineNumber: 1
|
|
552
|
+
});
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
getColumnTypeForOptions(lines, optionsLineIndex) {
|
|
557
|
+
for (let i = optionsLineIndex - 1; i >= 0; i--) {
|
|
558
|
+
const line = lines[i];
|
|
559
|
+
const typeMatch = line.match(/^\s*type\s*:\s*"([^"]+)"/);
|
|
560
|
+
if (typeMatch) {
|
|
561
|
+
return typeMatch[1];
|
|
562
|
+
}
|
|
563
|
+
if (/^\s*[a-zA-Z_][a-zA-Z0-9_]*\s*:\s*\{/.test(line)) {
|
|
564
|
+
break;
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
return "unknown";
|
|
568
|
+
}
|
|
569
|
+
isOptionCompatibleWithType(option, type) {
|
|
570
|
+
const compatibilityRules = {
|
|
571
|
+
"zerofill": ["int", "decimal", "float", "double"],
|
|
572
|
+
"unsigned": ["int", "decimal", "float", "double"],
|
|
573
|
+
"autoincrement": ["int"],
|
|
574
|
+
"primary": ["int", "varchar", "string"],
|
|
575
|
+
"not null": ["int", "varchar", "string", "text", "boolean", "date", "datetime", "timestamp", "decimal", "float", "double"],
|
|
576
|
+
"unique": ["int", "varchar", "string", "text"],
|
|
577
|
+
"index": ["int", "varchar", "string", "text", "date", "datetime", "timestamp"],
|
|
578
|
+
"required": ["int", "varchar", "string", "text", "boolean", "date", "datetime", "timestamp", "decimal", "float", "double"]
|
|
579
|
+
};
|
|
580
|
+
const compatibleTypes = compatibilityRules[option];
|
|
581
|
+
if (!compatibleTypes) {
|
|
582
|
+
return true;
|
|
583
|
+
}
|
|
584
|
+
return compatibleTypes.includes(type);
|
|
585
|
+
}
|
|
586
|
+
isInsideColumnsBlock(content, lineIndex) {
|
|
587
|
+
const lines = content.split("\n");
|
|
588
|
+
let columnsStartLine = -1;
|
|
589
|
+
let columnsEndLine = -1;
|
|
590
|
+
for (let i = 0; i < lines.length; i++) {
|
|
591
|
+
if (lines[i].includes("@columns")) {
|
|
592
|
+
columnsStartLine = i;
|
|
593
|
+
let braceCount = 0;
|
|
594
|
+
for (let j = i; j < lines.length; j++) {
|
|
595
|
+
const currentLine = lines[j];
|
|
596
|
+
braceCount += (currentLine.match(/\{/g) || []).length;
|
|
597
|
+
braceCount -= (currentLine.match(/\}/g) || []).length;
|
|
598
|
+
if (braceCount === 0 && j > i) {
|
|
599
|
+
columnsEndLine = j;
|
|
600
|
+
break;
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
break;
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
return columnsStartLine !== -1 && columnsEndLine !== -1 && lineIndex > columnsStartLine && lineIndex < columnsEndLine;
|
|
607
|
+
}
|
|
608
|
+
isInsideForeignKeyObject(content, lineIndex) {
|
|
609
|
+
const lines = content.split("\n");
|
|
610
|
+
for (let i = lineIndex; i >= 0; i--) {
|
|
611
|
+
const line = lines[i];
|
|
612
|
+
if (/foreign\s*:\s*\{/.test(line)) {
|
|
613
|
+
let braceCount = 0;
|
|
614
|
+
for (let j = i; j <= lineIndex; j++) {
|
|
615
|
+
const currentLine = lines[j];
|
|
616
|
+
const openBraces = (currentLine.match(/\{/g) || []).length;
|
|
617
|
+
const closeBraces = (currentLine.match(/\}/g) || []).length;
|
|
618
|
+
braceCount += openBraces - closeBraces;
|
|
619
|
+
if (braceCount === 0 && j > i) {
|
|
620
|
+
return false;
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
return braceCount > 0;
|
|
624
|
+
}
|
|
625
|
+
if (line.trim() === "}" || line.includes("};")) {
|
|
626
|
+
break;
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
return false;
|
|
630
|
+
}
|
|
631
|
+
};
|
|
632
|
+
|
|
633
|
+
// src/lib/DependencyResolver.ts
|
|
634
|
+
var import_fs3 = __toESM(require("fs"));
|
|
635
|
+
var import_path2 = __toESM(require("path"));
|
|
636
|
+
var DependencyResolver = class {
|
|
637
|
+
/**
|
|
638
|
+
* Resolves table dependencies and creates execution order
|
|
639
|
+
*/
|
|
640
|
+
static resolveDependencies(cubeFiles, cubeType = "table") {
|
|
641
|
+
const tableDependencies = this.extractDependencies(cubeFiles, cubeType);
|
|
642
|
+
const orderedTables = this.topologicalSort(tableDependencies);
|
|
643
|
+
const executionOrder = {
|
|
644
|
+
tables: cubeType === "table" ? orderedTables : [],
|
|
645
|
+
seeders: cubeType === "seeder" ? orderedTables : [],
|
|
646
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
647
|
+
};
|
|
648
|
+
this.saveExecutionOrder(executionOrder);
|
|
649
|
+
return executionOrder;
|
|
650
|
+
}
|
|
651
|
+
/**
|
|
652
|
+
* Extracts dependencies from cube files
|
|
653
|
+
*/
|
|
654
|
+
static extractDependencies(cubeFiles, cubeType) {
|
|
655
|
+
const dependencies = [];
|
|
656
|
+
for (const file of cubeFiles) {
|
|
657
|
+
let filePath;
|
|
658
|
+
if (import_path2.default.isAbsolute(file)) {
|
|
659
|
+
filePath = file;
|
|
660
|
+
} else if (import_fs3.default.existsSync(file)) {
|
|
661
|
+
filePath = import_path2.default.resolve(file);
|
|
662
|
+
} else {
|
|
663
|
+
filePath = import_path2.default.join(process.cwd(), "dbcube", "cubes", file);
|
|
664
|
+
}
|
|
665
|
+
try {
|
|
666
|
+
const tableNameResult = FileUtils_default.extracTableNameFromCube(filePath);
|
|
667
|
+
const tableName = tableNameResult.status === 200 ? tableNameResult.message : import_path2.default.basename(file, `.${cubeType}.cube`);
|
|
668
|
+
const deps = this.extractForeignKeyReferences(filePath);
|
|
669
|
+
dependencies.push({
|
|
670
|
+
tableName,
|
|
671
|
+
filePath,
|
|
672
|
+
dependencies: deps
|
|
673
|
+
});
|
|
674
|
+
} catch (error) {
|
|
675
|
+
console.error(`Error processing ${filePath}:`, error);
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
return dependencies;
|
|
679
|
+
}
|
|
680
|
+
/**
|
|
681
|
+
* Extracts foreign key references from a cube file
|
|
682
|
+
*/
|
|
683
|
+
static extractForeignKeyReferences(filePath) {
|
|
684
|
+
const dependencies = [];
|
|
685
|
+
try {
|
|
686
|
+
const content = import_fs3.default.readFileSync(filePath, "utf8");
|
|
687
|
+
const lines = content.split("\n");
|
|
688
|
+
let insideForeignKey = false;
|
|
689
|
+
let braceCount = 0;
|
|
690
|
+
for (const line of lines) {
|
|
691
|
+
if (/foreign\s*:\s*\{/.test(line)) {
|
|
692
|
+
insideForeignKey = true;
|
|
693
|
+
braceCount = 1;
|
|
694
|
+
const sameLineMatch = line.match(/table\s*:\s*["']([^"']+)["']/);
|
|
695
|
+
if (sameLineMatch) {
|
|
696
|
+
dependencies.push(sameLineMatch[1]);
|
|
697
|
+
insideForeignKey = false;
|
|
698
|
+
braceCount = 0;
|
|
699
|
+
}
|
|
700
|
+
continue;
|
|
701
|
+
}
|
|
702
|
+
if (insideForeignKey) {
|
|
703
|
+
braceCount += (line.match(/\{/g) || []).length;
|
|
704
|
+
braceCount -= (line.match(/\}/g) || []).length;
|
|
705
|
+
const tableMatch = line.match(/table\s*:\s*["']([^"']+)["']/);
|
|
706
|
+
if (tableMatch) {
|
|
707
|
+
dependencies.push(tableMatch[1]);
|
|
708
|
+
}
|
|
709
|
+
if (braceCount === 0) {
|
|
710
|
+
insideForeignKey = false;
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
} catch (error) {
|
|
715
|
+
console.error(`Error reading file ${filePath}:`, error);
|
|
716
|
+
}
|
|
717
|
+
return dependencies;
|
|
718
|
+
}
|
|
719
|
+
/**
|
|
720
|
+
* Performs topological sort to determine execution order
|
|
721
|
+
*/
|
|
722
|
+
static topologicalSort(dependencies) {
|
|
723
|
+
const graph = /* @__PURE__ */ new Map();
|
|
724
|
+
const inDegree = /* @__PURE__ */ new Map();
|
|
725
|
+
const tableMap = /* @__PURE__ */ new Map();
|
|
726
|
+
for (const dep of dependencies) {
|
|
727
|
+
graph.set(dep.tableName, dep.dependencies);
|
|
728
|
+
inDegree.set(dep.tableName, 0);
|
|
729
|
+
tableMap.set(dep.tableName, dep);
|
|
730
|
+
}
|
|
731
|
+
for (const dep of dependencies) {
|
|
732
|
+
for (const dependency of dep.dependencies) {
|
|
733
|
+
if (inDegree.has(dependency)) {
|
|
734
|
+
inDegree.set(dep.tableName, (inDegree.get(dep.tableName) || 0) + 1);
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
const queue = [];
|
|
739
|
+
const result = [];
|
|
740
|
+
for (const [table, degree] of inDegree) {
|
|
741
|
+
if (degree === 0) {
|
|
742
|
+
queue.push(table);
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
while (queue.length > 0) {
|
|
746
|
+
const current = queue.shift();
|
|
747
|
+
result.push(current);
|
|
748
|
+
const currentDeps = graph.get(current) || [];
|
|
749
|
+
for (const neighbor of currentDeps) {
|
|
750
|
+
if (inDegree.has(neighbor)) {
|
|
751
|
+
const newDegree = (inDegree.get(neighbor) || 0) - 1;
|
|
752
|
+
inDegree.set(neighbor, newDegree);
|
|
753
|
+
if (newDegree === 0) {
|
|
754
|
+
queue.push(neighbor);
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
if (result.length !== dependencies.length) {
|
|
760
|
+
console.warn("\u26A0\uFE0F Circular dependencies detected in tables. Some tables may not execute in optimal order.");
|
|
761
|
+
for (const dep of dependencies) {
|
|
762
|
+
if (!result.includes(dep.tableName)) {
|
|
763
|
+
result.push(dep.tableName);
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
return result;
|
|
768
|
+
}
|
|
769
|
+
/**
|
|
770
|
+
* Saves the execution order to .dbcube/orderexecute.json
|
|
771
|
+
*/
|
|
772
|
+
static saveExecutionOrder(order) {
|
|
773
|
+
try {
|
|
774
|
+
const projectRoot = process.cwd();
|
|
775
|
+
const dbcubeDir = import_path2.default.join(projectRoot, ".dbcube");
|
|
776
|
+
const orderFile = import_path2.default.join(dbcubeDir, "orderexecute.json");
|
|
777
|
+
if (!import_fs3.default.existsSync(dbcubeDir)) {
|
|
778
|
+
import_fs3.default.mkdirSync(dbcubeDir, { recursive: true });
|
|
779
|
+
}
|
|
780
|
+
import_fs3.default.writeFileSync(orderFile, JSON.stringify(order, null, 2), "utf8");
|
|
781
|
+
console.log(`\u{1F4C4} Execution order saved to: ${import_path2.default.relative(projectRoot, orderFile)}`);
|
|
782
|
+
} catch (error) {
|
|
783
|
+
console.error("\u274C Failed to save execution order:", error);
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
/**
|
|
787
|
+
* Loads the execution order from .dbcube/orderexecute.json
|
|
788
|
+
*/
|
|
789
|
+
static loadExecutionOrder() {
|
|
790
|
+
try {
|
|
791
|
+
const projectRoot = process.cwd();
|
|
792
|
+
const orderFile = import_path2.default.join(projectRoot, ".dbcube", "orderexecute.json");
|
|
793
|
+
if (!import_fs3.default.existsSync(orderFile)) {
|
|
794
|
+
return null;
|
|
795
|
+
}
|
|
796
|
+
const content = import_fs3.default.readFileSync(orderFile, "utf8");
|
|
797
|
+
return JSON.parse(content);
|
|
798
|
+
} catch (error) {
|
|
799
|
+
console.error("\u274C Failed to load execution order:", error);
|
|
800
|
+
return null;
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
/**
|
|
804
|
+
* Orders cube files based on saved execution order
|
|
805
|
+
*/
|
|
806
|
+
static orderCubeFiles(cubeFiles, cubeType) {
|
|
807
|
+
const executionOrder = this.loadExecutionOrder();
|
|
808
|
+
if (!executionOrder) {
|
|
809
|
+
console.log("\u{1F4C4} No execution order found, processing files in current order");
|
|
810
|
+
return cubeFiles;
|
|
811
|
+
}
|
|
812
|
+
const orderList = cubeType === "table" ? executionOrder.tables : executionOrder.seeders;
|
|
813
|
+
const orderedFiles = [];
|
|
814
|
+
const fileMap = /* @__PURE__ */ new Map();
|
|
815
|
+
for (const file of cubeFiles) {
|
|
816
|
+
const filePath = import_path2.default.isAbsolute(file) ? file : import_path2.default.join(process.cwd(), "dbcube", "cubes", file);
|
|
817
|
+
const tableNameResult = FileUtils_default.extracTableNameFromCube(filePath);
|
|
818
|
+
const tableName = tableNameResult.status === 200 ? tableNameResult.message : import_path2.default.basename(file, `.${cubeType}.cube`);
|
|
819
|
+
fileMap.set(tableName, file);
|
|
820
|
+
}
|
|
821
|
+
for (const tableName of orderList) {
|
|
822
|
+
if (fileMap.has(tableName)) {
|
|
823
|
+
orderedFiles.push(fileMap.get(tableName));
|
|
824
|
+
fileMap.delete(tableName);
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
for (const [, file] of fileMap) {
|
|
828
|
+
orderedFiles.push(file);
|
|
829
|
+
}
|
|
830
|
+
console.log(`\u{1F4CB} Using dependency order: ${orderList.join(" \u2192 ")}`);
|
|
831
|
+
return orderedFiles;
|
|
832
|
+
}
|
|
833
|
+
};
|
|
834
|
+
|
|
288
835
|
// src/lib/Schema.ts
|
|
289
836
|
var Schema = class {
|
|
290
837
|
name;
|
|
@@ -294,18 +841,27 @@ var Schema = class {
|
|
|
294
841
|
this.engine = new import_core.Engine(name);
|
|
295
842
|
}
|
|
296
843
|
/**
|
|
297
|
-
* Validates
|
|
844
|
+
* Validates cube file comprehensively including syntax, database configuration, and structure
|
|
298
845
|
* @param filePath - Path to the cube file
|
|
299
|
-
* @returns
|
|
846
|
+
* @returns validation result with any errors found
|
|
300
847
|
*/
|
|
301
848
|
validateDatabaseConfiguration(filePath) {
|
|
302
849
|
try {
|
|
850
|
+
const cubeValidator = new CubeValidator();
|
|
851
|
+
const cubeValidation = cubeValidator.validateCubeFile(filePath);
|
|
852
|
+
if (!cubeValidation.isValid && cubeValidation.errors.length > 0) {
|
|
853
|
+
return {
|
|
854
|
+
isValid: false,
|
|
855
|
+
error: cubeValidation.errors[0]
|
|
856
|
+
// Return the first error found
|
|
857
|
+
};
|
|
858
|
+
}
|
|
303
859
|
const dbResult = FileUtils_default.extractDatabaseNameFromCube(filePath);
|
|
304
860
|
if (dbResult.status !== 200) {
|
|
305
861
|
return {
|
|
306
862
|
isValid: false,
|
|
307
863
|
error: {
|
|
308
|
-
itemName:
|
|
864
|
+
itemName: import_path3.default.basename(filePath, import_path3.default.extname(filePath)),
|
|
309
865
|
error: `Error reading database directive: ${dbResult.message}`,
|
|
310
866
|
filePath,
|
|
311
867
|
lineNumber: this.findDatabaseLineNumber(filePath)
|
|
@@ -314,7 +870,7 @@ var Schema = class {
|
|
|
314
870
|
}
|
|
315
871
|
const cubeDbName = dbResult.message;
|
|
316
872
|
const configInstance = new import_core.Config();
|
|
317
|
-
const configFilePath =
|
|
873
|
+
const configFilePath = import_path3.default.resolve(process.cwd(), "dbcube.config.js");
|
|
318
874
|
const configFn = require(configFilePath);
|
|
319
875
|
if (typeof configFn === "function") {
|
|
320
876
|
configFn(configInstance);
|
|
@@ -341,7 +897,7 @@ var Schema = class {
|
|
|
341
897
|
return {
|
|
342
898
|
isValid: false,
|
|
343
899
|
error: {
|
|
344
|
-
itemName:
|
|
900
|
+
itemName: import_path3.default.basename(filePath, import_path3.default.extname(filePath)),
|
|
345
901
|
error: `Database configuration '${cubeDbName}' not found in dbcube.config.js. Available: ${availableText}`,
|
|
346
902
|
filePath,
|
|
347
903
|
lineNumber: this.findDatabaseLineNumber(filePath)
|
|
@@ -353,7 +909,7 @@ var Schema = class {
|
|
|
353
909
|
return {
|
|
354
910
|
isValid: false,
|
|
355
911
|
error: {
|
|
356
|
-
itemName:
|
|
912
|
+
itemName: import_path3.default.basename(filePath, import_path3.default.extname(filePath)),
|
|
357
913
|
error: `Database configuration validation failed: ${error.message}`,
|
|
358
914
|
filePath,
|
|
359
915
|
lineNumber: this.findDatabaseLineNumber(filePath)
|
|
@@ -366,7 +922,7 @@ var Schema = class {
|
|
|
366
922
|
*/
|
|
367
923
|
findDatabaseLineNumber(filePath) {
|
|
368
924
|
try {
|
|
369
|
-
const content =
|
|
925
|
+
const content = import_fs4.default.readFileSync(filePath, "utf8");
|
|
370
926
|
const lines = content.split("\n");
|
|
371
927
|
for (let i = 0; i < lines.length; i++) {
|
|
372
928
|
if (lines[i].includes("@database")) {
|
|
@@ -380,7 +936,7 @@ var Schema = class {
|
|
|
380
936
|
}
|
|
381
937
|
async createDatabase() {
|
|
382
938
|
const startTime = Date.now();
|
|
383
|
-
const rootPath =
|
|
939
|
+
const rootPath = import_path3.default.resolve(process.cwd());
|
|
384
940
|
UIUtils.showOperationHeader(" CREATING DATABASE", this.name, "\u{1F5C4}\uFE0F");
|
|
385
941
|
await UIUtils.showItemProgress("Preparando e instalando base de datos", 1, 1);
|
|
386
942
|
try {
|
|
@@ -424,28 +980,31 @@ var Schema = class {
|
|
|
424
980
|
}
|
|
425
981
|
async refreshTables() {
|
|
426
982
|
const startTime = Date.now();
|
|
427
|
-
const cubesDir =
|
|
428
|
-
if (!
|
|
983
|
+
const cubesDir = import_path3.default.join(process.cwd(), "dbcube", "cubes");
|
|
984
|
+
if (!import_fs4.default.existsSync(cubesDir)) {
|
|
429
985
|
throw new Error("\u274C The cubes folder does not exist");
|
|
430
986
|
}
|
|
431
987
|
const cubeFiles = FileUtils_default.getCubeFilesRecursively("dbcube", "table.cube");
|
|
432
988
|
if (cubeFiles.length === 0) {
|
|
433
989
|
throw new Error("\u274C There are no cubes to execute");
|
|
434
990
|
}
|
|
991
|
+
console.log("\u{1F504} Resolving table dependencies...");
|
|
992
|
+
DependencyResolver.resolveDependencies(cubeFiles, "table");
|
|
993
|
+
const orderedCubeFiles = DependencyResolver.orderCubeFiles(cubeFiles, "table");
|
|
435
994
|
UIUtils.showOperationHeader("EXECUTING REFRESH TABLES", this.name, "\u{1F504}");
|
|
436
995
|
let totalTablesProcessed = 0;
|
|
437
996
|
let successCount = 0;
|
|
438
997
|
let errorCount = 0;
|
|
439
998
|
const processedTables = [];
|
|
440
999
|
const errors = [];
|
|
441
|
-
for (let index = 0; index <
|
|
442
|
-
const file =
|
|
443
|
-
const filePath =
|
|
444
|
-
const stats =
|
|
1000
|
+
for (let index = 0; index < orderedCubeFiles.length; index++) {
|
|
1001
|
+
const file = orderedCubeFiles[index];
|
|
1002
|
+
const filePath = import_path3.default.isAbsolute(file) ? file : import_path3.default.join(cubesDir, file);
|
|
1003
|
+
const stats = import_fs4.default.statSync(filePath);
|
|
445
1004
|
if (stats.isFile()) {
|
|
446
1005
|
const getTableName = FileUtils_default.extracTableNameFromCube(filePath);
|
|
447
|
-
const tableName = getTableName.status === 200 ? getTableName.message :
|
|
448
|
-
await UIUtils.showItemProgress(tableName, index + 1,
|
|
1006
|
+
const tableName = getTableName.status === 200 ? getTableName.message : import_path3.default.basename(file, ".table.cube");
|
|
1007
|
+
await UIUtils.showItemProgress(tableName, index + 1, orderedCubeFiles.length);
|
|
449
1008
|
try {
|
|
450
1009
|
const validation = this.validateDatabaseConfiguration(filePath);
|
|
451
1010
|
if (!validation.isValid && validation.error) {
|
|
@@ -526,28 +1085,31 @@ var Schema = class {
|
|
|
526
1085
|
}
|
|
527
1086
|
async freshTables() {
|
|
528
1087
|
const startTime = Date.now();
|
|
529
|
-
const cubesDir =
|
|
530
|
-
if (!
|
|
1088
|
+
const cubesDir = import_path3.default.join(process.cwd(), "dbcube", "cubes");
|
|
1089
|
+
if (!import_fs4.default.existsSync(cubesDir)) {
|
|
531
1090
|
throw new Error("\u274C The cubes folder does not exist");
|
|
532
1091
|
}
|
|
533
1092
|
const cubeFiles = FileUtils_default.getCubeFilesRecursively("dbcube", "table.cube");
|
|
534
1093
|
if (cubeFiles.length === 0) {
|
|
535
1094
|
throw new Error("\u274C There are no cubes to execute");
|
|
536
1095
|
}
|
|
1096
|
+
console.log("\u{1F504} Resolving table dependencies...");
|
|
1097
|
+
DependencyResolver.resolveDependencies(cubeFiles, "table");
|
|
1098
|
+
const orderedCubeFiles = DependencyResolver.orderCubeFiles(cubeFiles, "table");
|
|
537
1099
|
UIUtils.showOperationHeader("EXECUTING FRESH TABLES", this.name);
|
|
538
1100
|
let totalTablesProcessed = 0;
|
|
539
1101
|
let successCount = 0;
|
|
540
1102
|
let errorCount = 0;
|
|
541
1103
|
const processedTables = [];
|
|
542
1104
|
const errors = [];
|
|
543
|
-
for (let index = 0; index <
|
|
544
|
-
const file =
|
|
545
|
-
const filePath =
|
|
546
|
-
const stats =
|
|
1105
|
+
for (let index = 0; index < orderedCubeFiles.length; index++) {
|
|
1106
|
+
const file = orderedCubeFiles[index];
|
|
1107
|
+
const filePath = import_path3.default.isAbsolute(file) ? file : import_path3.default.join(cubesDir, file);
|
|
1108
|
+
const stats = import_fs4.default.statSync(filePath);
|
|
547
1109
|
if (stats.isFile()) {
|
|
548
1110
|
const getTableName = FileUtils_default.extracTableNameFromCube(filePath);
|
|
549
|
-
const tableName = getTableName.status === 200 ? getTableName.message :
|
|
550
|
-
await UIUtils.showItemProgress(tableName, index + 1,
|
|
1111
|
+
const tableName = getTableName.status === 200 ? getTableName.message : import_path3.default.basename(file, ".table.cube");
|
|
1112
|
+
await UIUtils.showItemProgress(tableName, index + 1, orderedCubeFiles.length);
|
|
551
1113
|
try {
|
|
552
1114
|
const validation = this.validateDatabaseConfiguration(filePath);
|
|
553
1115
|
if (!validation.isValid && validation.error) {
|
|
@@ -626,28 +1188,29 @@ var Schema = class {
|
|
|
626
1188
|
}
|
|
627
1189
|
async executeSeeders() {
|
|
628
1190
|
const startTime = Date.now();
|
|
629
|
-
const cubesDir =
|
|
630
|
-
if (!
|
|
1191
|
+
const cubesDir = import_path3.default.join(process.cwd(), "dbcube", "cubes");
|
|
1192
|
+
if (!import_fs4.default.existsSync(cubesDir)) {
|
|
631
1193
|
throw new Error("\u274C The cubes folder does not exist");
|
|
632
1194
|
}
|
|
633
1195
|
const cubeFiles = FileUtils_default.getCubeFilesRecursively("dbcube", "seeder.cube");
|
|
634
1196
|
if (cubeFiles.length === 0) {
|
|
635
1197
|
throw new Error("\u274C There are no cubes to execute");
|
|
636
1198
|
}
|
|
1199
|
+
const orderedCubeFiles = DependencyResolver.orderCubeFiles(cubeFiles, "seeder");
|
|
637
1200
|
UIUtils.showOperationHeader("EXECUTING SEEDERS", this.name, "\u{1F331}");
|
|
638
1201
|
let totalSeedersProcessed = 0;
|
|
639
1202
|
let successCount = 0;
|
|
640
1203
|
let errorCount = 0;
|
|
641
1204
|
const processedSeeders = [];
|
|
642
1205
|
const errors = [];
|
|
643
|
-
for (let index = 0; index <
|
|
644
|
-
const file =
|
|
645
|
-
const filePath =
|
|
646
|
-
const stats =
|
|
1206
|
+
for (let index = 0; index < orderedCubeFiles.length; index++) {
|
|
1207
|
+
const file = orderedCubeFiles[index];
|
|
1208
|
+
const filePath = import_path3.default.isAbsolute(file) ? file : import_path3.default.join(cubesDir, file);
|
|
1209
|
+
const stats = import_fs4.default.statSync(filePath);
|
|
647
1210
|
if (stats.isFile()) {
|
|
648
1211
|
const getSeederName = FileUtils_default.extracTableNameFromCube(filePath);
|
|
649
|
-
const seederName = getSeederName.status === 200 ? getSeederName.message :
|
|
650
|
-
await UIUtils.showItemProgress(seederName, index + 1,
|
|
1212
|
+
const seederName = getSeederName.status === 200 ? getSeederName.message : import_path3.default.basename(file, ".seeder.cube");
|
|
1213
|
+
await UIUtils.showItemProgress(seederName, index + 1, orderedCubeFiles.length);
|
|
651
1214
|
try {
|
|
652
1215
|
const validation = this.validateDatabaseConfiguration(filePath);
|
|
653
1216
|
if (!validation.isValid && validation.error) {
|
|
@@ -697,9 +1260,9 @@ var Schema = class {
|
|
|
697
1260
|
}
|
|
698
1261
|
async executeTriggers() {
|
|
699
1262
|
const startTime = Date.now();
|
|
700
|
-
const cubesDir =
|
|
701
|
-
const triggersDirExit =
|
|
702
|
-
if (!
|
|
1263
|
+
const cubesDir = import_path3.default.join(process.cwd(), "dbcube", "cubes");
|
|
1264
|
+
const triggersDirExit = import_path3.default.join(process.cwd(), "dbcube", "triggers");
|
|
1265
|
+
if (!import_fs4.default.existsSync(cubesDir)) {
|
|
703
1266
|
throw new Error("\u274C The cubes folder does not exist");
|
|
704
1267
|
}
|
|
705
1268
|
const cubeFiles = FileUtils_default.getCubeFilesRecursively("dbcube", "trigger.cube");
|
|
@@ -714,11 +1277,11 @@ var Schema = class {
|
|
|
714
1277
|
const errors = [];
|
|
715
1278
|
for (let index = 0; index < cubeFiles.length; index++) {
|
|
716
1279
|
const file = cubeFiles[index];
|
|
717
|
-
const filePath =
|
|
718
|
-
const stats =
|
|
1280
|
+
const filePath = import_path3.default.isAbsolute(file) ? file : import_path3.default.join(cubesDir, file);
|
|
1281
|
+
const stats = import_fs4.default.statSync(filePath);
|
|
719
1282
|
if (stats.isFile()) {
|
|
720
1283
|
const getTriggerName = FileUtils_default.extracTableNameFromCube(filePath);
|
|
721
|
-
const triggerName = getTriggerName.status === 200 ? getTriggerName.message :
|
|
1284
|
+
const triggerName = getTriggerName.status === 200 ? getTriggerName.message : import_path3.default.basename(file, ".trigger.cube");
|
|
722
1285
|
await UIUtils.showItemProgress(triggerName, index + 1, cubeFiles.length);
|
|
723
1286
|
try {
|
|
724
1287
|
const validation = this.validateDatabaseConfiguration(filePath);
|
|
@@ -789,7 +1352,7 @@ ${import_chalk2.default.red("\u{1F6AB}")} ${import_chalk2.default.bold.red("ERRO
|
|
|
789
1352
|
const errorLocation = `${filePath}:${lineStr}:${columnStr}`;
|
|
790
1353
|
console.log(`${import_chalk2.default.cyan("[code]")} ${import_chalk2.default.yellow(errorLocation)}`);
|
|
791
1354
|
try {
|
|
792
|
-
const codeLines =
|
|
1355
|
+
const codeLines = import_fs4.default.readFileSync(filePath, "utf-8").split("\n");
|
|
793
1356
|
const start = Math.max(0, lineNum - 3);
|
|
794
1357
|
const end = Math.min(codeLines.length, lineNum + 2);
|
|
795
1358
|
for (let i = start; i < end; i++) {
|
|
@@ -803,6 +1366,7 @@ ${import_chalk2.default.red("\u{1F6AB}")} ${import_chalk2.default.bold.red("ERRO
|
|
|
803
1366
|
}
|
|
804
1367
|
}
|
|
805
1368
|
}
|
|
1369
|
+
console.log("");
|
|
806
1370
|
process.exit(1);
|
|
807
1371
|
}
|
|
808
1372
|
|
|
@@ -810,6 +1374,9 @@ ${import_chalk2.default.red("\u{1F6AB}")} ${import_chalk2.default.bold.red("ERRO
|
|
|
810
1374
|
var index_default = Schema;
|
|
811
1375
|
// Annotate the CommonJS export names for ESM import in node:
|
|
812
1376
|
0 && (module.exports = {
|
|
813
|
-
|
|
1377
|
+
CubeValidator,
|
|
1378
|
+
DependencyResolver,
|
|
1379
|
+
Schema,
|
|
1380
|
+
UIUtils
|
|
814
1381
|
});
|
|
815
1382
|
//# sourceMappingURL=index.cjs.map
|