@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.js
CHANGED
|
@@ -6,9 +6,9 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
6
6
|
});
|
|
7
7
|
|
|
8
8
|
// src/lib/Schema.ts
|
|
9
|
-
import
|
|
9
|
+
import fs4 from "fs";
|
|
10
10
|
import { Engine, TableProcessor, Config as ConfigClass } from "@dbcube/core";
|
|
11
|
-
import
|
|
11
|
+
import path3 from "path";
|
|
12
12
|
|
|
13
13
|
// src/lib/FileUtils.ts
|
|
14
14
|
import * as fs from "fs";
|
|
@@ -132,9 +132,13 @@ var FileUtils = class {
|
|
|
132
132
|
};
|
|
133
133
|
var FileUtils_default = FileUtils;
|
|
134
134
|
|
|
135
|
+
// src/lib/Schema.ts
|
|
136
|
+
import chalk2 from "chalk";
|
|
137
|
+
|
|
135
138
|
// src/lib/UIUtils.ts
|
|
136
139
|
import chalk from "chalk";
|
|
137
|
-
|
|
140
|
+
import fs2 from "fs";
|
|
141
|
+
var UIUtils = class _UIUtils {
|
|
138
142
|
/**
|
|
139
143
|
* Shows animated progress for processing items
|
|
140
144
|
*/
|
|
@@ -213,20 +217,349 @@ ${chalk.cyan("\u{1F4CA}")} ${chalk.bold.green(`SUMMARY OF ${operationName.toUppe
|
|
|
213
217
|
${chalk.red("\u{1F6AB}")} ${chalk.bold.red("ERRORS FOUND")}`);
|
|
214
218
|
console.log(chalk.red("\u2500".repeat(60)));
|
|
215
219
|
summary.errors.forEach((error, index) => {
|
|
216
|
-
console.log(`${chalk.red("
|
|
217
|
-
console.log(
|
|
220
|
+
console.log(`${chalk.red("[error]")} ${chalk.red(error.error)}`);
|
|
221
|
+
console.log("");
|
|
218
222
|
if (error.filePath) {
|
|
219
|
-
const
|
|
220
|
-
|
|
221
|
-
|
|
223
|
+
const location = error.lineNumber ? `${error.filePath}:${error.lineNumber}:7` : error.filePath;
|
|
224
|
+
console.log(`${chalk.cyan("[code]")} ${chalk.yellow(location)}`);
|
|
225
|
+
_UIUtils.showCodeContext(error.filePath, error.lineNumber || 1);
|
|
222
226
|
}
|
|
223
227
|
if (index < summary.errors.length - 1) {
|
|
224
|
-
console.log(
|
|
228
|
+
console.log("");
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Shows code context around an error location
|
|
235
|
+
*/
|
|
236
|
+
static showCodeContext(filePath, lineNumber, contextLines = 2) {
|
|
237
|
+
try {
|
|
238
|
+
const content = fs2.readFileSync(filePath, "utf8");
|
|
239
|
+
const lines = content.split("\n");
|
|
240
|
+
const startLine = Math.max(0, lineNumber - contextLines - 1);
|
|
241
|
+
const endLine = Math.min(lines.length, lineNumber + contextLines);
|
|
242
|
+
for (let i = startLine; i < endLine; i++) {
|
|
243
|
+
const currentLineNum = i + 1;
|
|
244
|
+
const line = lines[i];
|
|
245
|
+
const lineNumStr = currentLineNum.toString().padStart(4, " ");
|
|
246
|
+
if (currentLineNum === lineNumber) {
|
|
247
|
+
console.log(`${chalk.gray(lineNumStr)} ${chalk.red("<-")} ${chalk.white(line)}`);
|
|
248
|
+
} else {
|
|
249
|
+
console.log(`${chalk.gray(lineNumStr)} ${chalk.white(line)}`);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
} catch (error) {
|
|
253
|
+
console.log(chalk.gray(" (unable to show code context)"));
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
// src/lib/CubeValidator.ts
|
|
259
|
+
import fs3 from "fs";
|
|
260
|
+
import path2 from "path";
|
|
261
|
+
var CubeValidator = class {
|
|
262
|
+
validTypes = ["varchar", "int", "string", "text", "boolean", "date", "datetime", "timestamp", "decimal", "float", "double", "enum", "json"];
|
|
263
|
+
validOptions = ["not null", "primary", "autoincrement", "unique", "zerofill", "index", "required", "unsigned"];
|
|
264
|
+
validProperties = ["type", "length", "options", "value", "defaultValue", "foreign", "enumValues", "description"];
|
|
265
|
+
knownAnnotations = ["database", "table", "meta", "columns", "fields", "dataset", "beforeAdd", "afterAdd", "beforeUpdate", "afterUpdate", "beforeDelete", "afterDelete", "compute", "column"];
|
|
266
|
+
/**
|
|
267
|
+
* Validates a cube file comprehensively
|
|
268
|
+
*/
|
|
269
|
+
validateCubeFile(filePath) {
|
|
270
|
+
const errors = [];
|
|
271
|
+
try {
|
|
272
|
+
const content = fs3.readFileSync(filePath, "utf8");
|
|
273
|
+
const lines = content.split("\n");
|
|
274
|
+
const fileName = path2.basename(filePath, path2.extname(filePath));
|
|
275
|
+
for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {
|
|
276
|
+
const line = lines[lineIndex];
|
|
277
|
+
if (line.trim() === "" || line.trim().startsWith("//")) {
|
|
278
|
+
continue;
|
|
279
|
+
}
|
|
280
|
+
this.validateAnnotations(line, lineIndex + 1, filePath, fileName, errors);
|
|
281
|
+
this.validateDataTypes(line, lineIndex + 1, filePath, fileName, errors, content);
|
|
282
|
+
this.validateColumnOptions(line, lineIndex + 1, filePath, fileName, errors, lines);
|
|
283
|
+
this.validateColumnProperties(line, lineIndex + 1, filePath, fileName, errors, content);
|
|
284
|
+
this.validateRequiredColumnProperties(lines, lineIndex + 1, filePath, fileName, errors);
|
|
285
|
+
this.validateGeneralSyntax(line, lineIndex + 1, filePath, fileName, errors);
|
|
286
|
+
}
|
|
287
|
+
this.validateOverallStructure(content, filePath, fileName, errors);
|
|
288
|
+
} catch (error) {
|
|
289
|
+
errors.push({
|
|
290
|
+
itemName: path2.basename(filePath, path2.extname(filePath)),
|
|
291
|
+
error: `Failed to read cube file: ${error.message}`,
|
|
292
|
+
filePath,
|
|
293
|
+
lineNumber: 1
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
return {
|
|
297
|
+
isValid: errors.length === 0,
|
|
298
|
+
errors
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
validateAnnotations(line, lineNumber, filePath, fileName, errors) {
|
|
302
|
+
const annotationRegex = /@(\w+)/g;
|
|
303
|
+
let match;
|
|
304
|
+
while ((match = annotationRegex.exec(line)) !== null) {
|
|
305
|
+
const annotation = match[1];
|
|
306
|
+
if (!this.knownAnnotations.includes(annotation)) {
|
|
307
|
+
errors.push({
|
|
308
|
+
itemName: fileName,
|
|
309
|
+
error: `Unknown annotation '@${annotation}'. Valid annotations: ${this.knownAnnotations.join(", ")}`,
|
|
310
|
+
filePath,
|
|
311
|
+
lineNumber
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
validateDataTypes(line, lineNumber, filePath, fileName, errors, content) {
|
|
317
|
+
const typeRegex = /type:\s*["'](\w+)["']/g;
|
|
318
|
+
let match;
|
|
319
|
+
while ((match = typeRegex.exec(line)) !== null) {
|
|
320
|
+
const type = match[1];
|
|
321
|
+
if (!this.validTypes.includes(type)) {
|
|
322
|
+
errors.push({
|
|
323
|
+
itemName: fileName,
|
|
324
|
+
error: `Invalid data type '${type}'. Valid types: ${this.validTypes.join(", ")}`,
|
|
325
|
+
filePath,
|
|
326
|
+
lineNumber
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
if (line.includes('type: "varchar"')) {
|
|
331
|
+
const lines = content.split("\n");
|
|
332
|
+
const hasLengthNearby = lines.slice(Math.max(0, lineNumber - 1), Math.min(lineNumber + 4, lines.length)).some((nextLine) => nextLine.includes("length:"));
|
|
333
|
+
if (!hasLengthNearby) {
|
|
334
|
+
errors.push({
|
|
335
|
+
itemName: fileName,
|
|
336
|
+
error: "VARCHAR type requires a length specification",
|
|
337
|
+
filePath,
|
|
338
|
+
lineNumber
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
validateColumnOptions(line, lineNumber, filePath, fileName, errors, lines) {
|
|
344
|
+
const optionsMatch = line.match(/^\s*options\s*:\s*\[(.*)\]\s*;?\s*$/);
|
|
345
|
+
if (!optionsMatch) return;
|
|
346
|
+
const optionsContent = optionsMatch[1].trim();
|
|
347
|
+
const invalidSyntaxMatch = optionsContent.match(/[^",\s]+(?![^"]*")/);
|
|
348
|
+
if (invalidSyntaxMatch) {
|
|
349
|
+
errors.push({
|
|
350
|
+
itemName: fileName,
|
|
351
|
+
error: `Invalid syntax '${invalidSyntaxMatch[0]}' in options array. All values must be quoted strings`,
|
|
352
|
+
filePath,
|
|
353
|
+
lineNumber
|
|
354
|
+
});
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
357
|
+
const optionMatches = optionsContent.match(/"([^"]*)"/g);
|
|
358
|
+
if (optionMatches) {
|
|
359
|
+
const columnType = this.getColumnTypeForOptions(lines, lineNumber - 1);
|
|
360
|
+
optionMatches.forEach((optionMatch) => {
|
|
361
|
+
const option = optionMatch.replace(/"/g, "");
|
|
362
|
+
if (option.trim() === "") {
|
|
363
|
+
errors.push({
|
|
364
|
+
itemName: fileName,
|
|
365
|
+
error: "Empty option found in options array. All options must have a value",
|
|
366
|
+
filePath,
|
|
367
|
+
lineNumber
|
|
368
|
+
});
|
|
369
|
+
} else if (!this.validOptions.includes(option)) {
|
|
370
|
+
errors.push({
|
|
371
|
+
itemName: fileName,
|
|
372
|
+
error: `Invalid option '${option}'. Valid options: ${this.validOptions.join(", ")}`,
|
|
373
|
+
filePath,
|
|
374
|
+
lineNumber
|
|
375
|
+
});
|
|
376
|
+
} else if (!this.isOptionCompatibleWithType(option, columnType)) {
|
|
377
|
+
errors.push({
|
|
378
|
+
itemName: fileName,
|
|
379
|
+
error: `Option '${option}' is not compatible with type '${columnType}'`,
|
|
380
|
+
filePath,
|
|
381
|
+
lineNumber
|
|
382
|
+
});
|
|
225
383
|
}
|
|
226
384
|
});
|
|
227
|
-
console.log("");
|
|
228
385
|
}
|
|
229
386
|
}
|
|
387
|
+
validateColumnProperties(line, lineNumber, filePath, fileName, errors, content) {
|
|
388
|
+
const propertyKeyRegex = /^\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*:/;
|
|
389
|
+
const propMatch = propertyKeyRegex.exec(line);
|
|
390
|
+
if (!propMatch) return;
|
|
391
|
+
const propertyName = propMatch[1];
|
|
392
|
+
if (/^\s*[a-zA-Z_][a-zA-Z0-9_]*\s*:\s*\{/.test(line)) {
|
|
393
|
+
return;
|
|
394
|
+
}
|
|
395
|
+
if (this.isInsideColumnsBlock(content, lineNumber - 1)) {
|
|
396
|
+
if (!this.validProperties.includes(propertyName)) {
|
|
397
|
+
errors.push({
|
|
398
|
+
itemName: fileName,
|
|
399
|
+
error: `Invalid property '${propertyName}'. Valid properties: ${this.validProperties.join(", ")}`,
|
|
400
|
+
filePath,
|
|
401
|
+
lineNumber
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
if (/^\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*:\s*$/.test(line)) {
|
|
406
|
+
errors.push({
|
|
407
|
+
itemName: fileName,
|
|
408
|
+
error: `Property '${propertyName}' is missing a value`,
|
|
409
|
+
filePath,
|
|
410
|
+
lineNumber
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
validateRequiredColumnProperties(lines, lineNumber, filePath, fileName, errors) {
|
|
415
|
+
const line = lines[lineNumber - 1];
|
|
416
|
+
if (!/^\s*\}\s*;?\s*$/.test(line)) {
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
let columnStartLine = -1;
|
|
420
|
+
let columnName = "";
|
|
421
|
+
for (let i = lineNumber - 2; i >= 0; i--) {
|
|
422
|
+
const currentLine = lines[i];
|
|
423
|
+
const columnDefMatch = currentLine.match(/^\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*:\s*\{/);
|
|
424
|
+
if (columnDefMatch) {
|
|
425
|
+
let openBraces = 0;
|
|
426
|
+
let closeBraces = 0;
|
|
427
|
+
for (let j = i; j < lineNumber; j++) {
|
|
428
|
+
openBraces += (lines[j].match(/\{/g) || []).length;
|
|
429
|
+
closeBraces += (lines[j].match(/\}/g) || []).length;
|
|
430
|
+
}
|
|
431
|
+
if (openBraces === closeBraces) {
|
|
432
|
+
columnStartLine = i;
|
|
433
|
+
columnName = columnDefMatch[1];
|
|
434
|
+
break;
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
if (columnStartLine === -1 || !columnName) return;
|
|
439
|
+
let hasType = false;
|
|
440
|
+
for (let i = columnStartLine + 1; i < lineNumber - 1; i++) {
|
|
441
|
+
if (lines[i].match(/^\s*type\s*:/)) {
|
|
442
|
+
hasType = true;
|
|
443
|
+
break;
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
if (!hasType && columnName !== "foreign" && columnName !== "defaultValue") {
|
|
447
|
+
errors.push({
|
|
448
|
+
itemName: fileName,
|
|
449
|
+
error: `Column '${columnName}' is missing required 'type' property`,
|
|
450
|
+
filePath,
|
|
451
|
+
lineNumber: columnStartLine + 1
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
validateGeneralSyntax(line, lineNumber, filePath, fileName, errors) {
|
|
456
|
+
const quotes = line.match(/["']/g);
|
|
457
|
+
if (quotes && quotes.length % 2 !== 0) {
|
|
458
|
+
errors.push({
|
|
459
|
+
itemName: fileName,
|
|
460
|
+
error: "Mismatched quotes detected",
|
|
461
|
+
filePath,
|
|
462
|
+
lineNumber
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
if (line.includes("@database") || line.includes("@table")) {
|
|
466
|
+
const stringAnnotationRegex = /@(database|table)\s*\(\s*"([^"]*)"\s*\)/;
|
|
467
|
+
if (!stringAnnotationRegex.test(line)) {
|
|
468
|
+
errors.push({
|
|
469
|
+
itemName: fileName,
|
|
470
|
+
error: 'Invalid annotation syntax. Expected format: @annotation("value")',
|
|
471
|
+
filePath,
|
|
472
|
+
lineNumber
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
if (line.includes("@meta")) {
|
|
477
|
+
const metaObjectRegex = /@meta\s*\(\s*\{/;
|
|
478
|
+
if (!metaObjectRegex.test(line)) {
|
|
479
|
+
errors.push({
|
|
480
|
+
itemName: fileName,
|
|
481
|
+
error: "Invalid @meta syntax. Expected format: @meta({ ... })",
|
|
482
|
+
filePath,
|
|
483
|
+
lineNumber
|
|
484
|
+
});
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
validateOverallStructure(content, filePath, fileName, errors) {
|
|
489
|
+
const lines = content.split("\n");
|
|
490
|
+
const hasDatabase = lines.some((line) => line.includes("@database"));
|
|
491
|
+
if (!hasDatabase) {
|
|
492
|
+
errors.push({
|
|
493
|
+
itemName: fileName,
|
|
494
|
+
error: "Missing required @database annotation",
|
|
495
|
+
filePath,
|
|
496
|
+
lineNumber: 1
|
|
497
|
+
});
|
|
498
|
+
}
|
|
499
|
+
if (filePath.includes(".table.cube")) {
|
|
500
|
+
const hasColumns = lines.some((line) => line.includes("@columns"));
|
|
501
|
+
if (!hasColumns) {
|
|
502
|
+
errors.push({
|
|
503
|
+
itemName: fileName,
|
|
504
|
+
error: "Table cube files require @columns annotation",
|
|
505
|
+
filePath,
|
|
506
|
+
lineNumber: 1
|
|
507
|
+
});
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
getColumnTypeForOptions(lines, optionsLineIndex) {
|
|
512
|
+
for (let i = optionsLineIndex - 1; i >= 0; i--) {
|
|
513
|
+
const line = lines[i];
|
|
514
|
+
const typeMatch = line.match(/^\s*type\s*:\s*"([^"]+)"/);
|
|
515
|
+
if (typeMatch) {
|
|
516
|
+
return typeMatch[1];
|
|
517
|
+
}
|
|
518
|
+
if (/^\s*[a-zA-Z_][a-zA-Z0-9_]*\s*:\s*\{/.test(line)) {
|
|
519
|
+
break;
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
return "unknown";
|
|
523
|
+
}
|
|
524
|
+
isOptionCompatibleWithType(option, type) {
|
|
525
|
+
const compatibilityRules = {
|
|
526
|
+
"zerofill": ["int", "decimal", "float", "double"],
|
|
527
|
+
"unsigned": ["int", "decimal", "float", "double"],
|
|
528
|
+
"autoincrement": ["int"],
|
|
529
|
+
"primary": ["int", "varchar", "string"],
|
|
530
|
+
"not null": ["int", "varchar", "string", "text", "boolean", "date", "datetime", "timestamp", "decimal", "float", "double"],
|
|
531
|
+
"unique": ["int", "varchar", "string", "text"],
|
|
532
|
+
"index": ["int", "varchar", "string", "text", "date", "datetime", "timestamp"],
|
|
533
|
+
"required": ["int", "varchar", "string", "text", "boolean", "date", "datetime", "timestamp", "decimal", "float", "double"]
|
|
534
|
+
};
|
|
535
|
+
const compatibleTypes = compatibilityRules[option];
|
|
536
|
+
if (!compatibleTypes) {
|
|
537
|
+
return true;
|
|
538
|
+
}
|
|
539
|
+
return compatibleTypes.includes(type);
|
|
540
|
+
}
|
|
541
|
+
isInsideColumnsBlock(content, lineIndex) {
|
|
542
|
+
const lines = content.split("\n");
|
|
543
|
+
let columnsStartLine = -1;
|
|
544
|
+
let columnsEndLine = -1;
|
|
545
|
+
for (let i = 0; i < lines.length; i++) {
|
|
546
|
+
if (lines[i].includes("@columns")) {
|
|
547
|
+
columnsStartLine = i;
|
|
548
|
+
let braceCount = 0;
|
|
549
|
+
for (let j = i; j < lines.length; j++) {
|
|
550
|
+
const currentLine = lines[j];
|
|
551
|
+
braceCount += (currentLine.match(/\{/g) || []).length;
|
|
552
|
+
braceCount -= (currentLine.match(/\}/g) || []).length;
|
|
553
|
+
if (braceCount === 0 && j > i) {
|
|
554
|
+
columnsEndLine = j;
|
|
555
|
+
break;
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
break;
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
return columnsStartLine !== -1 && columnsEndLine !== -1 && lineIndex > columnsStartLine && lineIndex < columnsEndLine;
|
|
562
|
+
}
|
|
230
563
|
};
|
|
231
564
|
|
|
232
565
|
// src/lib/Schema.ts
|
|
@@ -238,18 +571,27 @@ var Schema = class {
|
|
|
238
571
|
this.engine = new Engine(name);
|
|
239
572
|
}
|
|
240
573
|
/**
|
|
241
|
-
* Validates
|
|
574
|
+
* Validates cube file comprehensively including syntax, database configuration, and structure
|
|
242
575
|
* @param filePath - Path to the cube file
|
|
243
|
-
* @returns
|
|
576
|
+
* @returns validation result with any errors found
|
|
244
577
|
*/
|
|
245
578
|
validateDatabaseConfiguration(filePath) {
|
|
246
579
|
try {
|
|
580
|
+
const cubeValidator = new CubeValidator();
|
|
581
|
+
const cubeValidation = cubeValidator.validateCubeFile(filePath);
|
|
582
|
+
if (!cubeValidation.isValid && cubeValidation.errors.length > 0) {
|
|
583
|
+
return {
|
|
584
|
+
isValid: false,
|
|
585
|
+
error: cubeValidation.errors[0]
|
|
586
|
+
// Return the first error found
|
|
587
|
+
};
|
|
588
|
+
}
|
|
247
589
|
const dbResult = FileUtils_default.extractDatabaseNameFromCube(filePath);
|
|
248
590
|
if (dbResult.status !== 200) {
|
|
249
591
|
return {
|
|
250
592
|
isValid: false,
|
|
251
593
|
error: {
|
|
252
|
-
itemName:
|
|
594
|
+
itemName: path3.basename(filePath, path3.extname(filePath)),
|
|
253
595
|
error: `Error reading database directive: ${dbResult.message}`,
|
|
254
596
|
filePath,
|
|
255
597
|
lineNumber: this.findDatabaseLineNumber(filePath)
|
|
@@ -258,7 +600,7 @@ var Schema = class {
|
|
|
258
600
|
}
|
|
259
601
|
const cubeDbName = dbResult.message;
|
|
260
602
|
const configInstance = new ConfigClass();
|
|
261
|
-
const configFilePath =
|
|
603
|
+
const configFilePath = path3.resolve(process.cwd(), "dbcube.config.js");
|
|
262
604
|
const configFn = __require(configFilePath);
|
|
263
605
|
if (typeof configFn === "function") {
|
|
264
606
|
configFn(configInstance);
|
|
@@ -285,7 +627,7 @@ var Schema = class {
|
|
|
285
627
|
return {
|
|
286
628
|
isValid: false,
|
|
287
629
|
error: {
|
|
288
|
-
itemName:
|
|
630
|
+
itemName: path3.basename(filePath, path3.extname(filePath)),
|
|
289
631
|
error: `Database configuration '${cubeDbName}' not found in dbcube.config.js. Available: ${availableText}`,
|
|
290
632
|
filePath,
|
|
291
633
|
lineNumber: this.findDatabaseLineNumber(filePath)
|
|
@@ -297,7 +639,7 @@ var Schema = class {
|
|
|
297
639
|
return {
|
|
298
640
|
isValid: false,
|
|
299
641
|
error: {
|
|
300
|
-
itemName:
|
|
642
|
+
itemName: path3.basename(filePath, path3.extname(filePath)),
|
|
301
643
|
error: `Database configuration validation failed: ${error.message}`,
|
|
302
644
|
filePath,
|
|
303
645
|
lineNumber: this.findDatabaseLineNumber(filePath)
|
|
@@ -310,7 +652,7 @@ var Schema = class {
|
|
|
310
652
|
*/
|
|
311
653
|
findDatabaseLineNumber(filePath) {
|
|
312
654
|
try {
|
|
313
|
-
const content =
|
|
655
|
+
const content = fs4.readFileSync(filePath, "utf8");
|
|
314
656
|
const lines = content.split("\n");
|
|
315
657
|
for (let i = 0; i < lines.length; i++) {
|
|
316
658
|
if (lines[i].includes("@database")) {
|
|
@@ -324,7 +666,7 @@ var Schema = class {
|
|
|
324
666
|
}
|
|
325
667
|
async createDatabase() {
|
|
326
668
|
const startTime = Date.now();
|
|
327
|
-
const rootPath =
|
|
669
|
+
const rootPath = path3.resolve(process.cwd());
|
|
328
670
|
UIUtils.showOperationHeader(" CREATING DATABASE", this.name, "\u{1F5C4}\uFE0F");
|
|
329
671
|
await UIUtils.showItemProgress("Preparando e instalando base de datos", 1, 1);
|
|
330
672
|
try {
|
|
@@ -368,8 +710,8 @@ var Schema = class {
|
|
|
368
710
|
}
|
|
369
711
|
async refreshTables() {
|
|
370
712
|
const startTime = Date.now();
|
|
371
|
-
const cubesDir =
|
|
372
|
-
if (!
|
|
713
|
+
const cubesDir = path3.join(process.cwd(), "dbcube", "cubes");
|
|
714
|
+
if (!fs4.existsSync(cubesDir)) {
|
|
373
715
|
throw new Error("\u274C The cubes folder does not exist");
|
|
374
716
|
}
|
|
375
717
|
const cubeFiles = FileUtils_default.getCubeFilesRecursively("dbcube", "table.cube");
|
|
@@ -384,11 +726,11 @@ var Schema = class {
|
|
|
384
726
|
const errors = [];
|
|
385
727
|
for (let index = 0; index < cubeFiles.length; index++) {
|
|
386
728
|
const file = cubeFiles[index];
|
|
387
|
-
const filePath =
|
|
388
|
-
const stats =
|
|
729
|
+
const filePath = path3.isAbsolute(file) ? file : path3.join(cubesDir, file);
|
|
730
|
+
const stats = fs4.statSync(filePath);
|
|
389
731
|
if (stats.isFile()) {
|
|
390
732
|
const getTableName = FileUtils_default.extracTableNameFromCube(filePath);
|
|
391
|
-
const tableName = getTableName.status === 200 ? getTableName.message :
|
|
733
|
+
const tableName = getTableName.status === 200 ? getTableName.message : path3.basename(file, ".table.cube");
|
|
392
734
|
await UIUtils.showItemProgress(tableName, index + 1, cubeFiles.length);
|
|
393
735
|
try {
|
|
394
736
|
const validation = this.validateDatabaseConfiguration(filePath);
|
|
@@ -470,8 +812,8 @@ var Schema = class {
|
|
|
470
812
|
}
|
|
471
813
|
async freshTables() {
|
|
472
814
|
const startTime = Date.now();
|
|
473
|
-
const cubesDir =
|
|
474
|
-
if (!
|
|
815
|
+
const cubesDir = path3.join(process.cwd(), "dbcube", "cubes");
|
|
816
|
+
if (!fs4.existsSync(cubesDir)) {
|
|
475
817
|
throw new Error("\u274C The cubes folder does not exist");
|
|
476
818
|
}
|
|
477
819
|
const cubeFiles = FileUtils_default.getCubeFilesRecursively("dbcube", "table.cube");
|
|
@@ -486,11 +828,11 @@ var Schema = class {
|
|
|
486
828
|
const errors = [];
|
|
487
829
|
for (let index = 0; index < cubeFiles.length; index++) {
|
|
488
830
|
const file = cubeFiles[index];
|
|
489
|
-
const filePath =
|
|
490
|
-
const stats =
|
|
831
|
+
const filePath = path3.isAbsolute(file) ? file : path3.join(cubesDir, file);
|
|
832
|
+
const stats = fs4.statSync(filePath);
|
|
491
833
|
if (stats.isFile()) {
|
|
492
834
|
const getTableName = FileUtils_default.extracTableNameFromCube(filePath);
|
|
493
|
-
const tableName = getTableName.status === 200 ? getTableName.message :
|
|
835
|
+
const tableName = getTableName.status === 200 ? getTableName.message : path3.basename(file, ".table.cube");
|
|
494
836
|
await UIUtils.showItemProgress(tableName, index + 1, cubeFiles.length);
|
|
495
837
|
try {
|
|
496
838
|
const validation = this.validateDatabaseConfiguration(filePath);
|
|
@@ -570,8 +912,8 @@ var Schema = class {
|
|
|
570
912
|
}
|
|
571
913
|
async executeSeeders() {
|
|
572
914
|
const startTime = Date.now();
|
|
573
|
-
const cubesDir =
|
|
574
|
-
if (!
|
|
915
|
+
const cubesDir = path3.join(process.cwd(), "dbcube", "cubes");
|
|
916
|
+
if (!fs4.existsSync(cubesDir)) {
|
|
575
917
|
throw new Error("\u274C The cubes folder does not exist");
|
|
576
918
|
}
|
|
577
919
|
const cubeFiles = FileUtils_default.getCubeFilesRecursively("dbcube", "seeder.cube");
|
|
@@ -586,11 +928,11 @@ var Schema = class {
|
|
|
586
928
|
const errors = [];
|
|
587
929
|
for (let index = 0; index < cubeFiles.length; index++) {
|
|
588
930
|
const file = cubeFiles[index];
|
|
589
|
-
const filePath =
|
|
590
|
-
const stats =
|
|
931
|
+
const filePath = path3.isAbsolute(file) ? file : path3.join(cubesDir, file);
|
|
932
|
+
const stats = fs4.statSync(filePath);
|
|
591
933
|
if (stats.isFile()) {
|
|
592
934
|
const getSeederName = FileUtils_default.extracTableNameFromCube(filePath);
|
|
593
|
-
const seederName = getSeederName.status === 200 ? getSeederName.message :
|
|
935
|
+
const seederName = getSeederName.status === 200 ? getSeederName.message : path3.basename(file, ".seeder.cube");
|
|
594
936
|
await UIUtils.showItemProgress(seederName, index + 1, cubeFiles.length);
|
|
595
937
|
try {
|
|
596
938
|
const validation = this.validateDatabaseConfiguration(filePath);
|
|
@@ -641,9 +983,9 @@ var Schema = class {
|
|
|
641
983
|
}
|
|
642
984
|
async executeTriggers() {
|
|
643
985
|
const startTime = Date.now();
|
|
644
|
-
const cubesDir =
|
|
645
|
-
const triggersDirExit =
|
|
646
|
-
if (!
|
|
986
|
+
const cubesDir = path3.join(process.cwd(), "dbcube", "cubes");
|
|
987
|
+
const triggersDirExit = path3.join(process.cwd(), "dbcube", "triggers");
|
|
988
|
+
if (!fs4.existsSync(cubesDir)) {
|
|
647
989
|
throw new Error("\u274C The cubes folder does not exist");
|
|
648
990
|
}
|
|
649
991
|
const cubeFiles = FileUtils_default.getCubeFilesRecursively("dbcube", "trigger.cube");
|
|
@@ -658,11 +1000,11 @@ var Schema = class {
|
|
|
658
1000
|
const errors = [];
|
|
659
1001
|
for (let index = 0; index < cubeFiles.length; index++) {
|
|
660
1002
|
const file = cubeFiles[index];
|
|
661
|
-
const filePath =
|
|
662
|
-
const stats =
|
|
1003
|
+
const filePath = path3.isAbsolute(file) ? file : path3.join(cubesDir, file);
|
|
1004
|
+
const stats = fs4.statSync(filePath);
|
|
663
1005
|
if (stats.isFile()) {
|
|
664
1006
|
const getTriggerName = FileUtils_default.extracTableNameFromCube(filePath);
|
|
665
|
-
const triggerName = getTriggerName.status === 200 ? getTriggerName.message :
|
|
1007
|
+
const triggerName = getTriggerName.status === 200 ? getTriggerName.message : path3.basename(file, ".trigger.cube");
|
|
666
1008
|
await UIUtils.showItemProgress(triggerName, index + 1, cubeFiles.length);
|
|
667
1009
|
try {
|
|
668
1010
|
const validation = this.validateDatabaseConfiguration(filePath);
|
|
@@ -715,29 +1057,11 @@ var Schema = class {
|
|
|
715
1057
|
}
|
|
716
1058
|
};
|
|
717
1059
|
function returnFormattedError(status, message) {
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
const GRAY = "\x1B[90m";
|
|
724
|
-
const UNDERLINE = "\x1B[4m";
|
|
725
|
-
const MAGENTA = "\x1B[35m";
|
|
726
|
-
let output = "";
|
|
727
|
-
let help = "";
|
|
728
|
-
const color = status === 600 ? YELLOW : RED;
|
|
729
|
-
if (message.includes("[help]")) {
|
|
730
|
-
const parts = message.split("[help]");
|
|
731
|
-
output += `
|
|
732
|
-
${RED}${BOLD}${parts[0]}${RESET}`;
|
|
733
|
-
help += `
|
|
734
|
-
${MAGENTA}${BOLD}[help]${RESET} ${GRAY}${parts[1]}${RESET}
|
|
735
|
-
`;
|
|
736
|
-
} else {
|
|
737
|
-
output += `
|
|
738
|
-
${color}${BOLD}${message}${RESET}
|
|
739
|
-
`;
|
|
740
|
-
}
|
|
1060
|
+
console.log(`
|
|
1061
|
+
${chalk2.red("\u{1F6AB}")} ${chalk2.bold.red("ERRORS FOUND")}`);
|
|
1062
|
+
console.log(chalk2.red("\u2500".repeat(60)));
|
|
1063
|
+
console.log(`${chalk2.red("[error]")} ${chalk2.red(message)}`);
|
|
1064
|
+
console.log("");
|
|
741
1065
|
const err = new Error();
|
|
742
1066
|
const stackLines = err.stack?.split("\n") || [];
|
|
743
1067
|
const relevantStackLine = stackLines.find(
|
|
@@ -749,39 +1073,32 @@ ${color}${BOLD}${message}${RESET}
|
|
|
749
1073
|
const [, filePath, lineStr, columnStr] = match;
|
|
750
1074
|
const lineNum = parseInt(lineStr, 10);
|
|
751
1075
|
const errorLocation = `${filePath}:${lineStr}:${columnStr}`;
|
|
1076
|
+
console.log(`${chalk2.cyan("[code]")} ${chalk2.yellow(errorLocation)}`);
|
|
752
1077
|
try {
|
|
753
|
-
const codeLines =
|
|
1078
|
+
const codeLines = fs4.readFileSync(filePath, "utf-8").split("\n");
|
|
754
1079
|
const start = Math.max(0, lineNum - 3);
|
|
755
1080
|
const end = Math.min(codeLines.length, lineNum + 2);
|
|
756
|
-
output += `
|
|
757
|
-
${CYAN}${BOLD}[code] ${RESET}${YELLOW} ${UNDERLINE}${errorLocation}${RESET}
|
|
758
|
-
`;
|
|
759
1081
|
for (let i = start; i < end; i++) {
|
|
760
1082
|
const line = codeLines[i];
|
|
761
1083
|
const lineLabel = `${i + 1}`.padStart(4, " ");
|
|
762
|
-
const pointer = i + 1 === lineNum ? `${
|
|
763
|
-
|
|
764
|
-
`;
|
|
1084
|
+
const pointer = i + 1 === lineNum ? `${chalk2.red("<-")}` : " ";
|
|
1085
|
+
console.log(`${chalk2.gray(lineLabel)} ${pointer} ${chalk2.white(line)}`);
|
|
765
1086
|
}
|
|
766
1087
|
} catch (err2) {
|
|
767
|
-
|
|
768
|
-
`;
|
|
769
|
-
output += `
|
|
770
|
-
${CYAN}${BOLD}Stack Trace:${RESET}
|
|
771
|
-
${stackLines.slice(2).join("\n")}
|
|
772
|
-
`;
|
|
1088
|
+
console.log(chalk2.gray(" (unable to show code context)"));
|
|
773
1089
|
}
|
|
774
1090
|
}
|
|
775
1091
|
}
|
|
776
|
-
|
|
777
|
-
console.error(output);
|
|
1092
|
+
console.log("");
|
|
778
1093
|
process.exit(1);
|
|
779
1094
|
}
|
|
780
1095
|
|
|
781
1096
|
// src/index.ts
|
|
782
1097
|
var index_default = Schema;
|
|
783
1098
|
export {
|
|
1099
|
+
CubeValidator,
|
|
784
1100
|
Schema,
|
|
1101
|
+
UIUtils,
|
|
785
1102
|
index_default as default
|
|
786
1103
|
};
|
|
787
1104
|
//# sourceMappingURL=index.js.map
|