@dbcube/schema-builder 5.0.13 → 5.1.3
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/bun.lockb +0 -0
- package/dist/index.cjs +158 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +129 -126
- package/dist/index.d.ts +129 -126
- package/dist/index.js +158 -1
- package/dist/index.js.map +1 -1
- package/package.json +9 -8
- package/tsup.config.ts +1 -1
package/bun.lockb
CHANGED
|
Binary file
|
package/dist/index.cjs
CHANGED
|
@@ -295,7 +295,7 @@ var CubeValidator = class {
|
|
|
295
295
|
validTypes = ["varchar", "int", "string", "text", "boolean", "date", "datetime", "timestamp", "decimal", "float", "double", "enum", "json"];
|
|
296
296
|
validOptions = ["not null", "primary", "autoincrement", "unique", "zerofill", "index", "required", "unsigned"];
|
|
297
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"];
|
|
298
|
+
knownAnnotations = ["database", "table", "meta", "columns", "indexes", "fields", "dataset", "beforeAdd", "afterAdd", "beforeUpdate", "afterUpdate", "beforeDelete", "afterDelete", "compute", "column", "changeName", "addColumn", "deleteColumn", "renameColumn", "changeType", "changeLength", "changeDefault", "changeOptions", "changeEnumValues"];
|
|
299
299
|
/**
|
|
300
300
|
* Validates a cube file comprehensively
|
|
301
301
|
*/
|
|
@@ -426,6 +426,18 @@ var CubeValidator = class {
|
|
|
426
426
|
if (/^\s*[a-zA-Z_][a-zA-Z0-9_]*\s*:\s*\{/.test(line)) {
|
|
427
427
|
return;
|
|
428
428
|
}
|
|
429
|
+
if (this.isInsideIndexesBlock(content, lineNumber - 1)) {
|
|
430
|
+
const validIndexProperties = ["columns", "unique"];
|
|
431
|
+
if (!validIndexProperties.includes(propertyName)) {
|
|
432
|
+
errors.push({
|
|
433
|
+
itemName: fileName,
|
|
434
|
+
error: `Invalid index property '${propertyName}'. Valid index properties: ${validIndexProperties.join(", ")}`,
|
|
435
|
+
filePath,
|
|
436
|
+
lineNumber
|
|
437
|
+
});
|
|
438
|
+
}
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
429
441
|
if (this.isInsideForeignKeyObject(content, lineNumber - 1)) {
|
|
430
442
|
const validForeignKeyProperties = ["table", "column"];
|
|
431
443
|
if (!validForeignKeyProperties.includes(propertyName)) {
|
|
@@ -457,6 +469,27 @@ var CubeValidator = class {
|
|
|
457
469
|
});
|
|
458
470
|
}
|
|
459
471
|
}
|
|
472
|
+
isInsideIndexesBlock(content, lineIndex) {
|
|
473
|
+
const lines = content.split("\n");
|
|
474
|
+
let indexesStartLine = -1;
|
|
475
|
+
let indexesEndLine = -1;
|
|
476
|
+
for (let i = 0; i < lines.length; i++) {
|
|
477
|
+
if (lines[i].includes("@indexes")) {
|
|
478
|
+
indexesStartLine = i;
|
|
479
|
+
let braceCount = 0;
|
|
480
|
+
for (let j = i; j < lines.length; j++) {
|
|
481
|
+
braceCount += (lines[j].match(/\{/g) || []).length;
|
|
482
|
+
braceCount -= (lines[j].match(/\}/g) || []).length;
|
|
483
|
+
if (braceCount === 0 && j > i) {
|
|
484
|
+
indexesEndLine = j;
|
|
485
|
+
break;
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
break;
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
return indexesStartLine !== -1 && indexesEndLine !== -1 && lineIndex > indexesStartLine && lineIndex < indexesEndLine;
|
|
492
|
+
}
|
|
460
493
|
validateRequiredColumnProperties(lines, lineNumber, filePath, fileName, errors) {
|
|
461
494
|
const line = lines[lineNumber - 1];
|
|
462
495
|
if (!/^\s*\}\s*;?\s*$/.test(line)) {
|
|
@@ -553,6 +586,28 @@ var CubeValidator = class {
|
|
|
553
586
|
});
|
|
554
587
|
}
|
|
555
588
|
}
|
|
589
|
+
if (filePath.includes(".alter.cube")) {
|
|
590
|
+
const hasTable = lines.some((line) => line.includes("@table"));
|
|
591
|
+
if (!hasTable) {
|
|
592
|
+
errors.push({
|
|
593
|
+
itemName: fileName,
|
|
594
|
+
error: "Alter cube files require @table annotation specifying the target table",
|
|
595
|
+
filePath,
|
|
596
|
+
lineNumber: 1
|
|
597
|
+
});
|
|
598
|
+
}
|
|
599
|
+
const hasAlterDirective = lines.some(
|
|
600
|
+
(line) => line.includes("@changeName") || line.includes("@addColumn") || line.includes("@deleteColumn") || line.includes("@renameColumn") || line.includes("@changeType") || line.includes("@changeLength") || line.includes("@changeDefault") || line.includes("@changeOptions") || line.includes("@changeEnumValues")
|
|
601
|
+
);
|
|
602
|
+
if (!hasAlterDirective) {
|
|
603
|
+
errors.push({
|
|
604
|
+
itemName: fileName,
|
|
605
|
+
error: "Alter cube files must contain at least one alter directive (@changeName, @addColumn, @deleteColumn, @renameColumn, @changeType, @changeLength, @changeDefault, @changeOptions, or @changeEnumValues)",
|
|
606
|
+
filePath,
|
|
607
|
+
lineNumber: 1
|
|
608
|
+
});
|
|
609
|
+
}
|
|
610
|
+
}
|
|
556
611
|
}
|
|
557
612
|
getColumnTypeForOptions(lines, optionsLineIndex) {
|
|
558
613
|
for (let i = optionsLineIndex - 1; i >= 0; i--) {
|
|
@@ -1371,6 +1426,108 @@ var Schema = class {
|
|
|
1371
1426
|
UIUtils.showOperationSummary(summary);
|
|
1372
1427
|
return totalSeedersProcessed > 0 ? { processed: totalSeedersProcessed, success: successCount, errors: errorCount } : null;
|
|
1373
1428
|
}
|
|
1429
|
+
async executeAlters() {
|
|
1430
|
+
const startTime = Date.now();
|
|
1431
|
+
const cubesDir = import_path3.default.join(process.cwd(), "dbcube");
|
|
1432
|
+
if (!import_fs4.default.existsSync(cubesDir)) {
|
|
1433
|
+
throw new Error("\u274C The cubes folder does not exist");
|
|
1434
|
+
}
|
|
1435
|
+
const cubeFiles = FileUtils_default.getCubeFilesRecursively("dbcube", ".alter.cube");
|
|
1436
|
+
if (cubeFiles.length === 0) {
|
|
1437
|
+
throw new Error("\u274C There are no .alter.cube files to execute");
|
|
1438
|
+
}
|
|
1439
|
+
UIUtils.showOperationHeader("EXECUTING ALTER TABLES", this.name, "\u{1F527}");
|
|
1440
|
+
let totalAltersProcessed = 0;
|
|
1441
|
+
let successCount = 0;
|
|
1442
|
+
let errorCount = 0;
|
|
1443
|
+
const processedAlters = [];
|
|
1444
|
+
const errors = [];
|
|
1445
|
+
for (let index = 0; index < cubeFiles.length; index++) {
|
|
1446
|
+
const file = cubeFiles[index];
|
|
1447
|
+
const filePath = import_path3.default.isAbsolute(file) ? file : import_path3.default.join(cubesDir, file);
|
|
1448
|
+
const stats = import_fs4.default.statSync(filePath);
|
|
1449
|
+
if (stats.isFile()) {
|
|
1450
|
+
const alterName = import_path3.default.basename(file, ".alter.cube");
|
|
1451
|
+
await UIUtils.showItemProgress(alterName, index + 1, cubeFiles.length);
|
|
1452
|
+
try {
|
|
1453
|
+
const validation = this.validateDatabaseConfiguration(filePath);
|
|
1454
|
+
if (!validation.isValid && validation.error) {
|
|
1455
|
+
UIUtils.showItemError(alterName, validation.error.error);
|
|
1456
|
+
errors.push(validation.error);
|
|
1457
|
+
errorCount++;
|
|
1458
|
+
continue;
|
|
1459
|
+
}
|
|
1460
|
+
const dbResult = FileUtils_default.extractDatabaseNameFromCube(filePath);
|
|
1461
|
+
const cubeDbName = dbResult.status === 200 ? dbResult.message : this.name;
|
|
1462
|
+
if (cubeDbName !== this.name) {
|
|
1463
|
+
continue;
|
|
1464
|
+
}
|
|
1465
|
+
const dml = await this.engine.run("schema_engine", [
|
|
1466
|
+
"--action",
|
|
1467
|
+
"parse_alter",
|
|
1468
|
+
"--schema-path",
|
|
1469
|
+
filePath
|
|
1470
|
+
]);
|
|
1471
|
+
if (dml.status != 200) {
|
|
1472
|
+
returnFormattedError(dml.status, dml.message);
|
|
1473
|
+
break;
|
|
1474
|
+
}
|
|
1475
|
+
const parseJson = JSON.stringify(dml.data.actions).replace(/[\r\n\t]/g, "").replace(/\\[rnt]/g, "").replace(/\s{2,}/g, " ");
|
|
1476
|
+
const queries = await this.engine.run("schema_engine", [
|
|
1477
|
+
"--action",
|
|
1478
|
+
"generate",
|
|
1479
|
+
"--mode",
|
|
1480
|
+
"alter",
|
|
1481
|
+
"--dml",
|
|
1482
|
+
parseJson
|
|
1483
|
+
]);
|
|
1484
|
+
if (queries.status != 200) {
|
|
1485
|
+
returnFormattedError(queries.status, queries.message);
|
|
1486
|
+
break;
|
|
1487
|
+
}
|
|
1488
|
+
delete queries.data.database_type;
|
|
1489
|
+
const parseJsonQueries = JSON.stringify(queries.data);
|
|
1490
|
+
const response = await this.engine.run("schema_engine", [
|
|
1491
|
+
"--action",
|
|
1492
|
+
"execute",
|
|
1493
|
+
"--mode",
|
|
1494
|
+
"alter",
|
|
1495
|
+
"--dml",
|
|
1496
|
+
parseJsonQueries
|
|
1497
|
+
]);
|
|
1498
|
+
if (response.status != 200) {
|
|
1499
|
+
returnFormattedError(response.status, response.message);
|
|
1500
|
+
break;
|
|
1501
|
+
}
|
|
1502
|
+
UIUtils.showItemSuccess(alterName);
|
|
1503
|
+
successCount++;
|
|
1504
|
+
processedAlters.push(alterName);
|
|
1505
|
+
totalAltersProcessed++;
|
|
1506
|
+
} catch (error) {
|
|
1507
|
+
const processError = {
|
|
1508
|
+
itemName: alterName,
|
|
1509
|
+
error: error.message,
|
|
1510
|
+
filePath
|
|
1511
|
+
};
|
|
1512
|
+
UIUtils.showItemError(alterName, error.message);
|
|
1513
|
+
errors.push(processError);
|
|
1514
|
+
errorCount++;
|
|
1515
|
+
}
|
|
1516
|
+
}
|
|
1517
|
+
}
|
|
1518
|
+
const summary = {
|
|
1519
|
+
startTime,
|
|
1520
|
+
totalProcessed: totalAltersProcessed,
|
|
1521
|
+
successCount,
|
|
1522
|
+
errorCount,
|
|
1523
|
+
processedItems: processedAlters,
|
|
1524
|
+
operationName: "alter tables",
|
|
1525
|
+
databaseName: this.name,
|
|
1526
|
+
errors
|
|
1527
|
+
};
|
|
1528
|
+
UIUtils.showOperationSummary(summary);
|
|
1529
|
+
return totalAltersProcessed > 0 ? { processed: totalAltersProcessed, success: successCount, errors: errorCount } : null;
|
|
1530
|
+
}
|
|
1374
1531
|
async executeTriggers() {
|
|
1375
1532
|
const startTime = Date.now();
|
|
1376
1533
|
const cubesDir = import_path3.default.join(process.cwd(), "dbcube");
|