@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/dist/index.js
CHANGED
|
@@ -255,7 +255,7 @@ var CubeValidator = class {
|
|
|
255
255
|
validTypes = ["varchar", "int", "string", "text", "boolean", "date", "datetime", "timestamp", "decimal", "float", "double", "enum", "json"];
|
|
256
256
|
validOptions = ["not null", "primary", "autoincrement", "unique", "zerofill", "index", "required", "unsigned"];
|
|
257
257
|
validProperties = ["type", "length", "options", "value", "defaultValue", "foreign", "enumValues", "description"];
|
|
258
|
-
knownAnnotations = ["database", "table", "meta", "columns", "fields", "dataset", "beforeAdd", "afterAdd", "beforeUpdate", "afterUpdate", "beforeDelete", "afterDelete", "compute", "column"];
|
|
258
|
+
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"];
|
|
259
259
|
/**
|
|
260
260
|
* Validates a cube file comprehensively
|
|
261
261
|
*/
|
|
@@ -386,6 +386,18 @@ var CubeValidator = class {
|
|
|
386
386
|
if (/^\s*[a-zA-Z_][a-zA-Z0-9_]*\s*:\s*\{/.test(line)) {
|
|
387
387
|
return;
|
|
388
388
|
}
|
|
389
|
+
if (this.isInsideIndexesBlock(content, lineNumber - 1)) {
|
|
390
|
+
const validIndexProperties = ["columns", "unique"];
|
|
391
|
+
if (!validIndexProperties.includes(propertyName)) {
|
|
392
|
+
errors.push({
|
|
393
|
+
itemName: fileName,
|
|
394
|
+
error: `Invalid index property '${propertyName}'. Valid index properties: ${validIndexProperties.join(", ")}`,
|
|
395
|
+
filePath,
|
|
396
|
+
lineNumber
|
|
397
|
+
});
|
|
398
|
+
}
|
|
399
|
+
return;
|
|
400
|
+
}
|
|
389
401
|
if (this.isInsideForeignKeyObject(content, lineNumber - 1)) {
|
|
390
402
|
const validForeignKeyProperties = ["table", "column"];
|
|
391
403
|
if (!validForeignKeyProperties.includes(propertyName)) {
|
|
@@ -417,6 +429,27 @@ var CubeValidator = class {
|
|
|
417
429
|
});
|
|
418
430
|
}
|
|
419
431
|
}
|
|
432
|
+
isInsideIndexesBlock(content, lineIndex) {
|
|
433
|
+
const lines = content.split("\n");
|
|
434
|
+
let indexesStartLine = -1;
|
|
435
|
+
let indexesEndLine = -1;
|
|
436
|
+
for (let i = 0; i < lines.length; i++) {
|
|
437
|
+
if (lines[i].includes("@indexes")) {
|
|
438
|
+
indexesStartLine = i;
|
|
439
|
+
let braceCount = 0;
|
|
440
|
+
for (let j = i; j < lines.length; j++) {
|
|
441
|
+
braceCount += (lines[j].match(/\{/g) || []).length;
|
|
442
|
+
braceCount -= (lines[j].match(/\}/g) || []).length;
|
|
443
|
+
if (braceCount === 0 && j > i) {
|
|
444
|
+
indexesEndLine = j;
|
|
445
|
+
break;
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
break;
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
return indexesStartLine !== -1 && indexesEndLine !== -1 && lineIndex > indexesStartLine && lineIndex < indexesEndLine;
|
|
452
|
+
}
|
|
420
453
|
validateRequiredColumnProperties(lines, lineNumber, filePath, fileName, errors) {
|
|
421
454
|
const line = lines[lineNumber - 1];
|
|
422
455
|
if (!/^\s*\}\s*;?\s*$/.test(line)) {
|
|
@@ -513,6 +546,28 @@ var CubeValidator = class {
|
|
|
513
546
|
});
|
|
514
547
|
}
|
|
515
548
|
}
|
|
549
|
+
if (filePath.includes(".alter.cube")) {
|
|
550
|
+
const hasTable = lines.some((line) => line.includes("@table"));
|
|
551
|
+
if (!hasTable) {
|
|
552
|
+
errors.push({
|
|
553
|
+
itemName: fileName,
|
|
554
|
+
error: "Alter cube files require @table annotation specifying the target table",
|
|
555
|
+
filePath,
|
|
556
|
+
lineNumber: 1
|
|
557
|
+
});
|
|
558
|
+
}
|
|
559
|
+
const hasAlterDirective = lines.some(
|
|
560
|
+
(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")
|
|
561
|
+
);
|
|
562
|
+
if (!hasAlterDirective) {
|
|
563
|
+
errors.push({
|
|
564
|
+
itemName: fileName,
|
|
565
|
+
error: "Alter cube files must contain at least one alter directive (@changeName, @addColumn, @deleteColumn, @renameColumn, @changeType, @changeLength, @changeDefault, @changeOptions, or @changeEnumValues)",
|
|
566
|
+
filePath,
|
|
567
|
+
lineNumber: 1
|
|
568
|
+
});
|
|
569
|
+
}
|
|
570
|
+
}
|
|
516
571
|
}
|
|
517
572
|
getColumnTypeForOptions(lines, optionsLineIndex) {
|
|
518
573
|
for (let i = optionsLineIndex - 1; i >= 0; i--) {
|
|
@@ -1331,6 +1386,108 @@ var Schema = class {
|
|
|
1331
1386
|
UIUtils.showOperationSummary(summary);
|
|
1332
1387
|
return totalSeedersProcessed > 0 ? { processed: totalSeedersProcessed, success: successCount, errors: errorCount } : null;
|
|
1333
1388
|
}
|
|
1389
|
+
async executeAlters() {
|
|
1390
|
+
const startTime = Date.now();
|
|
1391
|
+
const cubesDir = path4.join(process.cwd(), "dbcube");
|
|
1392
|
+
if (!fs5.existsSync(cubesDir)) {
|
|
1393
|
+
throw new Error("\u274C The cubes folder does not exist");
|
|
1394
|
+
}
|
|
1395
|
+
const cubeFiles = FileUtils_default.getCubeFilesRecursively("dbcube", ".alter.cube");
|
|
1396
|
+
if (cubeFiles.length === 0) {
|
|
1397
|
+
throw new Error("\u274C There are no .alter.cube files to execute");
|
|
1398
|
+
}
|
|
1399
|
+
UIUtils.showOperationHeader("EXECUTING ALTER TABLES", this.name, "\u{1F527}");
|
|
1400
|
+
let totalAltersProcessed = 0;
|
|
1401
|
+
let successCount = 0;
|
|
1402
|
+
let errorCount = 0;
|
|
1403
|
+
const processedAlters = [];
|
|
1404
|
+
const errors = [];
|
|
1405
|
+
for (let index = 0; index < cubeFiles.length; index++) {
|
|
1406
|
+
const file = cubeFiles[index];
|
|
1407
|
+
const filePath = path4.isAbsolute(file) ? file : path4.join(cubesDir, file);
|
|
1408
|
+
const stats = fs5.statSync(filePath);
|
|
1409
|
+
if (stats.isFile()) {
|
|
1410
|
+
const alterName = path4.basename(file, ".alter.cube");
|
|
1411
|
+
await UIUtils.showItemProgress(alterName, index + 1, cubeFiles.length);
|
|
1412
|
+
try {
|
|
1413
|
+
const validation = this.validateDatabaseConfiguration(filePath);
|
|
1414
|
+
if (!validation.isValid && validation.error) {
|
|
1415
|
+
UIUtils.showItemError(alterName, validation.error.error);
|
|
1416
|
+
errors.push(validation.error);
|
|
1417
|
+
errorCount++;
|
|
1418
|
+
continue;
|
|
1419
|
+
}
|
|
1420
|
+
const dbResult = FileUtils_default.extractDatabaseNameFromCube(filePath);
|
|
1421
|
+
const cubeDbName = dbResult.status === 200 ? dbResult.message : this.name;
|
|
1422
|
+
if (cubeDbName !== this.name) {
|
|
1423
|
+
continue;
|
|
1424
|
+
}
|
|
1425
|
+
const dml = await this.engine.run("schema_engine", [
|
|
1426
|
+
"--action",
|
|
1427
|
+
"parse_alter",
|
|
1428
|
+
"--schema-path",
|
|
1429
|
+
filePath
|
|
1430
|
+
]);
|
|
1431
|
+
if (dml.status != 200) {
|
|
1432
|
+
returnFormattedError(dml.status, dml.message);
|
|
1433
|
+
break;
|
|
1434
|
+
}
|
|
1435
|
+
const parseJson = JSON.stringify(dml.data.actions).replace(/[\r\n\t]/g, "").replace(/\\[rnt]/g, "").replace(/\s{2,}/g, " ");
|
|
1436
|
+
const queries = await this.engine.run("schema_engine", [
|
|
1437
|
+
"--action",
|
|
1438
|
+
"generate",
|
|
1439
|
+
"--mode",
|
|
1440
|
+
"alter",
|
|
1441
|
+
"--dml",
|
|
1442
|
+
parseJson
|
|
1443
|
+
]);
|
|
1444
|
+
if (queries.status != 200) {
|
|
1445
|
+
returnFormattedError(queries.status, queries.message);
|
|
1446
|
+
break;
|
|
1447
|
+
}
|
|
1448
|
+
delete queries.data.database_type;
|
|
1449
|
+
const parseJsonQueries = JSON.stringify(queries.data);
|
|
1450
|
+
const response = await this.engine.run("schema_engine", [
|
|
1451
|
+
"--action",
|
|
1452
|
+
"execute",
|
|
1453
|
+
"--mode",
|
|
1454
|
+
"alter",
|
|
1455
|
+
"--dml",
|
|
1456
|
+
parseJsonQueries
|
|
1457
|
+
]);
|
|
1458
|
+
if (response.status != 200) {
|
|
1459
|
+
returnFormattedError(response.status, response.message);
|
|
1460
|
+
break;
|
|
1461
|
+
}
|
|
1462
|
+
UIUtils.showItemSuccess(alterName);
|
|
1463
|
+
successCount++;
|
|
1464
|
+
processedAlters.push(alterName);
|
|
1465
|
+
totalAltersProcessed++;
|
|
1466
|
+
} catch (error) {
|
|
1467
|
+
const processError = {
|
|
1468
|
+
itemName: alterName,
|
|
1469
|
+
error: error.message,
|
|
1470
|
+
filePath
|
|
1471
|
+
};
|
|
1472
|
+
UIUtils.showItemError(alterName, error.message);
|
|
1473
|
+
errors.push(processError);
|
|
1474
|
+
errorCount++;
|
|
1475
|
+
}
|
|
1476
|
+
}
|
|
1477
|
+
}
|
|
1478
|
+
const summary = {
|
|
1479
|
+
startTime,
|
|
1480
|
+
totalProcessed: totalAltersProcessed,
|
|
1481
|
+
successCount,
|
|
1482
|
+
errorCount,
|
|
1483
|
+
processedItems: processedAlters,
|
|
1484
|
+
operationName: "alter tables",
|
|
1485
|
+
databaseName: this.name,
|
|
1486
|
+
errors
|
|
1487
|
+
};
|
|
1488
|
+
UIUtils.showOperationSummary(summary);
|
|
1489
|
+
return totalAltersProcessed > 0 ? { processed: totalAltersProcessed, success: successCount, errors: errorCount } : null;
|
|
1490
|
+
}
|
|
1334
1491
|
async executeTriggers() {
|
|
1335
1492
|
const startTime = Date.now();
|
|
1336
1493
|
const cubesDir = path4.join(process.cwd(), "dbcube");
|