@dbcube/schema-builder 1.0.14 → 1.0.16

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 CHANGED
@@ -36,7 +36,7 @@ __export(index_exports, {
36
36
  module.exports = __toCommonJS(index_exports);
37
37
 
38
38
  // src/lib/Schema.ts
39
- var import_fs = __toESM(require("fs"));
39
+ var import_fs2 = __toESM(require("fs"));
40
40
  var import_core = require("@dbcube/core");
41
41
  var import_path = __toESM(require("path"));
42
42
 
@@ -162,9 +162,13 @@ var FileUtils = class {
162
162
  };
163
163
  var FileUtils_default = FileUtils;
164
164
 
165
+ // src/lib/Schema.ts
166
+ var import_chalk2 = __toESM(require("chalk"));
167
+
165
168
  // src/lib/UIUtils.ts
166
169
  var import_chalk = __toESM(require("chalk"));
167
- var UIUtils = class {
170
+ var import_fs = __toESM(require("fs"));
171
+ var UIUtils = class _UIUtils {
168
172
  /**
169
173
  * Shows animated progress for processing items
170
174
  */
@@ -196,12 +200,11 @@ var UIUtils = class {
196
200
  `);
197
201
  }
198
202
  /**
199
- * Shows error for an item
203
+ * Shows error for an item (simplified - only shows X)
200
204
  */
201
205
  static showItemError(itemName, error) {
202
- process.stdout.write(` ${import_chalk.default.red("\u2717")} ${import_chalk.default.red("ERROR")}
206
+ process.stdout.write(` ${import_chalk.default.red("\u2717")}
203
207
  `);
204
- console.log(`${import_chalk.default.red("\u2502 ")} ${import_chalk.default.gray("\u2514\u2500")} ${import_chalk.default.red(error)}`);
205
208
  }
206
209
  /**
207
210
  * Shows operation header
@@ -239,6 +242,46 @@ ${import_chalk.default.cyan("\u{1F4CA}")} ${import_chalk.default.bold.green(`SUM
239
242
  }
240
243
  console.log(`${import_chalk.default.blue("\u251C\u2500")} ${import_chalk.default.gray(`Total time: ${totalTime}s`)}`);
241
244
  console.log(`${import_chalk.default.blue("\u2514\u2500")} ${import_chalk.default.bold(totalProcessed > 0 ? import_chalk.default.green("\u2705 Completed") : import_chalk.default.yellow("\u26A0\uFE0F No changes"))}`);
245
+ if (summary.errors && summary.errors.length > 0) {
246
+ console.log(`
247
+ ${import_chalk.default.red("\u{1F6AB}")} ${import_chalk.default.bold.red("ERRORS FOUND")}`);
248
+ console.log(import_chalk.default.red("\u2500".repeat(60)));
249
+ summary.errors.forEach((error, index) => {
250
+ console.log(`${import_chalk.default.red("[error]")} ${import_chalk.default.red(error.error)}`);
251
+ console.log("");
252
+ if (error.filePath) {
253
+ const location = error.lineNumber ? `${error.filePath}:${error.lineNumber}:7` : error.filePath;
254
+ console.log(`${import_chalk.default.cyan("[code]")} ${import_chalk.default.yellow(location)}`);
255
+ _UIUtils.showCodeContext(error.filePath, error.lineNumber || 1);
256
+ }
257
+ if (index < summary.errors.length - 1) {
258
+ console.log("");
259
+ }
260
+ });
261
+ }
262
+ }
263
+ /**
264
+ * Shows code context around an error location
265
+ */
266
+ static showCodeContext(filePath, lineNumber, contextLines = 2) {
267
+ try {
268
+ const content = import_fs.default.readFileSync(filePath, "utf8");
269
+ const lines = content.split("\n");
270
+ const startLine = Math.max(0, lineNumber - contextLines - 1);
271
+ const endLine = Math.min(lines.length, lineNumber + contextLines);
272
+ for (let i = startLine; i < endLine; i++) {
273
+ const currentLineNum = i + 1;
274
+ const line = lines[i];
275
+ const lineNumStr = currentLineNum.toString().padStart(4, " ");
276
+ if (currentLineNum === lineNumber) {
277
+ console.log(`${import_chalk.default.gray(lineNumStr)} ${import_chalk.default.red("<-")} ${import_chalk.default.white(line)}`);
278
+ } else {
279
+ console.log(`${import_chalk.default.gray(lineNumStr)} ${import_chalk.default.white(line)}`);
280
+ }
281
+ }
282
+ } catch (error) {
283
+ console.log(import_chalk.default.gray(" (unable to show code context)"));
284
+ }
242
285
  }
243
286
  };
244
287
 
@@ -259,7 +302,15 @@ var Schema = class {
259
302
  try {
260
303
  const dbResult = FileUtils_default.extractDatabaseNameFromCube(filePath);
261
304
  if (dbResult.status !== 200) {
262
- throw new Error(`Error reading database directive from ${filePath}: ${dbResult.message}`);
305
+ return {
306
+ isValid: false,
307
+ error: {
308
+ itemName: import_path.default.basename(filePath, import_path.default.extname(filePath)),
309
+ error: `Error reading database directive: ${dbResult.message}`,
310
+ filePath,
311
+ lineNumber: this.findDatabaseLineNumber(filePath)
312
+ }
313
+ };
263
314
  }
264
315
  const cubeDbName = dbResult.message;
265
316
  const configInstance = new import_core.Config();
@@ -287,13 +338,44 @@ var Schema = class {
287
338
  } catch (e) {
288
339
  }
289
340
  const availableText = availableDbs.length > 0 ? availableDbs.join(", ") : "none found";
290
- throw new Error(`\u274C Database configuration '${cubeDbName}' from cube file '${import_path.default.basename(filePath)}' not found in dbcube.config.js.
291
-
292
- Available databases: ${availableText}`);
341
+ return {
342
+ isValid: false,
343
+ error: {
344
+ itemName: import_path.default.basename(filePath, import_path.default.extname(filePath)),
345
+ error: `Database configuration '${cubeDbName}' not found in dbcube.config.js. Available: ${availableText}`,
346
+ filePath,
347
+ lineNumber: this.findDatabaseLineNumber(filePath)
348
+ }
349
+ };
293
350
  }
294
- return true;
351
+ return { isValid: true };
295
352
  } catch (error) {
296
- throw new Error(`Database configuration validation failed: ${error.message}`);
353
+ return {
354
+ isValid: false,
355
+ error: {
356
+ itemName: import_path.default.basename(filePath, import_path.default.extname(filePath)),
357
+ error: `Database configuration validation failed: ${error.message}`,
358
+ filePath,
359
+ lineNumber: this.findDatabaseLineNumber(filePath)
360
+ }
361
+ };
362
+ }
363
+ }
364
+ /**
365
+ * Finds the line number where @database directive is located
366
+ */
367
+ findDatabaseLineNumber(filePath) {
368
+ try {
369
+ const content = import_fs2.default.readFileSync(filePath, "utf8");
370
+ const lines = content.split("\n");
371
+ for (let i = 0; i < lines.length; i++) {
372
+ if (lines[i].includes("@database")) {
373
+ return i + 1;
374
+ }
375
+ }
376
+ return 1;
377
+ } catch {
378
+ return 1;
297
379
  }
298
380
  }
299
381
  async createDatabase() {
@@ -319,7 +401,8 @@ Available databases: ${availableText}`);
319
401
  errorCount: 0,
320
402
  processedItems: [this.name],
321
403
  operationName: "create database",
322
- databaseName: this.name
404
+ databaseName: this.name,
405
+ errors: []
323
406
  };
324
407
  UIUtils.showOperationSummary(summary);
325
408
  return response.data;
@@ -332,7 +415,8 @@ Available databases: ${availableText}`);
332
415
  errorCount: 1,
333
416
  processedItems: [],
334
417
  operationName: "create database",
335
- databaseName: this.name
418
+ databaseName: this.name,
419
+ errors: []
336
420
  };
337
421
  UIUtils.showOperationSummary(summary);
338
422
  throw error;
@@ -341,7 +425,7 @@ Available databases: ${availableText}`);
341
425
  async refreshTables() {
342
426
  const startTime = Date.now();
343
427
  const cubesDir = import_path.default.join(process.cwd(), "dbcube", "cubes");
344
- if (!import_fs.default.existsSync(cubesDir)) {
428
+ if (!import_fs2.default.existsSync(cubesDir)) {
345
429
  throw new Error("\u274C The cubes folder does not exist");
346
430
  }
347
431
  const cubeFiles = FileUtils_default.getCubeFilesRecursively("dbcube", "table.cube");
@@ -353,16 +437,23 @@ Available databases: ${availableText}`);
353
437
  let successCount = 0;
354
438
  let errorCount = 0;
355
439
  const processedTables = [];
440
+ const errors = [];
356
441
  for (let index = 0; index < cubeFiles.length; index++) {
357
442
  const file = cubeFiles[index];
358
443
  const filePath = import_path.default.isAbsolute(file) ? file : import_path.default.join(cubesDir, file);
359
- const stats = import_fs.default.statSync(filePath);
444
+ const stats = import_fs2.default.statSync(filePath);
360
445
  if (stats.isFile()) {
361
446
  const getTableName = FileUtils_default.extracTableNameFromCube(filePath);
362
447
  const tableName = getTableName.status === 200 ? getTableName.message : import_path.default.basename(file, ".table.cube");
363
448
  await UIUtils.showItemProgress(tableName, index + 1, cubeFiles.length);
364
449
  try {
365
- this.validateDatabaseConfiguration(filePath);
450
+ const validation = this.validateDatabaseConfiguration(filePath);
451
+ if (!validation.isValid && validation.error) {
452
+ UIUtils.showItemError(tableName, validation.error.error);
453
+ errors.push(validation.error);
454
+ errorCount++;
455
+ continue;
456
+ }
366
457
  const dml = await this.engine.run("schema_engine", [
367
458
  "--action",
368
459
  "parse_table",
@@ -409,7 +500,13 @@ Available databases: ${availableText}`);
409
500
  processedTables.push(tableName);
410
501
  totalTablesProcessed++;
411
502
  } catch (error) {
503
+ const processError = {
504
+ itemName: tableName,
505
+ error: error.message,
506
+ filePath
507
+ };
412
508
  UIUtils.showItemError(tableName, error.message);
509
+ errors.push(processError);
413
510
  errorCount++;
414
511
  }
415
512
  }
@@ -421,7 +518,8 @@ Available databases: ${availableText}`);
421
518
  errorCount,
422
519
  processedItems: processedTables,
423
520
  operationName: "refresh tables",
424
- databaseName: this.name
521
+ databaseName: this.name,
522
+ errors
425
523
  };
426
524
  UIUtils.showOperationSummary(summary);
427
525
  return totalTablesProcessed > 0 ? { processed: totalTablesProcessed, success: successCount, errors: errorCount } : null;
@@ -429,7 +527,7 @@ Available databases: ${availableText}`);
429
527
  async freshTables() {
430
528
  const startTime = Date.now();
431
529
  const cubesDir = import_path.default.join(process.cwd(), "dbcube", "cubes");
432
- if (!import_fs.default.existsSync(cubesDir)) {
530
+ if (!import_fs2.default.existsSync(cubesDir)) {
433
531
  throw new Error("\u274C The cubes folder does not exist");
434
532
  }
435
533
  const cubeFiles = FileUtils_default.getCubeFilesRecursively("dbcube", "table.cube");
@@ -441,16 +539,23 @@ Available databases: ${availableText}`);
441
539
  let successCount = 0;
442
540
  let errorCount = 0;
443
541
  const processedTables = [];
542
+ const errors = [];
444
543
  for (let index = 0; index < cubeFiles.length; index++) {
445
544
  const file = cubeFiles[index];
446
545
  const filePath = import_path.default.isAbsolute(file) ? file : import_path.default.join(cubesDir, file);
447
- const stats = import_fs.default.statSync(filePath);
546
+ const stats = import_fs2.default.statSync(filePath);
448
547
  if (stats.isFile()) {
449
548
  const getTableName = FileUtils_default.extracTableNameFromCube(filePath);
450
549
  const tableName = getTableName.status === 200 ? getTableName.message : import_path.default.basename(file, ".table.cube");
451
550
  await UIUtils.showItemProgress(tableName, index + 1, cubeFiles.length);
452
551
  try {
453
- this.validateDatabaseConfiguration(filePath);
552
+ const validation = this.validateDatabaseConfiguration(filePath);
553
+ if (!validation.isValid && validation.error) {
554
+ UIUtils.showItemError(tableName, validation.error.error);
555
+ errors.push(validation.error);
556
+ errorCount++;
557
+ continue;
558
+ }
454
559
  const dml = await this.engine.run("schema_engine", [
455
560
  "--action",
456
561
  "parse_table",
@@ -495,7 +600,13 @@ Available databases: ${availableText}`);
495
600
  processedTables.push(tableName);
496
601
  totalTablesProcessed++;
497
602
  } catch (error) {
603
+ const processError = {
604
+ itemName: tableName,
605
+ error: error.message,
606
+ filePath
607
+ };
498
608
  UIUtils.showItemError(tableName, error.message);
609
+ errors.push(processError);
499
610
  errorCount++;
500
611
  }
501
612
  }
@@ -507,7 +618,8 @@ Available databases: ${availableText}`);
507
618
  errorCount,
508
619
  processedItems: processedTables,
509
620
  operationName: "fresh tables",
510
- databaseName: this.name
621
+ databaseName: this.name,
622
+ errors
511
623
  };
512
624
  UIUtils.showOperationSummary(summary);
513
625
  return totalTablesProcessed > 0 ? { processed: totalTablesProcessed, success: successCount, errors: errorCount } : null;
@@ -515,7 +627,7 @@ Available databases: ${availableText}`);
515
627
  async executeSeeders() {
516
628
  const startTime = Date.now();
517
629
  const cubesDir = import_path.default.join(process.cwd(), "dbcube", "cubes");
518
- if (!import_fs.default.existsSync(cubesDir)) {
630
+ if (!import_fs2.default.existsSync(cubesDir)) {
519
631
  throw new Error("\u274C The cubes folder does not exist");
520
632
  }
521
633
  const cubeFiles = FileUtils_default.getCubeFilesRecursively("dbcube", "seeder.cube");
@@ -527,16 +639,23 @@ Available databases: ${availableText}`);
527
639
  let successCount = 0;
528
640
  let errorCount = 0;
529
641
  const processedSeeders = [];
642
+ const errors = [];
530
643
  for (let index = 0; index < cubeFiles.length; index++) {
531
644
  const file = cubeFiles[index];
532
645
  const filePath = import_path.default.isAbsolute(file) ? file : import_path.default.join(cubesDir, file);
533
- const stats = import_fs.default.statSync(filePath);
646
+ const stats = import_fs2.default.statSync(filePath);
534
647
  if (stats.isFile()) {
535
648
  const getSeederName = FileUtils_default.extracTableNameFromCube(filePath);
536
649
  const seederName = getSeederName.status === 200 ? getSeederName.message : import_path.default.basename(file, ".seeder.cube");
537
650
  await UIUtils.showItemProgress(seederName, index + 1, cubeFiles.length);
538
651
  try {
539
- this.validateDatabaseConfiguration(filePath);
652
+ const validation = this.validateDatabaseConfiguration(filePath);
653
+ if (!validation.isValid && validation.error) {
654
+ UIUtils.showItemError(seederName, validation.error.error);
655
+ errors.push(validation.error);
656
+ errorCount++;
657
+ continue;
658
+ }
540
659
  const response = await this.engine.run("schema_engine", [
541
660
  "--action",
542
661
  "seeder",
@@ -552,7 +671,13 @@ Available databases: ${availableText}`);
552
671
  processedSeeders.push(seederName);
553
672
  totalSeedersProcessed++;
554
673
  } catch (error) {
674
+ const processError = {
675
+ itemName: seederName,
676
+ error: error.message,
677
+ filePath
678
+ };
555
679
  UIUtils.showItemError(seederName, error.message);
680
+ errors.push(processError);
556
681
  errorCount++;
557
682
  }
558
683
  }
@@ -564,7 +689,8 @@ Available databases: ${availableText}`);
564
689
  errorCount,
565
690
  processedItems: processedSeeders,
566
691
  operationName: "seeders",
567
- databaseName: this.name
692
+ databaseName: this.name,
693
+ errors
568
694
  };
569
695
  UIUtils.showOperationSummary(summary);
570
696
  return totalSeedersProcessed > 0 ? { processed: totalSeedersProcessed, success: successCount, errors: errorCount } : null;
@@ -573,7 +699,7 @@ Available databases: ${availableText}`);
573
699
  const startTime = Date.now();
574
700
  const cubesDir = import_path.default.join(process.cwd(), "dbcube", "cubes");
575
701
  const triggersDirExit = import_path.default.join(process.cwd(), "dbcube", "triggers");
576
- if (!import_fs.default.existsSync(cubesDir)) {
702
+ if (!import_fs2.default.existsSync(cubesDir)) {
577
703
  throw new Error("\u274C The cubes folder does not exist");
578
704
  }
579
705
  const cubeFiles = FileUtils_default.getCubeFilesRecursively("dbcube", "trigger.cube");
@@ -585,16 +711,23 @@ Available databases: ${availableText}`);
585
711
  let successCount = 0;
586
712
  let errorCount = 0;
587
713
  const processedTriggers = [];
714
+ const errors = [];
588
715
  for (let index = 0; index < cubeFiles.length; index++) {
589
716
  const file = cubeFiles[index];
590
717
  const filePath = import_path.default.isAbsolute(file) ? file : import_path.default.join(cubesDir, file);
591
- const stats = import_fs.default.statSync(filePath);
718
+ const stats = import_fs2.default.statSync(filePath);
592
719
  if (stats.isFile()) {
593
720
  const getTriggerName = FileUtils_default.extracTableNameFromCube(filePath);
594
721
  const triggerName = getTriggerName.status === 200 ? getTriggerName.message : import_path.default.basename(file, ".trigger.cube");
595
722
  await UIUtils.showItemProgress(triggerName, index + 1, cubeFiles.length);
596
723
  try {
597
- this.validateDatabaseConfiguration(filePath);
724
+ const validation = this.validateDatabaseConfiguration(filePath);
725
+ if (!validation.isValid && validation.error) {
726
+ UIUtils.showItemError(triggerName, validation.error.error);
727
+ errors.push(validation.error);
728
+ errorCount++;
729
+ continue;
730
+ }
598
731
  const response = await this.engine.run("schema_engine", [
599
732
  "--action",
600
733
  "trigger",
@@ -612,7 +745,13 @@ Available databases: ${availableText}`);
612
745
  processedTriggers.push(triggerName);
613
746
  totalTriggersProcessed++;
614
747
  } catch (error) {
748
+ const processError = {
749
+ itemName: triggerName,
750
+ error: error.message,
751
+ filePath
752
+ };
615
753
  UIUtils.showItemError(triggerName, error.message);
754
+ errors.push(processError);
616
755
  errorCount++;
617
756
  }
618
757
  }
@@ -624,36 +763,19 @@ Available databases: ${availableText}`);
624
763
  errorCount,
625
764
  processedItems: processedTriggers,
626
765
  operationName: "triggers",
627
- databaseName: this.name
766
+ databaseName: this.name,
767
+ errors
628
768
  };
629
769
  UIUtils.showOperationSummary(summary);
630
770
  return totalTriggersProcessed > 0 ? { processed: totalTriggersProcessed, success: successCount, errors: errorCount } : null;
631
771
  }
632
772
  };
633
773
  function returnFormattedError(status, message) {
634
- const RESET = "\x1B[0m";
635
- const RED = "\x1B[31m";
636
- const YELLOW = "\x1B[33m";
637
- const BOLD = "\x1B[1m";
638
- const CYAN = "\x1B[36m";
639
- const GRAY = "\x1B[90m";
640
- const UNDERLINE = "\x1B[4m";
641
- const MAGENTA = "\x1B[35m";
642
- let output = "";
643
- let help = "";
644
- const color = status === 600 ? YELLOW : RED;
645
- if (message.includes("[help]")) {
646
- const parts = message.split("[help]");
647
- output += `
648
- ${RED}${BOLD}${parts[0]}${RESET}`;
649
- help += `
650
- ${MAGENTA}${BOLD}[help]${RESET} ${GRAY}${parts[1]}${RESET}
651
- `;
652
- } else {
653
- output += `
654
- ${color}${BOLD}${message}${RESET}
655
- `;
656
- }
774
+ console.log(`
775
+ ${import_chalk2.default.red("\u{1F6AB}")} ${import_chalk2.default.bold.red("ERRORS FOUND")}`);
776
+ console.log(import_chalk2.default.red("\u2500".repeat(60)));
777
+ console.log(`${import_chalk2.default.red("[error]")} ${import_chalk2.default.red(message)}`);
778
+ console.log("");
657
779
  const err = new Error();
658
780
  const stackLines = err.stack?.split("\n") || [];
659
781
  const relevantStackLine = stackLines.find(
@@ -665,32 +787,22 @@ ${color}${BOLD}${message}${RESET}
665
787
  const [, filePath, lineStr, columnStr] = match;
666
788
  const lineNum = parseInt(lineStr, 10);
667
789
  const errorLocation = `${filePath}:${lineStr}:${columnStr}`;
790
+ console.log(`${import_chalk2.default.cyan("[code]")} ${import_chalk2.default.yellow(errorLocation)}`);
668
791
  try {
669
- const codeLines = import_fs.default.readFileSync(filePath, "utf-8").split("\n");
792
+ const codeLines = import_fs2.default.readFileSync(filePath, "utf-8").split("\n");
670
793
  const start = Math.max(0, lineNum - 3);
671
794
  const end = Math.min(codeLines.length, lineNum + 2);
672
- output += `
673
- ${CYAN}${BOLD}[code] ${RESET}${YELLOW} ${UNDERLINE}${errorLocation}${RESET}
674
- `;
675
795
  for (let i = start; i < end; i++) {
676
796
  const line = codeLines[i];
677
797
  const lineLabel = `${i + 1}`.padStart(4, " ");
678
- const pointer = i + 1 === lineNum ? `${RED}<-${RESET}` : " ";
679
- output += `${GRAY}${lineLabel}${RESET} ${pointer} ${line}
680
- `;
798
+ const pointer = i + 1 === lineNum ? `${import_chalk2.default.red("<-")}` : " ";
799
+ console.log(`${import_chalk2.default.gray(lineLabel)} ${pointer} ${import_chalk2.default.white(line)}`);
681
800
  }
682
801
  } catch (err2) {
683
- output += `${YELLOW}\u26A0\uFE0F No se pudo leer el archivo de origen: ${filePath}${RESET}
684
- `;
685
- output += `
686
- ${CYAN}${BOLD}Stack Trace:${RESET}
687
- ${stackLines.slice(2).join("\n")}
688
- `;
802
+ console.log(import_chalk2.default.gray(" (unable to show code context)"));
689
803
  }
690
804
  }
691
805
  }
692
- output += help;
693
- console.error(output);
694
806
  process.exit(1);
695
807
  }
696
808