arkormx 2.0.0-next.3 → 2.0.0-next.5
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/cli.mjs +477 -128
- package/dist/index.cjs +2479 -2087
- package/dist/index.d.cts +64 -3
- package/dist/index.d.mts +64 -3
- package/dist/index.mjs +2546 -2169
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -6,13 +6,13 @@ import { str } from "@h3ravel/support";
|
|
|
6
6
|
import path, { dirname as dirname$1, extname as extname$1, join as join$1, relative } from "path";
|
|
7
7
|
import { copyFileSync, existsSync as existsSync$1, mkdirSync as mkdirSync$1, readFileSync as readFileSync$1, readdirSync as readdirSync$1, rmSync as rmSync$1, writeFileSync as writeFileSync$1 } from "fs";
|
|
8
8
|
import { AsyncLocalStorage } from "async_hooks";
|
|
9
|
+
import { createHash } from "node:crypto";
|
|
9
10
|
import { createJiti } from "@rexxars/jiti";
|
|
10
11
|
import { pathToFileURL } from "node:url";
|
|
11
12
|
import { createRequire } from "module";
|
|
12
13
|
import { fileURLToPath } from "url";
|
|
13
14
|
import { Logger } from "@h3ravel/shared";
|
|
14
15
|
import { Command, Kernel } from "@h3ravel/musket";
|
|
15
|
-
import { createHash } from "node:crypto";
|
|
16
16
|
|
|
17
17
|
//#region src/Exceptions/ArkormException.ts
|
|
18
18
|
var ArkormException = class extends Error {
|
|
@@ -1436,6 +1436,374 @@ const applyMigrationRollbackToPrismaSchema = async (migration, options = {}) =>
|
|
|
1436
1436
|
};
|
|
1437
1437
|
};
|
|
1438
1438
|
|
|
1439
|
+
//#endregion
|
|
1440
|
+
//#region src/helpers/migration-history.ts
|
|
1441
|
+
const createEmptyAppliedMigrationsState = () => ({
|
|
1442
|
+
version: 1,
|
|
1443
|
+
migrations: [],
|
|
1444
|
+
runs: []
|
|
1445
|
+
});
|
|
1446
|
+
const supportsDatabaseMigrationState = (adapter) => {
|
|
1447
|
+
return typeof adapter?.readAppliedMigrationsState === "function" && typeof adapter?.writeAppliedMigrationsState === "function";
|
|
1448
|
+
};
|
|
1449
|
+
const resolveMigrationStateFilePath = (cwd, configuredPath) => {
|
|
1450
|
+
if (configuredPath && configuredPath.trim().length > 0) return resolve(configuredPath);
|
|
1451
|
+
return join(cwd, ".arkormx", "migrations.applied.json");
|
|
1452
|
+
};
|
|
1453
|
+
const buildMigrationIdentity = (filePath, className) => {
|
|
1454
|
+
const fileName = filePath.split("/").pop()?.split("\\").pop() ?? filePath;
|
|
1455
|
+
return `${fileName.slice(0, fileName.length - extname(fileName).length)}:${className}`;
|
|
1456
|
+
};
|
|
1457
|
+
const computeMigrationChecksum = (filePath) => {
|
|
1458
|
+
const source = readFileSync(filePath, "utf-8");
|
|
1459
|
+
return createHash("sha256").update(source).digest("hex");
|
|
1460
|
+
};
|
|
1461
|
+
const readAppliedMigrationsState = (stateFilePath) => {
|
|
1462
|
+
if (!existsSync(stateFilePath)) return createEmptyAppliedMigrationsState();
|
|
1463
|
+
try {
|
|
1464
|
+
const parsed = JSON.parse(readFileSync(stateFilePath, "utf-8"));
|
|
1465
|
+
if (!Array.isArray(parsed.migrations)) return createEmptyAppliedMigrationsState();
|
|
1466
|
+
return {
|
|
1467
|
+
version: 1,
|
|
1468
|
+
migrations: parsed.migrations.filter((migration) => {
|
|
1469
|
+
return typeof migration?.id === "string" && typeof migration?.file === "string" && typeof migration?.className === "string" && typeof migration?.appliedAt === "string" && (migration?.checksum === void 0 || typeof migration?.checksum === "string");
|
|
1470
|
+
}),
|
|
1471
|
+
runs: Array.isArray(parsed.runs) ? parsed.runs.filter((run) => {
|
|
1472
|
+
return typeof run?.id === "string" && typeof run?.appliedAt === "string" && Array.isArray(run?.migrationIds) && run.migrationIds.every((item) => typeof item === "string");
|
|
1473
|
+
}) : []
|
|
1474
|
+
};
|
|
1475
|
+
} catch {
|
|
1476
|
+
return createEmptyAppliedMigrationsState();
|
|
1477
|
+
}
|
|
1478
|
+
};
|
|
1479
|
+
const readAppliedMigrationsStateFromStore = async (adapter, stateFilePath) => {
|
|
1480
|
+
if (supportsDatabaseMigrationState(adapter)) return await adapter.readAppliedMigrationsState();
|
|
1481
|
+
return readAppliedMigrationsState(stateFilePath);
|
|
1482
|
+
};
|
|
1483
|
+
const writeAppliedMigrationsState = (stateFilePath, state) => {
|
|
1484
|
+
const directory = dirname(stateFilePath);
|
|
1485
|
+
if (!existsSync(directory)) mkdirSync(directory, { recursive: true });
|
|
1486
|
+
writeFileSync(stateFilePath, JSON.stringify(state, null, 2));
|
|
1487
|
+
};
|
|
1488
|
+
const writeAppliedMigrationsStateToStore = async (adapter, stateFilePath, state) => {
|
|
1489
|
+
if (supportsDatabaseMigrationState(adapter)) {
|
|
1490
|
+
await adapter.writeAppliedMigrationsState(state);
|
|
1491
|
+
return;
|
|
1492
|
+
}
|
|
1493
|
+
writeAppliedMigrationsState(stateFilePath, state);
|
|
1494
|
+
};
|
|
1495
|
+
const isMigrationApplied = (state, identity, checksum) => {
|
|
1496
|
+
const matched = state.migrations.find((migration) => migration.id === identity);
|
|
1497
|
+
if (!matched) return false;
|
|
1498
|
+
if (checksum && matched.checksum) return matched.checksum === checksum;
|
|
1499
|
+
if (checksum && !matched.checksum) return false;
|
|
1500
|
+
return true;
|
|
1501
|
+
};
|
|
1502
|
+
const findAppliedMigration = (state, identity) => {
|
|
1503
|
+
return state.migrations.find((migration) => migration.id === identity);
|
|
1504
|
+
};
|
|
1505
|
+
const markMigrationApplied = (state, entry) => {
|
|
1506
|
+
const next = state.migrations.filter((migration) => migration.id !== entry.id);
|
|
1507
|
+
next.push(entry);
|
|
1508
|
+
return {
|
|
1509
|
+
version: 1,
|
|
1510
|
+
migrations: next,
|
|
1511
|
+
runs: state.runs ?? []
|
|
1512
|
+
};
|
|
1513
|
+
};
|
|
1514
|
+
const removeAppliedMigration = (state, identity) => {
|
|
1515
|
+
return {
|
|
1516
|
+
version: 1,
|
|
1517
|
+
migrations: state.migrations.filter((migration) => migration.id !== identity),
|
|
1518
|
+
runs: (state.runs ?? []).map((run) => ({
|
|
1519
|
+
...run,
|
|
1520
|
+
migrationIds: run.migrationIds.filter((id) => id !== identity)
|
|
1521
|
+
})).filter((run) => run.migrationIds.length > 0)
|
|
1522
|
+
};
|
|
1523
|
+
};
|
|
1524
|
+
const buildMigrationRunId = () => {
|
|
1525
|
+
return `run_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`;
|
|
1526
|
+
};
|
|
1527
|
+
const markMigrationRun = (state, run) => {
|
|
1528
|
+
const nextRuns = (state.runs ?? []).filter((existing) => existing.id !== run.id);
|
|
1529
|
+
nextRuns.push(run);
|
|
1530
|
+
return {
|
|
1531
|
+
version: 1,
|
|
1532
|
+
migrations: state.migrations,
|
|
1533
|
+
runs: nextRuns
|
|
1534
|
+
};
|
|
1535
|
+
};
|
|
1536
|
+
const getLastMigrationRun = (state) => {
|
|
1537
|
+
const runs = state.runs ?? [];
|
|
1538
|
+
if (runs.length === 0) return void 0;
|
|
1539
|
+
return runs.map((run, index) => ({
|
|
1540
|
+
run,
|
|
1541
|
+
index
|
|
1542
|
+
})).sort((left, right) => {
|
|
1543
|
+
const appliedAtOrder = right.run.appliedAt.localeCompare(left.run.appliedAt);
|
|
1544
|
+
if (appliedAtOrder !== 0) return appliedAtOrder;
|
|
1545
|
+
return right.index - left.index;
|
|
1546
|
+
})[0]?.run;
|
|
1547
|
+
};
|
|
1548
|
+
const getLatestAppliedMigrations = (state, steps) => {
|
|
1549
|
+
return state.migrations.map((migration, index) => ({
|
|
1550
|
+
migration,
|
|
1551
|
+
index
|
|
1552
|
+
})).sort((left, right) => {
|
|
1553
|
+
const appliedAtOrder = right.migration.appliedAt.localeCompare(left.migration.appliedAt);
|
|
1554
|
+
if (appliedAtOrder !== 0) return appliedAtOrder;
|
|
1555
|
+
return right.index - left.index;
|
|
1556
|
+
}).slice(0, Math.max(0, steps)).map((entry) => entry.migration);
|
|
1557
|
+
};
|
|
1558
|
+
|
|
1559
|
+
//#endregion
|
|
1560
|
+
//#region src/helpers/column-mappings.ts
|
|
1561
|
+
let cachedColumnMappingsPath;
|
|
1562
|
+
let cachedColumnMappingsState;
|
|
1563
|
+
const resolvePersistedMetadataFeatures = (features) => {
|
|
1564
|
+
return {
|
|
1565
|
+
persistedColumnMappings: features?.persistedColumnMappings !== false,
|
|
1566
|
+
persistedEnums: features?.persistedEnums !== false
|
|
1567
|
+
};
|
|
1568
|
+
};
|
|
1569
|
+
const createEmptyPersistedColumnMappingsState = () => ({
|
|
1570
|
+
version: 1,
|
|
1571
|
+
tables: {}
|
|
1572
|
+
});
|
|
1573
|
+
const resolveColumnMappingsFilePath = (cwd, configuredPath) => {
|
|
1574
|
+
if (configuredPath && configuredPath.trim().length > 0) return resolve(configuredPath);
|
|
1575
|
+
return join(cwd, ".arkormx", "column-mappings.json");
|
|
1576
|
+
};
|
|
1577
|
+
const normalizePersistedEnumValues = (values) => {
|
|
1578
|
+
if (!Array.isArray(values)) return [];
|
|
1579
|
+
return values.filter((value) => typeof value === "string" && value.trim().length > 0);
|
|
1580
|
+
};
|
|
1581
|
+
const normalizeLegacyTableColumns = (columns) => {
|
|
1582
|
+
return Object.entries(columns).reduce((mapped, [attribute, column]) => {
|
|
1583
|
+
if (attribute.trim().length === 0) return mapped;
|
|
1584
|
+
if (typeof column !== "string" || column.trim().length === 0) return mapped;
|
|
1585
|
+
mapped[attribute] = column;
|
|
1586
|
+
return mapped;
|
|
1587
|
+
}, {});
|
|
1588
|
+
};
|
|
1589
|
+
const normalizePersistedTableMetadata = (table) => {
|
|
1590
|
+
if (!table || typeof table !== "object" || Array.isArray(table)) return {
|
|
1591
|
+
columns: {},
|
|
1592
|
+
enums: {}
|
|
1593
|
+
};
|
|
1594
|
+
const candidate = table;
|
|
1595
|
+
if (!(Object.prototype.hasOwnProperty.call(candidate, "columns") || Object.prototype.hasOwnProperty.call(candidate, "enums"))) return {
|
|
1596
|
+
columns: normalizeLegacyTableColumns(candidate),
|
|
1597
|
+
enums: {}
|
|
1598
|
+
};
|
|
1599
|
+
return {
|
|
1600
|
+
columns: normalizeLegacyTableColumns(candidate.columns ?? {}),
|
|
1601
|
+
enums: Object.entries(candidate.enums ?? {}).reduce((all, [columnName, values]) => {
|
|
1602
|
+
if (columnName.trim().length === 0) return all;
|
|
1603
|
+
const normalizedValues = normalizePersistedEnumValues(values);
|
|
1604
|
+
if (normalizedValues.length > 0) all[columnName] = normalizedValues;
|
|
1605
|
+
return all;
|
|
1606
|
+
}, {})
|
|
1607
|
+
};
|
|
1608
|
+
};
|
|
1609
|
+
const normalizePersistedColumnMappingsState = (state) => {
|
|
1610
|
+
return {
|
|
1611
|
+
version: 1,
|
|
1612
|
+
tables: Object.entries(state?.tables ?? {}).reduce((all, [tableName, tableMetadata]) => {
|
|
1613
|
+
if (tableName.trim().length === 0) return all;
|
|
1614
|
+
const normalized = normalizePersistedTableMetadata(tableMetadata);
|
|
1615
|
+
if (Object.keys(normalized.columns).length > 0 || Object.keys(normalized.enums).length > 0) all[tableName] = normalized;
|
|
1616
|
+
return all;
|
|
1617
|
+
}, {})
|
|
1618
|
+
};
|
|
1619
|
+
};
|
|
1620
|
+
const buildPersistedFeatureDisabledError = (feature, table) => {
|
|
1621
|
+
return new ArkormException(`Table [${table}] requires ${feature === "persistedColumnMappings" ? "persisted column mappings" : "persisted enum metadata"}, but ${feature === "persistedColumnMappings" ? "features.persistedColumnMappings" : "features.persistedEnums"} is disabled in arkormx.config.*.`, {
|
|
1622
|
+
operation: "metadata.persisted",
|
|
1623
|
+
meta: {
|
|
1624
|
+
feature,
|
|
1625
|
+
table
|
|
1626
|
+
}
|
|
1627
|
+
});
|
|
1628
|
+
};
|
|
1629
|
+
const assertPersistedTableMetadataEnabled = (table, metadata, features, strict) => {
|
|
1630
|
+
if (!strict) return;
|
|
1631
|
+
if (!features.persistedColumnMappings && Object.keys(metadata.columns).length > 0) throw buildPersistedFeatureDisabledError("persistedColumnMappings", table);
|
|
1632
|
+
if (!features.persistedEnums && Object.keys(metadata.enums).length > 0) throw buildPersistedFeatureDisabledError("persistedEnums", table);
|
|
1633
|
+
};
|
|
1634
|
+
const buildEnumUnionType = (values) => {
|
|
1635
|
+
return values.map((value) => {
|
|
1636
|
+
return `'${value.replace(/'/g, String.raw`\'`)}'`;
|
|
1637
|
+
}).join(" | ");
|
|
1638
|
+
};
|
|
1639
|
+
const resetPersistedColumnMappingsCache = () => {
|
|
1640
|
+
cachedColumnMappingsPath = void 0;
|
|
1641
|
+
cachedColumnMappingsState = void 0;
|
|
1642
|
+
};
|
|
1643
|
+
const readPersistedColumnMappingsState = (filePath) => {
|
|
1644
|
+
if (cachedColumnMappingsPath === filePath && cachedColumnMappingsState) return cachedColumnMappingsState;
|
|
1645
|
+
if (!existsSync(filePath)) {
|
|
1646
|
+
const empty = createEmptyPersistedColumnMappingsState();
|
|
1647
|
+
cachedColumnMappingsPath = filePath;
|
|
1648
|
+
cachedColumnMappingsState = empty;
|
|
1649
|
+
return empty;
|
|
1650
|
+
}
|
|
1651
|
+
try {
|
|
1652
|
+
const normalized = normalizePersistedColumnMappingsState(JSON.parse(readFileSync(filePath, "utf-8")));
|
|
1653
|
+
cachedColumnMappingsPath = filePath;
|
|
1654
|
+
cachedColumnMappingsState = normalized;
|
|
1655
|
+
return normalized;
|
|
1656
|
+
} catch {
|
|
1657
|
+
const empty = createEmptyPersistedColumnMappingsState();
|
|
1658
|
+
cachedColumnMappingsPath = filePath;
|
|
1659
|
+
cachedColumnMappingsState = empty;
|
|
1660
|
+
return empty;
|
|
1661
|
+
}
|
|
1662
|
+
};
|
|
1663
|
+
const writePersistedColumnMappingsState = (filePath, state) => {
|
|
1664
|
+
const normalized = normalizePersistedColumnMappingsState(state);
|
|
1665
|
+
const directory = dirname(filePath);
|
|
1666
|
+
if (!existsSync(directory)) mkdirSync(directory, { recursive: true });
|
|
1667
|
+
writeFileSync(filePath, JSON.stringify(normalized, null, 2));
|
|
1668
|
+
cachedColumnMappingsPath = filePath;
|
|
1669
|
+
cachedColumnMappingsState = normalized;
|
|
1670
|
+
};
|
|
1671
|
+
const deletePersistedColumnMappingsState = (filePath) => {
|
|
1672
|
+
if (existsSync(filePath)) rmSync(filePath, { force: true });
|
|
1673
|
+
resetPersistedColumnMappingsCache();
|
|
1674
|
+
};
|
|
1675
|
+
const getPersistedTableMetadata = (table, options = {}) => {
|
|
1676
|
+
const metadata = readPersistedColumnMappingsState(resolveColumnMappingsFilePath(options.cwd ?? process.cwd(), options.configuredPath)).tables[table] ?? {
|
|
1677
|
+
columns: {},
|
|
1678
|
+
enums: {}
|
|
1679
|
+
};
|
|
1680
|
+
assertPersistedTableMetadataEnabled(table, metadata, options.features ?? resolvePersistedMetadataFeatures(), options.strict ?? false);
|
|
1681
|
+
return {
|
|
1682
|
+
columns: { ...metadata.columns },
|
|
1683
|
+
enums: Object.entries(metadata.enums).reduce((all, [columnName, values]) => {
|
|
1684
|
+
all[columnName] = [...values];
|
|
1685
|
+
return all;
|
|
1686
|
+
}, {})
|
|
1687
|
+
};
|
|
1688
|
+
};
|
|
1689
|
+
const applyMappedColumn = (tableColumns, column, features, table) => {
|
|
1690
|
+
if (typeof column.map === "string" && column.map.trim().length > 0 && column.map !== column.name) {
|
|
1691
|
+
if (!features.persistedColumnMappings) throw buildPersistedFeatureDisabledError("persistedColumnMappings", table);
|
|
1692
|
+
tableColumns[column.name] = column.map;
|
|
1693
|
+
return;
|
|
1694
|
+
}
|
|
1695
|
+
delete tableColumns[column.name];
|
|
1696
|
+
};
|
|
1697
|
+
const applyEnumColumn = (tableEnums, column, features, table) => {
|
|
1698
|
+
const values = column.enumValues ?? [];
|
|
1699
|
+
if (column.type === "enum" && values.length > 0) {
|
|
1700
|
+
if (!features.persistedEnums) throw buildPersistedFeatureDisabledError("persistedEnums", table);
|
|
1701
|
+
tableEnums[column.name] = [...values];
|
|
1702
|
+
return;
|
|
1703
|
+
}
|
|
1704
|
+
delete tableEnums[column.name];
|
|
1705
|
+
};
|
|
1706
|
+
const removePersistedColumnMetadata = (tableMetadata, columnName) => {
|
|
1707
|
+
delete tableMetadata.columns[columnName];
|
|
1708
|
+
delete tableMetadata.enums[columnName];
|
|
1709
|
+
Object.entries(tableMetadata.columns).forEach(([attribute, mappedColumn]) => {
|
|
1710
|
+
if (mappedColumn === columnName) delete tableMetadata.columns[attribute];
|
|
1711
|
+
});
|
|
1712
|
+
};
|
|
1713
|
+
const applyOperationsToPersistedColumnMappingsState = (state, operations, features = resolvePersistedMetadataFeatures()) => {
|
|
1714
|
+
const nextTables = Object.entries(state.tables).reduce((all, [table, metadata]) => {
|
|
1715
|
+
all[table] = {
|
|
1716
|
+
columns: { ...metadata.columns },
|
|
1717
|
+
enums: Object.entries(metadata.enums).reduce((nextEnums, [columnName, values]) => {
|
|
1718
|
+
nextEnums[columnName] = [...values];
|
|
1719
|
+
return nextEnums;
|
|
1720
|
+
}, {})
|
|
1721
|
+
};
|
|
1722
|
+
return all;
|
|
1723
|
+
}, {});
|
|
1724
|
+
operations.forEach((operation) => {
|
|
1725
|
+
if (operation.type === "createTable") {
|
|
1726
|
+
const tableMetadata = nextTables[operation.table] ?? {
|
|
1727
|
+
columns: {},
|
|
1728
|
+
enums: {}
|
|
1729
|
+
};
|
|
1730
|
+
operation.columns.forEach((column) => {
|
|
1731
|
+
applyMappedColumn(tableMetadata.columns, column, features, operation.table);
|
|
1732
|
+
applyEnumColumn(tableMetadata.enums, column, features, operation.table);
|
|
1733
|
+
});
|
|
1734
|
+
if (Object.keys(tableMetadata.columns).length > 0 || Object.keys(tableMetadata.enums).length > 0) nextTables[operation.table] = tableMetadata;
|
|
1735
|
+
else delete nextTables[operation.table];
|
|
1736
|
+
return;
|
|
1737
|
+
}
|
|
1738
|
+
if (operation.type === "alterTable") {
|
|
1739
|
+
const tableMetadata = nextTables[operation.table] ?? {
|
|
1740
|
+
columns: {},
|
|
1741
|
+
enums: {}
|
|
1742
|
+
};
|
|
1743
|
+
operation.addColumns.forEach((column) => {
|
|
1744
|
+
applyMappedColumn(tableMetadata.columns, column, features, operation.table);
|
|
1745
|
+
applyEnumColumn(tableMetadata.enums, column, features, operation.table);
|
|
1746
|
+
});
|
|
1747
|
+
operation.dropColumns.forEach((columnName) => {
|
|
1748
|
+
removePersistedColumnMetadata(tableMetadata, columnName);
|
|
1749
|
+
});
|
|
1750
|
+
if (Object.keys(tableMetadata.columns).length > 0 || Object.keys(tableMetadata.enums).length > 0) nextTables[operation.table] = tableMetadata;
|
|
1751
|
+
else delete nextTables[operation.table];
|
|
1752
|
+
return;
|
|
1753
|
+
}
|
|
1754
|
+
delete nextTables[operation.table];
|
|
1755
|
+
});
|
|
1756
|
+
return {
|
|
1757
|
+
version: 1,
|
|
1758
|
+
tables: nextTables
|
|
1759
|
+
};
|
|
1760
|
+
};
|
|
1761
|
+
const rebuildPersistedColumnMappingsState = async (state, availableMigrations, features = resolvePersistedMetadataFeatures()) => {
|
|
1762
|
+
const availableByIdentity = new Map(availableMigrations.map(([migrationClass, file]) => [buildMigrationIdentity(file, migrationClass.name), migrationClass]));
|
|
1763
|
+
let nextState = createEmptyPersistedColumnMappingsState();
|
|
1764
|
+
const orderedMigrations = state.migrations.map((migration, index) => ({
|
|
1765
|
+
migration,
|
|
1766
|
+
index
|
|
1767
|
+
})).sort((left, right) => {
|
|
1768
|
+
const appliedAtOrder = left.migration.appliedAt.localeCompare(right.migration.appliedAt);
|
|
1769
|
+
if (appliedAtOrder !== 0) return appliedAtOrder;
|
|
1770
|
+
return left.index - right.index;
|
|
1771
|
+
});
|
|
1772
|
+
for (const { migration } of orderedMigrations) {
|
|
1773
|
+
const migrationClass = availableByIdentity.get(migration.id);
|
|
1774
|
+
if (!migrationClass) throw new ArkormException(`Unable to rebuild persisted column mappings because migration [${migration.id}] could not be resolved from the current migration files.`, {
|
|
1775
|
+
operation: "migration.columnMappings",
|
|
1776
|
+
meta: {
|
|
1777
|
+
migrationId: migration.id,
|
|
1778
|
+
file: migration.file,
|
|
1779
|
+
className: migration.className
|
|
1780
|
+
}
|
|
1781
|
+
});
|
|
1782
|
+
const operations = await getMigrationPlan(migrationClass, "up");
|
|
1783
|
+
nextState = applyOperationsToPersistedColumnMappingsState(nextState, operations, features);
|
|
1784
|
+
}
|
|
1785
|
+
return nextState;
|
|
1786
|
+
};
|
|
1787
|
+
const syncPersistedColumnMappingsFromState = async (cwd, state, availableMigrations, features = resolvePersistedMetadataFeatures()) => {
|
|
1788
|
+
const filePath = resolveColumnMappingsFilePath(cwd);
|
|
1789
|
+
const nextState = await rebuildPersistedColumnMappingsState(state, availableMigrations, features);
|
|
1790
|
+
if (Object.keys(nextState.tables).length === 0) {
|
|
1791
|
+
deletePersistedColumnMappingsState(filePath);
|
|
1792
|
+
return;
|
|
1793
|
+
}
|
|
1794
|
+
writePersistedColumnMappingsState(filePath, nextState);
|
|
1795
|
+
};
|
|
1796
|
+
const validatePersistedMetadataFeaturesForMigrations = async (migrations, features = resolvePersistedMetadataFeatures()) => {
|
|
1797
|
+
let nextState = createEmptyPersistedColumnMappingsState();
|
|
1798
|
+
for (const [migrationClass] of migrations) {
|
|
1799
|
+
const operations = await getMigrationPlan(migrationClass, "up");
|
|
1800
|
+
nextState = applyOperationsToPersistedColumnMappingsState(nextState, operations, features);
|
|
1801
|
+
}
|
|
1802
|
+
};
|
|
1803
|
+
const getPersistedEnumTsType = (values) => {
|
|
1804
|
+
return buildEnumUnionType(values);
|
|
1805
|
+
};
|
|
1806
|
+
|
|
1439
1807
|
//#endregion
|
|
1440
1808
|
//#region src/helpers/runtime-module-loader.ts
|
|
1441
1809
|
var RuntimeModuleLoader = class {
|
|
@@ -1463,6 +1831,10 @@ const resolveDefaultStubsPath = () => {
|
|
|
1463
1831
|
return path.join(process.cwd(), "stubs");
|
|
1464
1832
|
};
|
|
1465
1833
|
const baseConfig = {
|
|
1834
|
+
features: {
|
|
1835
|
+
persistedColumnMappings: true,
|
|
1836
|
+
persistedEnums: true
|
|
1837
|
+
},
|
|
1466
1838
|
paths: {
|
|
1467
1839
|
stubs: resolveDefaultStubsPath(),
|
|
1468
1840
|
seeders: path.join(process.cwd(), "database", "seeders"),
|
|
@@ -1475,6 +1847,7 @@ const baseConfig = {
|
|
|
1475
1847
|
};
|
|
1476
1848
|
const userConfig = {
|
|
1477
1849
|
...baseConfig,
|
|
1850
|
+
features: { ...baseConfig.features ?? {} },
|
|
1478
1851
|
paths: { ...baseConfig.paths ?? {} }
|
|
1479
1852
|
};
|
|
1480
1853
|
let runtimeConfigLoaded = false;
|
|
@@ -1497,6 +1870,15 @@ const mergePathConfig = (paths) => {
|
|
|
1497
1870
|
...incoming
|
|
1498
1871
|
};
|
|
1499
1872
|
};
|
|
1873
|
+
const mergeFeatureConfig = (features) => {
|
|
1874
|
+
const defaults = baseConfig.features ?? {};
|
|
1875
|
+
const current = userConfig.features ?? {};
|
|
1876
|
+
return {
|
|
1877
|
+
...defaults,
|
|
1878
|
+
...current,
|
|
1879
|
+
...features ?? {}
|
|
1880
|
+
};
|
|
1881
|
+
};
|
|
1500
1882
|
const bindAdapterToModels = (adapter, models) => {
|
|
1501
1883
|
models.forEach((model) => {
|
|
1502
1884
|
model.setAdapter(adapter);
|
|
@@ -1522,6 +1904,7 @@ const getUserConfig = (key) => {
|
|
|
1522
1904
|
const configureArkormRuntime = (prisma, options = {}) => {
|
|
1523
1905
|
const nextConfig = {
|
|
1524
1906
|
...userConfig,
|
|
1907
|
+
features: mergeFeatureConfig(options.features),
|
|
1525
1908
|
paths: mergePathConfig(options.paths)
|
|
1526
1909
|
};
|
|
1527
1910
|
nextConfig.prisma = prisma;
|
|
@@ -1566,6 +1949,7 @@ const resolveAndApplyConfig = (imported) => {
|
|
|
1566
1949
|
configureArkormRuntime(config.prisma, {
|
|
1567
1950
|
adapter: config.adapter,
|
|
1568
1951
|
boot: config.boot,
|
|
1952
|
+
features: config.features,
|
|
1569
1953
|
pagination: config.pagination,
|
|
1570
1954
|
paths: config.paths,
|
|
1571
1955
|
outputExt: config.outputExt
|
|
@@ -2157,6 +2541,35 @@ var CliApp = class {
|
|
|
2157
2541
|
skipped
|
|
2158
2542
|
};
|
|
2159
2543
|
}
|
|
2544
|
+
applyPersistedFieldMetadata(structure) {
|
|
2545
|
+
const persistedMetadata = getPersistedTableMetadata(structure.table, {
|
|
2546
|
+
features: resolvePersistedMetadataFeatures(this.getConfig("features")),
|
|
2547
|
+
strict: true
|
|
2548
|
+
});
|
|
2549
|
+
if (Object.keys(persistedMetadata.columns).length === 0 && Object.keys(persistedMetadata.enums).length === 0) return structure;
|
|
2550
|
+
const attributesByColumn = Object.entries(persistedMetadata.columns).reduce((all, [attribute, column]) => {
|
|
2551
|
+
all[column] = attribute;
|
|
2552
|
+
return all;
|
|
2553
|
+
}, {});
|
|
2554
|
+
return {
|
|
2555
|
+
...structure,
|
|
2556
|
+
fields: structure.fields.map((field) => {
|
|
2557
|
+
const logicalName = attributesByColumn[field.name] ?? field.name;
|
|
2558
|
+
const enumValues = persistedMetadata.enums[logicalName] ?? persistedMetadata.enums[field.name];
|
|
2559
|
+
if (!enumValues || enumValues.length === 0) return {
|
|
2560
|
+
...field,
|
|
2561
|
+
name: logicalName
|
|
2562
|
+
};
|
|
2563
|
+
const enumType = getPersistedEnumTsType(enumValues);
|
|
2564
|
+
const isArray = /^Array<.+>$/.test(field.type);
|
|
2565
|
+
return {
|
|
2566
|
+
...field,
|
|
2567
|
+
name: logicalName,
|
|
2568
|
+
type: isArray ? `Array<${enumType}>` : enumType
|
|
2569
|
+
};
|
|
2570
|
+
})
|
|
2571
|
+
};
|
|
2572
|
+
}
|
|
2160
2573
|
/**
|
|
2161
2574
|
* Parse Prisma enum definitions from a schema and return their member names.
|
|
2162
2575
|
*
|
|
@@ -2315,7 +2728,10 @@ var CliApp = class {
|
|
|
2315
2728
|
return all;
|
|
2316
2729
|
}, /* @__PURE__ */ new Map());
|
|
2317
2730
|
const discovered = await adapter.introspectModels({ tables: [...new Set([...sources.values()].map((source) => source.table))] });
|
|
2318
|
-
const structuresByTable = new Map(discovered.map((model) =>
|
|
2731
|
+
const structuresByTable = new Map(discovered.map((model) => {
|
|
2732
|
+
const enriched = this.applyPersistedFieldMetadata(model);
|
|
2733
|
+
return [enriched.table, enriched];
|
|
2734
|
+
}));
|
|
2319
2735
|
const result = this.syncModelFiles(modelFiles, (filePath) => {
|
|
2320
2736
|
const parsed = sources.get(filePath);
|
|
2321
2737
|
return parsed ? structuresByTable.get(parsed.table) : void 0;
|
|
@@ -2529,126 +2945,6 @@ var MakeSeederCommand = class extends Command {
|
|
|
2529
2945
|
}
|
|
2530
2946
|
};
|
|
2531
2947
|
|
|
2532
|
-
//#endregion
|
|
2533
|
-
//#region src/helpers/migration-history.ts
|
|
2534
|
-
const createEmptyAppliedMigrationsState = () => ({
|
|
2535
|
-
version: 1,
|
|
2536
|
-
migrations: [],
|
|
2537
|
-
runs: []
|
|
2538
|
-
});
|
|
2539
|
-
const supportsDatabaseMigrationState = (adapter) => {
|
|
2540
|
-
return typeof adapter?.readAppliedMigrationsState === "function" && typeof adapter?.writeAppliedMigrationsState === "function";
|
|
2541
|
-
};
|
|
2542
|
-
const resolveMigrationStateFilePath = (cwd, configuredPath) => {
|
|
2543
|
-
if (configuredPath && configuredPath.trim().length > 0) return resolve(configuredPath);
|
|
2544
|
-
return join(cwd, ".arkormx", "migrations.applied.json");
|
|
2545
|
-
};
|
|
2546
|
-
const buildMigrationIdentity = (filePath, className) => {
|
|
2547
|
-
const fileName = filePath.split("/").pop()?.split("\\").pop() ?? filePath;
|
|
2548
|
-
return `${fileName.slice(0, fileName.length - extname(fileName).length)}:${className}`;
|
|
2549
|
-
};
|
|
2550
|
-
const computeMigrationChecksum = (filePath) => {
|
|
2551
|
-
const source = readFileSync(filePath, "utf-8");
|
|
2552
|
-
return createHash("sha256").update(source).digest("hex");
|
|
2553
|
-
};
|
|
2554
|
-
const readAppliedMigrationsState = (stateFilePath) => {
|
|
2555
|
-
if (!existsSync(stateFilePath)) return createEmptyAppliedMigrationsState();
|
|
2556
|
-
try {
|
|
2557
|
-
const parsed = JSON.parse(readFileSync(stateFilePath, "utf-8"));
|
|
2558
|
-
if (!Array.isArray(parsed.migrations)) return createEmptyAppliedMigrationsState();
|
|
2559
|
-
return {
|
|
2560
|
-
version: 1,
|
|
2561
|
-
migrations: parsed.migrations.filter((migration) => {
|
|
2562
|
-
return typeof migration?.id === "string" && typeof migration?.file === "string" && typeof migration?.className === "string" && typeof migration?.appliedAt === "string" && (migration?.checksum === void 0 || typeof migration?.checksum === "string");
|
|
2563
|
-
}),
|
|
2564
|
-
runs: Array.isArray(parsed.runs) ? parsed.runs.filter((run) => {
|
|
2565
|
-
return typeof run?.id === "string" && typeof run?.appliedAt === "string" && Array.isArray(run?.migrationIds) && run.migrationIds.every((item) => typeof item === "string");
|
|
2566
|
-
}) : []
|
|
2567
|
-
};
|
|
2568
|
-
} catch {
|
|
2569
|
-
return createEmptyAppliedMigrationsState();
|
|
2570
|
-
}
|
|
2571
|
-
};
|
|
2572
|
-
const readAppliedMigrationsStateFromStore = async (adapter, stateFilePath) => {
|
|
2573
|
-
if (supportsDatabaseMigrationState(adapter)) return await adapter.readAppliedMigrationsState();
|
|
2574
|
-
return readAppliedMigrationsState(stateFilePath);
|
|
2575
|
-
};
|
|
2576
|
-
const writeAppliedMigrationsState = (stateFilePath, state) => {
|
|
2577
|
-
const directory = dirname(stateFilePath);
|
|
2578
|
-
if (!existsSync(directory)) mkdirSync(directory, { recursive: true });
|
|
2579
|
-
writeFileSync(stateFilePath, JSON.stringify(state, null, 2));
|
|
2580
|
-
};
|
|
2581
|
-
const writeAppliedMigrationsStateToStore = async (adapter, stateFilePath, state) => {
|
|
2582
|
-
if (supportsDatabaseMigrationState(adapter)) {
|
|
2583
|
-
await adapter.writeAppliedMigrationsState(state);
|
|
2584
|
-
return;
|
|
2585
|
-
}
|
|
2586
|
-
writeAppliedMigrationsState(stateFilePath, state);
|
|
2587
|
-
};
|
|
2588
|
-
const isMigrationApplied = (state, identity, checksum) => {
|
|
2589
|
-
const matched = state.migrations.find((migration) => migration.id === identity);
|
|
2590
|
-
if (!matched) return false;
|
|
2591
|
-
if (checksum && matched.checksum) return matched.checksum === checksum;
|
|
2592
|
-
if (checksum && !matched.checksum) return false;
|
|
2593
|
-
return true;
|
|
2594
|
-
};
|
|
2595
|
-
const findAppliedMigration = (state, identity) => {
|
|
2596
|
-
return state.migrations.find((migration) => migration.id === identity);
|
|
2597
|
-
};
|
|
2598
|
-
const markMigrationApplied = (state, entry) => {
|
|
2599
|
-
const next = state.migrations.filter((migration) => migration.id !== entry.id);
|
|
2600
|
-
next.push(entry);
|
|
2601
|
-
return {
|
|
2602
|
-
version: 1,
|
|
2603
|
-
migrations: next,
|
|
2604
|
-
runs: state.runs ?? []
|
|
2605
|
-
};
|
|
2606
|
-
};
|
|
2607
|
-
const removeAppliedMigration = (state, identity) => {
|
|
2608
|
-
return {
|
|
2609
|
-
version: 1,
|
|
2610
|
-
migrations: state.migrations.filter((migration) => migration.id !== identity),
|
|
2611
|
-
runs: (state.runs ?? []).map((run) => ({
|
|
2612
|
-
...run,
|
|
2613
|
-
migrationIds: run.migrationIds.filter((id) => id !== identity)
|
|
2614
|
-
})).filter((run) => run.migrationIds.length > 0)
|
|
2615
|
-
};
|
|
2616
|
-
};
|
|
2617
|
-
const buildMigrationRunId = () => {
|
|
2618
|
-
return `run_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`;
|
|
2619
|
-
};
|
|
2620
|
-
const markMigrationRun = (state, run) => {
|
|
2621
|
-
const nextRuns = (state.runs ?? []).filter((existing) => existing.id !== run.id);
|
|
2622
|
-
nextRuns.push(run);
|
|
2623
|
-
return {
|
|
2624
|
-
version: 1,
|
|
2625
|
-
migrations: state.migrations,
|
|
2626
|
-
runs: nextRuns
|
|
2627
|
-
};
|
|
2628
|
-
};
|
|
2629
|
-
const getLastMigrationRun = (state) => {
|
|
2630
|
-
const runs = state.runs ?? [];
|
|
2631
|
-
if (runs.length === 0) return void 0;
|
|
2632
|
-
return runs.map((run, index) => ({
|
|
2633
|
-
run,
|
|
2634
|
-
index
|
|
2635
|
-
})).sort((left, right) => {
|
|
2636
|
-
const appliedAtOrder = right.run.appliedAt.localeCompare(left.run.appliedAt);
|
|
2637
|
-
if (appliedAtOrder !== 0) return appliedAtOrder;
|
|
2638
|
-
return right.index - left.index;
|
|
2639
|
-
})[0]?.run;
|
|
2640
|
-
};
|
|
2641
|
-
const getLatestAppliedMigrations = (state, steps) => {
|
|
2642
|
-
return state.migrations.map((migration, index) => ({
|
|
2643
|
-
migration,
|
|
2644
|
-
index
|
|
2645
|
-
})).sort((left, right) => {
|
|
2646
|
-
const appliedAtOrder = right.migration.appliedAt.localeCompare(left.migration.appliedAt);
|
|
2647
|
-
if (appliedAtOrder !== 0) return appliedAtOrder;
|
|
2648
|
-
return right.index - left.index;
|
|
2649
|
-
}).slice(0, Math.max(0, steps)).map((entry) => entry.migration);
|
|
2650
|
-
};
|
|
2651
|
-
|
|
2652
2948
|
//#endregion
|
|
2653
2949
|
//#region src/database/Migration.ts
|
|
2654
2950
|
const MIGRATION_BRAND = Symbol.for("arkormx.migration");
|
|
@@ -2706,6 +3002,7 @@ var MigrateCommand = class extends Command {
|
|
|
2706
3002
|
let appliedState = await readAppliedMigrationsStateFromStore(this.app.getConfig("adapter"), stateFilePath);
|
|
2707
3003
|
const adapter = this.app.getConfig("adapter");
|
|
2708
3004
|
const useDatabaseMigrations = supportsDatabaseMigrationExecution(adapter);
|
|
3005
|
+
const persistedFeatures = resolvePersistedMetadataFeatures(this.app.getConfig("features"));
|
|
2709
3006
|
const skipped = [];
|
|
2710
3007
|
const changed = [];
|
|
2711
3008
|
const pending = classes.filter(([migrationClass, file]) => {
|
|
@@ -2724,9 +3021,21 @@ var MigrateCommand = class extends Command {
|
|
|
2724
3021
|
this.success(this.app.splitLogger("Changed", `${file} (${migrationClass.name})`));
|
|
2725
3022
|
});
|
|
2726
3023
|
if (pending.length === 0) {
|
|
3024
|
+
if (appliedState) try {
|
|
3025
|
+
await syncPersistedColumnMappingsFromState(process.cwd(), appliedState, await this.loadAllMigrations(migrationsDir), persistedFeatures);
|
|
3026
|
+
} catch (error) {
|
|
3027
|
+
this.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
3028
|
+
return;
|
|
3029
|
+
}
|
|
2727
3030
|
this.success("No pending migration classes to apply.");
|
|
2728
3031
|
return;
|
|
2729
3032
|
}
|
|
3033
|
+
if (useDatabaseMigrations) try {
|
|
3034
|
+
await validatePersistedMetadataFeaturesForMigrations(pending, persistedFeatures);
|
|
3035
|
+
} catch (error) {
|
|
3036
|
+
this.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
3037
|
+
return;
|
|
3038
|
+
}
|
|
2730
3039
|
for (const [MigrationClassItem] of pending) {
|
|
2731
3040
|
if (useDatabaseMigrations) {
|
|
2732
3041
|
await applyMigrationToDatabase(adapter, MigrationClassItem);
|
|
@@ -2756,6 +3065,12 @@ var MigrateCommand = class extends Command {
|
|
|
2756
3065
|
migrationIds: runAppliedIds
|
|
2757
3066
|
});
|
|
2758
3067
|
await writeAppliedMigrationsStateToStore(adapter, stateFilePath, appliedState);
|
|
3068
|
+
try {
|
|
3069
|
+
await syncPersistedColumnMappingsFromState(process.cwd(), appliedState, await this.loadAllMigrations(migrationsDir), persistedFeatures);
|
|
3070
|
+
} catch (error) {
|
|
3071
|
+
this.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
3072
|
+
return;
|
|
3073
|
+
}
|
|
2759
3074
|
}
|
|
2760
3075
|
if (!useDatabaseMigrations && !this.option("skip-generate")) runPrismaCommand(["generate"], process.cwd());
|
|
2761
3076
|
if (!useDatabaseMigrations && !this.option("skip-migrate")) if (this.option("deploy")) runPrismaCommand(["migrate", "deploy"], process.cwd());
|
|
@@ -2835,12 +3150,24 @@ var MigrateFreshCommand = class extends Command {
|
|
|
2835
3150
|
if (!existsSync(migrationsDir)) return void this.error(`Error: Migrations directory not found: ${this.app.formatPathForLog(configuredMigrationsDir)}`);
|
|
2836
3151
|
const adapter = this.app.getConfig("adapter");
|
|
2837
3152
|
const useDatabaseMigrations = supportsDatabaseMigrationExecution(adapter);
|
|
3153
|
+
const persistedFeatures = resolvePersistedMetadataFeatures(this.app.getConfig("features"));
|
|
2838
3154
|
const schemaPath = this.option("schema") ? resolve(String(this.option("schema"))) : join(process.cwd(), "prisma", "schema.prisma");
|
|
2839
3155
|
const stateFilePath = resolveMigrationStateFilePath(process.cwd(), this.option("state-file") ? String(this.option("state-file")) : void 0);
|
|
2840
3156
|
const migrations = await this.loadAllMigrations(migrationsDir);
|
|
2841
3157
|
if (migrations.length === 0) return void this.error("Error: No migration classes found to run.");
|
|
2842
|
-
if (
|
|
2843
|
-
|
|
3158
|
+
if (useDatabaseMigrations) try {
|
|
3159
|
+
await validatePersistedMetadataFeaturesForMigrations(migrations, persistedFeatures);
|
|
3160
|
+
} catch (error) {
|
|
3161
|
+
this.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
3162
|
+
return;
|
|
3163
|
+
}
|
|
3164
|
+
if (useDatabaseMigrations) {
|
|
3165
|
+
if (!supportsDatabaseReset(adapter)) {
|
|
3166
|
+
this.error("Error: Your current database adapter does not support database reset.");
|
|
3167
|
+
return;
|
|
3168
|
+
}
|
|
3169
|
+
await adapter.resetDatabase();
|
|
3170
|
+
} else {
|
|
2844
3171
|
if (!existsSync(schemaPath)) return void this.error(`Error: Prisma schema file not found: ${this.app.formatPathForLog(schemaPath)}`);
|
|
2845
3172
|
writeFileSync(schemaPath, stripPrismaSchemaModelsAndEnums(readFileSync(schemaPath, "utf-8")));
|
|
2846
3173
|
}
|
|
@@ -2869,6 +3196,12 @@ var MigrateFreshCommand = class extends Command {
|
|
|
2869
3196
|
migrationIds: appliedState.migrations.map((migration) => migration.id)
|
|
2870
3197
|
});
|
|
2871
3198
|
await writeAppliedMigrationsStateToStore(adapter, stateFilePath, appliedState);
|
|
3199
|
+
try {
|
|
3200
|
+
await syncPersistedColumnMappingsFromState(process.cwd(), appliedState, migrations, persistedFeatures);
|
|
3201
|
+
} catch (error) {
|
|
3202
|
+
this.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
3203
|
+
return;
|
|
3204
|
+
}
|
|
2872
3205
|
if (!useDatabaseMigrations) {
|
|
2873
3206
|
const schemaArgs = this.option("schema") ? ["--schema", schemaPath] : [];
|
|
2874
3207
|
if (!this.option("skip-generate")) runPrismaCommand(["generate", ...schemaArgs], process.cwd());
|
|
@@ -2927,6 +3260,7 @@ var MigrateRollbackCommand = class extends Command {
|
|
|
2927
3260
|
const stateFilePath = resolveMigrationStateFilePath(process.cwd(), this.option("state-file") ? String(this.option("state-file")) : void 0);
|
|
2928
3261
|
const adapter = this.app.getConfig("adapter");
|
|
2929
3262
|
const useDatabaseMigrations = supportsDatabaseMigrationExecution(adapter);
|
|
3263
|
+
const persistedFeatures = resolvePersistedMetadataFeatures(this.app.getConfig("features"));
|
|
2930
3264
|
let appliedState = await readAppliedMigrationsStateFromStore(adapter, stateFilePath);
|
|
2931
3265
|
const stepOption = this.option("step");
|
|
2932
3266
|
const stepCount = stepOption == null ? void 0 : Number(stepOption);
|
|
@@ -2964,6 +3298,12 @@ var MigrateRollbackCommand = class extends Command {
|
|
|
2964
3298
|
appliedState = removeAppliedMigration(appliedState, identity);
|
|
2965
3299
|
}
|
|
2966
3300
|
await writeAppliedMigrationsStateToStore(adapter, stateFilePath, appliedState);
|
|
3301
|
+
try {
|
|
3302
|
+
await syncPersistedColumnMappingsFromState(process.cwd(), appliedState, available, persistedFeatures);
|
|
3303
|
+
} catch (error) {
|
|
3304
|
+
this.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
3305
|
+
return;
|
|
3306
|
+
}
|
|
2967
3307
|
if (!useDatabaseMigrations && !this.option("skip-generate")) runPrismaCommand(["generate"], process.cwd());
|
|
2968
3308
|
if (!useDatabaseMigrations && !this.option("skip-migrate")) if (this.option("deploy")) runPrismaCommand(["migrate", "deploy"], process.cwd());
|
|
2969
3309
|
else runPrismaCommand([
|
|
@@ -3014,6 +3354,7 @@ var MigrationHistoryCommand = class extends Command {
|
|
|
3014
3354
|
if (this.option("delete")) {
|
|
3015
3355
|
if (usesDatabaseState) {
|
|
3016
3356
|
await adapter.writeAppliedMigrationsState(createEmptyAppliedMigrationsState());
|
|
3357
|
+
deletePersistedColumnMappingsState(resolveColumnMappingsFilePath(process.cwd()));
|
|
3017
3358
|
this.success("Deleted tracked migration state from database.");
|
|
3018
3359
|
return;
|
|
3019
3360
|
}
|
|
@@ -3022,11 +3363,13 @@ var MigrationHistoryCommand = class extends Command {
|
|
|
3022
3363
|
return;
|
|
3023
3364
|
}
|
|
3024
3365
|
rmSync(stateFilePath);
|
|
3366
|
+
deletePersistedColumnMappingsState(resolveColumnMappingsFilePath(process.cwd()));
|
|
3025
3367
|
this.success(`Deleted migration state file: ${this.app.formatPathForLog(stateFilePath)}`);
|
|
3026
3368
|
return;
|
|
3027
3369
|
}
|
|
3028
3370
|
if (this.option("reset")) {
|
|
3029
3371
|
await writeAppliedMigrationsStateToStore(adapter, stateFilePath, createEmptyAppliedMigrationsState());
|
|
3372
|
+
deletePersistedColumnMappingsState(resolveColumnMappingsFilePath(process.cwd()));
|
|
3030
3373
|
this.success(usesDatabaseState ? "Reset migration state in database." : `Reset migration state: ${this.app.formatPathForLog(stateFilePath)}`);
|
|
3031
3374
|
return;
|
|
3032
3375
|
}
|
|
@@ -3060,10 +3403,16 @@ var ModelsSyncCommand = class extends Command {
|
|
|
3060
3403
|
description = "Sync model declare attributes from the active adapter when supported, otherwise fall back to the Prisma schema";
|
|
3061
3404
|
async handle() {
|
|
3062
3405
|
this.app.command = this;
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
|
|
3406
|
+
let result;
|
|
3407
|
+
try {
|
|
3408
|
+
result = await this.app.syncModels({
|
|
3409
|
+
schemaPath: this.option("schema") ? resolve(String(this.option("schema"))) : void 0,
|
|
3410
|
+
modelsDir: this.option("models") ? resolve(String(this.option("models"))) : void 0
|
|
3411
|
+
});
|
|
3412
|
+
} catch (error) {
|
|
3413
|
+
this.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
3414
|
+
return;
|
|
3415
|
+
}
|
|
3067
3416
|
const updatedLines = result.updated.length === 0 ? [this.app.splitLogger("Updated", "none")] : result.updated.map((path) => this.app.splitLogger("Updated", path));
|
|
3068
3417
|
this.success("SUCCESS: Model sync completed with the following results:");
|
|
3069
3418
|
[
|