arkormx 2.0.0-next.3 → 2.0.0-next.4
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 +471 -128
- package/dist/index.cjs +2507 -2124
- package/dist/index.d.cts +63 -2
- package/dist/index.d.mts +63 -2
- package/dist/index.mjs +2538 -2170
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -3,6 +3,7 @@ import { existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync
|
|
|
3
3
|
import { dirname, extname, join, resolve } from "node:path";
|
|
4
4
|
import { spawnSync } from "node:child_process";
|
|
5
5
|
import { str } from "@h3ravel/support";
|
|
6
|
+
import { createHash } from "node:crypto";
|
|
6
7
|
import path, { dirname as dirname$1, extname as extname$1, join as join$1, relative } from "path";
|
|
7
8
|
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
9
|
import { AsyncLocalStorage } from "async_hooks";
|
|
@@ -12,7 +13,6 @@ 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,377 @@ 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 getPersistedEnumMap = (table, options = {}) => {
|
|
1690
|
+
return getPersistedTableMetadata(table, options).enums;
|
|
1691
|
+
};
|
|
1692
|
+
const applyMappedColumn = (tableColumns, column, features, table) => {
|
|
1693
|
+
if (typeof column.map === "string" && column.map.trim().length > 0 && column.map !== column.name) {
|
|
1694
|
+
if (!features.persistedColumnMappings) throw buildPersistedFeatureDisabledError("persistedColumnMappings", table);
|
|
1695
|
+
tableColumns[column.name] = column.map;
|
|
1696
|
+
return;
|
|
1697
|
+
}
|
|
1698
|
+
delete tableColumns[column.name];
|
|
1699
|
+
};
|
|
1700
|
+
const applyEnumColumn = (tableEnums, column, features, table) => {
|
|
1701
|
+
const values = column.enumValues ?? [];
|
|
1702
|
+
if (column.type === "enum" && values.length > 0) {
|
|
1703
|
+
if (!features.persistedEnums) throw buildPersistedFeatureDisabledError("persistedEnums", table);
|
|
1704
|
+
tableEnums[column.name] = [...values];
|
|
1705
|
+
return;
|
|
1706
|
+
}
|
|
1707
|
+
delete tableEnums[column.name];
|
|
1708
|
+
};
|
|
1709
|
+
const removePersistedColumnMetadata = (tableMetadata, columnName) => {
|
|
1710
|
+
delete tableMetadata.columns[columnName];
|
|
1711
|
+
delete tableMetadata.enums[columnName];
|
|
1712
|
+
Object.entries(tableMetadata.columns).forEach(([attribute, mappedColumn]) => {
|
|
1713
|
+
if (mappedColumn === columnName) delete tableMetadata.columns[attribute];
|
|
1714
|
+
});
|
|
1715
|
+
};
|
|
1716
|
+
const applyOperationsToPersistedColumnMappingsState = (state, operations, features = resolvePersistedMetadataFeatures()) => {
|
|
1717
|
+
const nextTables = Object.entries(state.tables).reduce((all, [table, metadata]) => {
|
|
1718
|
+
all[table] = {
|
|
1719
|
+
columns: { ...metadata.columns },
|
|
1720
|
+
enums: Object.entries(metadata.enums).reduce((nextEnums, [columnName, values]) => {
|
|
1721
|
+
nextEnums[columnName] = [...values];
|
|
1722
|
+
return nextEnums;
|
|
1723
|
+
}, {})
|
|
1724
|
+
};
|
|
1725
|
+
return all;
|
|
1726
|
+
}, {});
|
|
1727
|
+
operations.forEach((operation) => {
|
|
1728
|
+
if (operation.type === "createTable") {
|
|
1729
|
+
const tableMetadata = nextTables[operation.table] ?? {
|
|
1730
|
+
columns: {},
|
|
1731
|
+
enums: {}
|
|
1732
|
+
};
|
|
1733
|
+
operation.columns.forEach((column) => {
|
|
1734
|
+
applyMappedColumn(tableMetadata.columns, column, features, operation.table);
|
|
1735
|
+
applyEnumColumn(tableMetadata.enums, column, features, operation.table);
|
|
1736
|
+
});
|
|
1737
|
+
if (Object.keys(tableMetadata.columns).length > 0 || Object.keys(tableMetadata.enums).length > 0) nextTables[operation.table] = tableMetadata;
|
|
1738
|
+
else delete nextTables[operation.table];
|
|
1739
|
+
return;
|
|
1740
|
+
}
|
|
1741
|
+
if (operation.type === "alterTable") {
|
|
1742
|
+
const tableMetadata = nextTables[operation.table] ?? {
|
|
1743
|
+
columns: {},
|
|
1744
|
+
enums: {}
|
|
1745
|
+
};
|
|
1746
|
+
operation.addColumns.forEach((column) => {
|
|
1747
|
+
applyMappedColumn(tableMetadata.columns, column, features, operation.table);
|
|
1748
|
+
applyEnumColumn(tableMetadata.enums, column, features, operation.table);
|
|
1749
|
+
});
|
|
1750
|
+
operation.dropColumns.forEach((columnName) => {
|
|
1751
|
+
removePersistedColumnMetadata(tableMetadata, columnName);
|
|
1752
|
+
});
|
|
1753
|
+
if (Object.keys(tableMetadata.columns).length > 0 || Object.keys(tableMetadata.enums).length > 0) nextTables[operation.table] = tableMetadata;
|
|
1754
|
+
else delete nextTables[operation.table];
|
|
1755
|
+
return;
|
|
1756
|
+
}
|
|
1757
|
+
delete nextTables[operation.table];
|
|
1758
|
+
});
|
|
1759
|
+
return {
|
|
1760
|
+
version: 1,
|
|
1761
|
+
tables: nextTables
|
|
1762
|
+
};
|
|
1763
|
+
};
|
|
1764
|
+
const rebuildPersistedColumnMappingsState = async (state, availableMigrations, features = resolvePersistedMetadataFeatures()) => {
|
|
1765
|
+
const availableByIdentity = new Map(availableMigrations.map(([migrationClass, file]) => [buildMigrationIdentity(file, migrationClass.name), migrationClass]));
|
|
1766
|
+
let nextState = createEmptyPersistedColumnMappingsState();
|
|
1767
|
+
const orderedMigrations = state.migrations.map((migration, index) => ({
|
|
1768
|
+
migration,
|
|
1769
|
+
index
|
|
1770
|
+
})).sort((left, right) => {
|
|
1771
|
+
const appliedAtOrder = left.migration.appliedAt.localeCompare(right.migration.appliedAt);
|
|
1772
|
+
if (appliedAtOrder !== 0) return appliedAtOrder;
|
|
1773
|
+
return left.index - right.index;
|
|
1774
|
+
});
|
|
1775
|
+
for (const { migration } of orderedMigrations) {
|
|
1776
|
+
const migrationClass = availableByIdentity.get(migration.id);
|
|
1777
|
+
if (!migrationClass) throw new ArkormException(`Unable to rebuild persisted column mappings because migration [${migration.id}] could not be resolved from the current migration files.`, {
|
|
1778
|
+
operation: "migration.columnMappings",
|
|
1779
|
+
meta: {
|
|
1780
|
+
migrationId: migration.id,
|
|
1781
|
+
file: migration.file,
|
|
1782
|
+
className: migration.className
|
|
1783
|
+
}
|
|
1784
|
+
});
|
|
1785
|
+
const operations = await getMigrationPlan(migrationClass, "up");
|
|
1786
|
+
nextState = applyOperationsToPersistedColumnMappingsState(nextState, operations, features);
|
|
1787
|
+
}
|
|
1788
|
+
return nextState;
|
|
1789
|
+
};
|
|
1790
|
+
const syncPersistedColumnMappingsFromState = async (cwd, state, availableMigrations, features = resolvePersistedMetadataFeatures()) => {
|
|
1791
|
+
const filePath = resolveColumnMappingsFilePath(cwd);
|
|
1792
|
+
const nextState = await rebuildPersistedColumnMappingsState(state, availableMigrations, features);
|
|
1793
|
+
if (Object.keys(nextState.tables).length === 0) {
|
|
1794
|
+
deletePersistedColumnMappingsState(filePath);
|
|
1795
|
+
return;
|
|
1796
|
+
}
|
|
1797
|
+
writePersistedColumnMappingsState(filePath, nextState);
|
|
1798
|
+
};
|
|
1799
|
+
const validatePersistedMetadataFeaturesForMigrations = async (migrations, features = resolvePersistedMetadataFeatures()) => {
|
|
1800
|
+
let nextState = createEmptyPersistedColumnMappingsState();
|
|
1801
|
+
for (const [migrationClass] of migrations) {
|
|
1802
|
+
const operations = await getMigrationPlan(migrationClass, "up");
|
|
1803
|
+
nextState = applyOperationsToPersistedColumnMappingsState(nextState, operations, features);
|
|
1804
|
+
}
|
|
1805
|
+
};
|
|
1806
|
+
const getPersistedEnumTsType = (values) => {
|
|
1807
|
+
return buildEnumUnionType(values);
|
|
1808
|
+
};
|
|
1809
|
+
|
|
1439
1810
|
//#endregion
|
|
1440
1811
|
//#region src/helpers/runtime-module-loader.ts
|
|
1441
1812
|
var RuntimeModuleLoader = class {
|
|
@@ -1463,6 +1834,10 @@ const resolveDefaultStubsPath = () => {
|
|
|
1463
1834
|
return path.join(process.cwd(), "stubs");
|
|
1464
1835
|
};
|
|
1465
1836
|
const baseConfig = {
|
|
1837
|
+
features: {
|
|
1838
|
+
persistedColumnMappings: true,
|
|
1839
|
+
persistedEnums: true
|
|
1840
|
+
},
|
|
1466
1841
|
paths: {
|
|
1467
1842
|
stubs: resolveDefaultStubsPath(),
|
|
1468
1843
|
seeders: path.join(process.cwd(), "database", "seeders"),
|
|
@@ -1475,6 +1850,7 @@ const baseConfig = {
|
|
|
1475
1850
|
};
|
|
1476
1851
|
const userConfig = {
|
|
1477
1852
|
...baseConfig,
|
|
1853
|
+
features: { ...baseConfig.features ?? {} },
|
|
1478
1854
|
paths: { ...baseConfig.paths ?? {} }
|
|
1479
1855
|
};
|
|
1480
1856
|
let runtimeConfigLoaded = false;
|
|
@@ -1497,6 +1873,15 @@ const mergePathConfig = (paths) => {
|
|
|
1497
1873
|
...incoming
|
|
1498
1874
|
};
|
|
1499
1875
|
};
|
|
1876
|
+
const mergeFeatureConfig = (features) => {
|
|
1877
|
+
const defaults = baseConfig.features ?? {};
|
|
1878
|
+
const current = userConfig.features ?? {};
|
|
1879
|
+
return {
|
|
1880
|
+
...defaults,
|
|
1881
|
+
...current,
|
|
1882
|
+
...features ?? {}
|
|
1883
|
+
};
|
|
1884
|
+
};
|
|
1500
1885
|
const bindAdapterToModels = (adapter, models) => {
|
|
1501
1886
|
models.forEach((model) => {
|
|
1502
1887
|
model.setAdapter(adapter);
|
|
@@ -1522,6 +1907,7 @@ const getUserConfig = (key) => {
|
|
|
1522
1907
|
const configureArkormRuntime = (prisma, options = {}) => {
|
|
1523
1908
|
const nextConfig = {
|
|
1524
1909
|
...userConfig,
|
|
1910
|
+
features: mergeFeatureConfig(options.features),
|
|
1525
1911
|
paths: mergePathConfig(options.paths)
|
|
1526
1912
|
};
|
|
1527
1913
|
nextConfig.prisma = prisma;
|
|
@@ -1566,6 +1952,7 @@ const resolveAndApplyConfig = (imported) => {
|
|
|
1566
1952
|
configureArkormRuntime(config.prisma, {
|
|
1567
1953
|
adapter: config.adapter,
|
|
1568
1954
|
boot: config.boot,
|
|
1955
|
+
features: config.features,
|
|
1569
1956
|
pagination: config.pagination,
|
|
1570
1957
|
paths: config.paths,
|
|
1571
1958
|
outputExt: config.outputExt
|
|
@@ -2157,6 +2544,26 @@ var CliApp = class {
|
|
|
2157
2544
|
skipped
|
|
2158
2545
|
};
|
|
2159
2546
|
}
|
|
2547
|
+
applyPersistedEnumMetadata(structure) {
|
|
2548
|
+
const persistedEnums = getPersistedEnumMap(structure.table, {
|
|
2549
|
+
features: resolvePersistedMetadataFeatures(this.getConfig("features")),
|
|
2550
|
+
strict: true
|
|
2551
|
+
});
|
|
2552
|
+
if (Object.keys(persistedEnums).length === 0) return structure;
|
|
2553
|
+
return {
|
|
2554
|
+
...structure,
|
|
2555
|
+
fields: structure.fields.map((field) => {
|
|
2556
|
+
const enumValues = persistedEnums[field.name];
|
|
2557
|
+
if (!enumValues || enumValues.length === 0) return field;
|
|
2558
|
+
const enumType = getPersistedEnumTsType(enumValues);
|
|
2559
|
+
const isArray = /^Array<.+>$/.test(field.type);
|
|
2560
|
+
return {
|
|
2561
|
+
...field,
|
|
2562
|
+
type: isArray ? `Array<${enumType}>` : enumType
|
|
2563
|
+
};
|
|
2564
|
+
})
|
|
2565
|
+
};
|
|
2566
|
+
}
|
|
2160
2567
|
/**
|
|
2161
2568
|
* Parse Prisma enum definitions from a schema and return their member names.
|
|
2162
2569
|
*
|
|
@@ -2315,7 +2722,10 @@ var CliApp = class {
|
|
|
2315
2722
|
return all;
|
|
2316
2723
|
}, /* @__PURE__ */ new Map());
|
|
2317
2724
|
const discovered = await adapter.introspectModels({ tables: [...new Set([...sources.values()].map((source) => source.table))] });
|
|
2318
|
-
const structuresByTable = new Map(discovered.map((model) =>
|
|
2725
|
+
const structuresByTable = new Map(discovered.map((model) => {
|
|
2726
|
+
const enriched = this.applyPersistedEnumMetadata(model);
|
|
2727
|
+
return [enriched.table, enriched];
|
|
2728
|
+
}));
|
|
2319
2729
|
const result = this.syncModelFiles(modelFiles, (filePath) => {
|
|
2320
2730
|
const parsed = sources.get(filePath);
|
|
2321
2731
|
return parsed ? structuresByTable.get(parsed.table) : void 0;
|
|
@@ -2529,126 +2939,6 @@ var MakeSeederCommand = class extends Command {
|
|
|
2529
2939
|
}
|
|
2530
2940
|
};
|
|
2531
2941
|
|
|
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
2942
|
//#endregion
|
|
2653
2943
|
//#region src/database/Migration.ts
|
|
2654
2944
|
const MIGRATION_BRAND = Symbol.for("arkormx.migration");
|
|
@@ -2706,6 +2996,7 @@ var MigrateCommand = class extends Command {
|
|
|
2706
2996
|
let appliedState = await readAppliedMigrationsStateFromStore(this.app.getConfig("adapter"), stateFilePath);
|
|
2707
2997
|
const adapter = this.app.getConfig("adapter");
|
|
2708
2998
|
const useDatabaseMigrations = supportsDatabaseMigrationExecution(adapter);
|
|
2999
|
+
const persistedFeatures = resolvePersistedMetadataFeatures(this.app.getConfig("features"));
|
|
2709
3000
|
const skipped = [];
|
|
2710
3001
|
const changed = [];
|
|
2711
3002
|
const pending = classes.filter(([migrationClass, file]) => {
|
|
@@ -2724,9 +3015,21 @@ var MigrateCommand = class extends Command {
|
|
|
2724
3015
|
this.success(this.app.splitLogger("Changed", `${file} (${migrationClass.name})`));
|
|
2725
3016
|
});
|
|
2726
3017
|
if (pending.length === 0) {
|
|
3018
|
+
if (appliedState) try {
|
|
3019
|
+
await syncPersistedColumnMappingsFromState(process.cwd(), appliedState, await this.loadAllMigrations(migrationsDir), persistedFeatures);
|
|
3020
|
+
} catch (error) {
|
|
3021
|
+
this.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
3022
|
+
return;
|
|
3023
|
+
}
|
|
2727
3024
|
this.success("No pending migration classes to apply.");
|
|
2728
3025
|
return;
|
|
2729
3026
|
}
|
|
3027
|
+
if (useDatabaseMigrations) try {
|
|
3028
|
+
await validatePersistedMetadataFeaturesForMigrations(pending, persistedFeatures);
|
|
3029
|
+
} catch (error) {
|
|
3030
|
+
this.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
3031
|
+
return;
|
|
3032
|
+
}
|
|
2730
3033
|
for (const [MigrationClassItem] of pending) {
|
|
2731
3034
|
if (useDatabaseMigrations) {
|
|
2732
3035
|
await applyMigrationToDatabase(adapter, MigrationClassItem);
|
|
@@ -2756,6 +3059,12 @@ var MigrateCommand = class extends Command {
|
|
|
2756
3059
|
migrationIds: runAppliedIds
|
|
2757
3060
|
});
|
|
2758
3061
|
await writeAppliedMigrationsStateToStore(adapter, stateFilePath, appliedState);
|
|
3062
|
+
try {
|
|
3063
|
+
await syncPersistedColumnMappingsFromState(process.cwd(), appliedState, await this.loadAllMigrations(migrationsDir), persistedFeatures);
|
|
3064
|
+
} catch (error) {
|
|
3065
|
+
this.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
3066
|
+
return;
|
|
3067
|
+
}
|
|
2759
3068
|
}
|
|
2760
3069
|
if (!useDatabaseMigrations && !this.option("skip-generate")) runPrismaCommand(["generate"], process.cwd());
|
|
2761
3070
|
if (!useDatabaseMigrations && !this.option("skip-migrate")) if (this.option("deploy")) runPrismaCommand(["migrate", "deploy"], process.cwd());
|
|
@@ -2835,12 +3144,24 @@ var MigrateFreshCommand = class extends Command {
|
|
|
2835
3144
|
if (!existsSync(migrationsDir)) return void this.error(`Error: Migrations directory not found: ${this.app.formatPathForLog(configuredMigrationsDir)}`);
|
|
2836
3145
|
const adapter = this.app.getConfig("adapter");
|
|
2837
3146
|
const useDatabaseMigrations = supportsDatabaseMigrationExecution(adapter);
|
|
3147
|
+
const persistedFeatures = resolvePersistedMetadataFeatures(this.app.getConfig("features"));
|
|
2838
3148
|
const schemaPath = this.option("schema") ? resolve(String(this.option("schema"))) : join(process.cwd(), "prisma", "schema.prisma");
|
|
2839
3149
|
const stateFilePath = resolveMigrationStateFilePath(process.cwd(), this.option("state-file") ? String(this.option("state-file")) : void 0);
|
|
2840
3150
|
const migrations = await this.loadAllMigrations(migrationsDir);
|
|
2841
3151
|
if (migrations.length === 0) return void this.error("Error: No migration classes found to run.");
|
|
2842
|
-
if (
|
|
2843
|
-
|
|
3152
|
+
if (useDatabaseMigrations) try {
|
|
3153
|
+
await validatePersistedMetadataFeaturesForMigrations(migrations, persistedFeatures);
|
|
3154
|
+
} catch (error) {
|
|
3155
|
+
this.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
3156
|
+
return;
|
|
3157
|
+
}
|
|
3158
|
+
if (useDatabaseMigrations) {
|
|
3159
|
+
if (!supportsDatabaseReset(adapter)) {
|
|
3160
|
+
this.error("Error: Your current database adapter does not support database reset.");
|
|
3161
|
+
return;
|
|
3162
|
+
}
|
|
3163
|
+
await adapter.resetDatabase();
|
|
3164
|
+
} else {
|
|
2844
3165
|
if (!existsSync(schemaPath)) return void this.error(`Error: Prisma schema file not found: ${this.app.formatPathForLog(schemaPath)}`);
|
|
2845
3166
|
writeFileSync(schemaPath, stripPrismaSchemaModelsAndEnums(readFileSync(schemaPath, "utf-8")));
|
|
2846
3167
|
}
|
|
@@ -2869,6 +3190,12 @@ var MigrateFreshCommand = class extends Command {
|
|
|
2869
3190
|
migrationIds: appliedState.migrations.map((migration) => migration.id)
|
|
2870
3191
|
});
|
|
2871
3192
|
await writeAppliedMigrationsStateToStore(adapter, stateFilePath, appliedState);
|
|
3193
|
+
try {
|
|
3194
|
+
await syncPersistedColumnMappingsFromState(process.cwd(), appliedState, migrations, persistedFeatures);
|
|
3195
|
+
} catch (error) {
|
|
3196
|
+
this.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
3197
|
+
return;
|
|
3198
|
+
}
|
|
2872
3199
|
if (!useDatabaseMigrations) {
|
|
2873
3200
|
const schemaArgs = this.option("schema") ? ["--schema", schemaPath] : [];
|
|
2874
3201
|
if (!this.option("skip-generate")) runPrismaCommand(["generate", ...schemaArgs], process.cwd());
|
|
@@ -2927,6 +3254,7 @@ var MigrateRollbackCommand = class extends Command {
|
|
|
2927
3254
|
const stateFilePath = resolveMigrationStateFilePath(process.cwd(), this.option("state-file") ? String(this.option("state-file")) : void 0);
|
|
2928
3255
|
const adapter = this.app.getConfig("adapter");
|
|
2929
3256
|
const useDatabaseMigrations = supportsDatabaseMigrationExecution(adapter);
|
|
3257
|
+
const persistedFeatures = resolvePersistedMetadataFeatures(this.app.getConfig("features"));
|
|
2930
3258
|
let appliedState = await readAppliedMigrationsStateFromStore(adapter, stateFilePath);
|
|
2931
3259
|
const stepOption = this.option("step");
|
|
2932
3260
|
const stepCount = stepOption == null ? void 0 : Number(stepOption);
|
|
@@ -2964,6 +3292,12 @@ var MigrateRollbackCommand = class extends Command {
|
|
|
2964
3292
|
appliedState = removeAppliedMigration(appliedState, identity);
|
|
2965
3293
|
}
|
|
2966
3294
|
await writeAppliedMigrationsStateToStore(adapter, stateFilePath, appliedState);
|
|
3295
|
+
try {
|
|
3296
|
+
await syncPersistedColumnMappingsFromState(process.cwd(), appliedState, available, persistedFeatures);
|
|
3297
|
+
} catch (error) {
|
|
3298
|
+
this.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
3299
|
+
return;
|
|
3300
|
+
}
|
|
2967
3301
|
if (!useDatabaseMigrations && !this.option("skip-generate")) runPrismaCommand(["generate"], process.cwd());
|
|
2968
3302
|
if (!useDatabaseMigrations && !this.option("skip-migrate")) if (this.option("deploy")) runPrismaCommand(["migrate", "deploy"], process.cwd());
|
|
2969
3303
|
else runPrismaCommand([
|
|
@@ -3014,6 +3348,7 @@ var MigrationHistoryCommand = class extends Command {
|
|
|
3014
3348
|
if (this.option("delete")) {
|
|
3015
3349
|
if (usesDatabaseState) {
|
|
3016
3350
|
await adapter.writeAppliedMigrationsState(createEmptyAppliedMigrationsState());
|
|
3351
|
+
deletePersistedColumnMappingsState(resolveColumnMappingsFilePath(process.cwd()));
|
|
3017
3352
|
this.success("Deleted tracked migration state from database.");
|
|
3018
3353
|
return;
|
|
3019
3354
|
}
|
|
@@ -3022,11 +3357,13 @@ var MigrationHistoryCommand = class extends Command {
|
|
|
3022
3357
|
return;
|
|
3023
3358
|
}
|
|
3024
3359
|
rmSync(stateFilePath);
|
|
3360
|
+
deletePersistedColumnMappingsState(resolveColumnMappingsFilePath(process.cwd()));
|
|
3025
3361
|
this.success(`Deleted migration state file: ${this.app.formatPathForLog(stateFilePath)}`);
|
|
3026
3362
|
return;
|
|
3027
3363
|
}
|
|
3028
3364
|
if (this.option("reset")) {
|
|
3029
3365
|
await writeAppliedMigrationsStateToStore(adapter, stateFilePath, createEmptyAppliedMigrationsState());
|
|
3366
|
+
deletePersistedColumnMappingsState(resolveColumnMappingsFilePath(process.cwd()));
|
|
3030
3367
|
this.success(usesDatabaseState ? "Reset migration state in database." : `Reset migration state: ${this.app.formatPathForLog(stateFilePath)}`);
|
|
3031
3368
|
return;
|
|
3032
3369
|
}
|
|
@@ -3060,10 +3397,16 @@ var ModelsSyncCommand = class extends Command {
|
|
|
3060
3397
|
description = "Sync model declare attributes from the active adapter when supported, otherwise fall back to the Prisma schema";
|
|
3061
3398
|
async handle() {
|
|
3062
3399
|
this.app.command = this;
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
|
|
3400
|
+
let result;
|
|
3401
|
+
try {
|
|
3402
|
+
result = await this.app.syncModels({
|
|
3403
|
+
schemaPath: this.option("schema") ? resolve(String(this.option("schema"))) : void 0,
|
|
3404
|
+
modelsDir: this.option("models") ? resolve(String(this.option("models"))) : void 0
|
|
3405
|
+
});
|
|
3406
|
+
} catch (error) {
|
|
3407
|
+
this.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
3408
|
+
return;
|
|
3409
|
+
}
|
|
3067
3410
|
const updatedLines = result.updated.length === 0 ? [this.app.splitLogger("Updated", "none")] : result.updated.map((path) => this.app.splitLogger("Updated", path));
|
|
3068
3411
|
this.success("SUCCESS: Model sync completed with the following results:");
|
|
3069
3412
|
[
|