arkormx 0.2.5 → 0.2.7
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 +239 -90
- package/dist/index.cjs +169 -14
- package/dist/index.d.cts +40 -1
- package/dist/index.d.mts +40 -1
- package/dist/index.mjs +240 -92
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import { createRequire } from "module";
|
|
4
|
-
import { 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 "node:fs";
|
|
5
|
-
import { dirname as dirname$1, extname as extname$1, join as join$1, resolve } from "node:path";
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { dirname, extname, join, resolve } from "node:path";
|
|
6
3
|
import { spawnSync } from "node:child_process";
|
|
7
4
|
import { str } from "@h3ravel/support";
|
|
5
|
+
import path, { dirname as dirname$1, extname as extname$1, join as join$1, relative } from "path";
|
|
6
|
+
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
7
|
import { fileURLToPath, pathToFileURL } from "url";
|
|
8
|
+
import { createRequire } from "module";
|
|
9
9
|
import { Logger } from "@h3ravel/shared";
|
|
10
10
|
import { Command } from "@h3ravel/musket";
|
|
11
11
|
import { createHash } from "node:crypto";
|
|
@@ -1070,14 +1070,14 @@ const generateMigrationFile = (name, options = {}) => {
|
|
|
1070
1070
|
const fileSlug = toMigrationFileSlug(name);
|
|
1071
1071
|
const className = resolveMigrationClassName(name);
|
|
1072
1072
|
const extension = options.extension ?? "ts";
|
|
1073
|
-
const directory = options.directory ?? join
|
|
1073
|
+
const directory = options.directory ?? join(process.cwd(), "database", "migrations");
|
|
1074
1074
|
const fileName = `${timestamp}_${fileSlug}.${extension}`;
|
|
1075
|
-
const filePath = join
|
|
1075
|
+
const filePath = join(directory, fileName);
|
|
1076
1076
|
const content = buildMigrationSource(className, extension);
|
|
1077
1077
|
if (options.write ?? true) {
|
|
1078
|
-
if (!existsSync
|
|
1079
|
-
if (existsSync
|
|
1080
|
-
writeFileSync
|
|
1078
|
+
if (!existsSync(directory)) mkdirSync(directory, { recursive: true });
|
|
1079
|
+
if (existsSync(filePath)) throw new ArkormException(`Migration file already exists: ${filePath}`);
|
|
1080
|
+
writeFileSync(filePath, content);
|
|
1081
1081
|
}
|
|
1082
1082
|
return {
|
|
1083
1083
|
fileName,
|
|
@@ -1110,12 +1110,32 @@ const getMigrationPlan = async (migration, direction = "up") => {
|
|
|
1110
1110
|
* @returns A promise that resolves to an object containing the updated schema, schema path, and list of operations applied.
|
|
1111
1111
|
*/
|
|
1112
1112
|
const applyMigrationToPrismaSchema = async (migration, options = {}) => {
|
|
1113
|
-
const schemaPath = options.schemaPath ?? join
|
|
1114
|
-
if (!existsSync
|
|
1115
|
-
const source = readFileSync
|
|
1113
|
+
const schemaPath = options.schemaPath ?? join(process.cwd(), "prisma", "schema.prisma");
|
|
1114
|
+
if (!existsSync(schemaPath)) throw new ArkormException(`Prisma schema file not found: ${schemaPath}`);
|
|
1115
|
+
const source = readFileSync(schemaPath, "utf-8");
|
|
1116
1116
|
const operations = await getMigrationPlan(migration, "up");
|
|
1117
1117
|
const schema = applyOperationsToPrismaSchema(source, operations);
|
|
1118
|
-
if (options.write ?? true) writeFileSync
|
|
1118
|
+
if (options.write ?? true) writeFileSync(schemaPath, schema);
|
|
1119
|
+
return {
|
|
1120
|
+
schema,
|
|
1121
|
+
schemaPath,
|
|
1122
|
+
operations
|
|
1123
|
+
};
|
|
1124
|
+
};
|
|
1125
|
+
/**
|
|
1126
|
+
* Apply the rollback (down) operations defined in a migration to a Prisma schema file.
|
|
1127
|
+
*
|
|
1128
|
+
* @param migration The migration class or instance to rollback.
|
|
1129
|
+
* @param options Options for applying the rollback, including schema path and write flag.
|
|
1130
|
+
* @returns A promise that resolves to an object containing the updated schema, schema path, and rollback operations applied.
|
|
1131
|
+
*/
|
|
1132
|
+
const applyMigrationRollbackToPrismaSchema = async (migration, options = {}) => {
|
|
1133
|
+
const schemaPath = options.schemaPath ?? join(process.cwd(), "prisma", "schema.prisma");
|
|
1134
|
+
if (!existsSync(schemaPath)) throw new ArkormException(`Prisma schema file not found: ${schemaPath}`);
|
|
1135
|
+
const source = readFileSync(schemaPath, "utf-8");
|
|
1136
|
+
const operations = await getMigrationPlan(migration, "down");
|
|
1137
|
+
const schema = applyOperationsToPrismaSchema(source, operations);
|
|
1138
|
+
if (options.write ?? true) writeFileSync(schemaPath, schema);
|
|
1119
1139
|
return {
|
|
1120
1140
|
schema,
|
|
1121
1141
|
schemaPath,
|
|
@@ -1134,7 +1154,7 @@ const applyMigrationToPrismaSchema = async (migration, options = {}) => {
|
|
|
1134
1154
|
const runMigrationWithPrisma = async (migration, options = {}) => {
|
|
1135
1155
|
const cwd = options.cwd ?? process.cwd();
|
|
1136
1156
|
const applied = await applyMigrationToPrismaSchema(migration, {
|
|
1137
|
-
schemaPath: options.schemaPath ?? join
|
|
1157
|
+
schemaPath: options.schemaPath ?? join(cwd, "prisma", "schema.prisma"),
|
|
1138
1158
|
write: options.write
|
|
1139
1159
|
});
|
|
1140
1160
|
const shouldGenerate = options.runGenerate ?? true;
|
|
@@ -1161,7 +1181,7 @@ const resolveDefaultStubsPath = () => {
|
|
|
1161
1181
|
while (true) {
|
|
1162
1182
|
const packageJsonPath = path.join(current, "package.json");
|
|
1163
1183
|
const stubsPath = path.join(current, "stubs");
|
|
1164
|
-
if (existsSync(packageJsonPath) && existsSync(stubsPath)) return stubsPath;
|
|
1184
|
+
if (existsSync$1(packageJsonPath) && existsSync$1(stubsPath)) return stubsPath;
|
|
1165
1185
|
const parent = path.dirname(current);
|
|
1166
1186
|
if (parent === current) break;
|
|
1167
1187
|
current = parent;
|
|
@@ -1296,7 +1316,7 @@ const loadRuntimeConfigSync = () => {
|
|
|
1296
1316
|
const require = createRequire(import.meta.url);
|
|
1297
1317
|
const syncConfigPaths = [path.join(process.cwd(), "arkormx.config.cjs")];
|
|
1298
1318
|
for (const configPath of syncConfigPaths) {
|
|
1299
|
-
if (!existsSync(configPath)) continue;
|
|
1319
|
+
if (!existsSync$1(configPath)) continue;
|
|
1300
1320
|
try {
|
|
1301
1321
|
resolveAndApplyConfig(require(configPath));
|
|
1302
1322
|
return true;
|
|
@@ -1318,7 +1338,7 @@ const loadArkormConfig = async () => {
|
|
|
1318
1338
|
runtimeConfigLoadingPromise = (async () => {
|
|
1319
1339
|
const configPaths = [path.join(process.cwd(), "arkormx.config.js"), path.join(process.cwd(), "arkormx.config.ts")];
|
|
1320
1340
|
for (const configPath of configPaths) {
|
|
1321
|
-
if (!existsSync(configPath)) continue;
|
|
1341
|
+
if (!existsSync$1(configPath)) continue;
|
|
1322
1342
|
try {
|
|
1323
1343
|
resolveAndApplyConfig(await importConfigFile(configPath));
|
|
1324
1344
|
return;
|
|
@@ -1412,8 +1432,8 @@ var CliApp = class {
|
|
|
1412
1432
|
* @param filePath
|
|
1413
1433
|
*/
|
|
1414
1434
|
ensureDirectory(filePath) {
|
|
1415
|
-
const dir = dirname(filePath);
|
|
1416
|
-
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
1435
|
+
const dir = dirname$1(filePath);
|
|
1436
|
+
if (!existsSync$1(dir)) mkdirSync$1(dir, { recursive: true });
|
|
1417
1437
|
}
|
|
1418
1438
|
/**
|
|
1419
1439
|
* Convert absolute paths under current working directory into relative display paths.
|
|
@@ -1462,13 +1482,13 @@ var CliApp = class {
|
|
|
1462
1482
|
* @returns
|
|
1463
1483
|
*/
|
|
1464
1484
|
resolveRuntimeDirectoryPath(directoryPath) {
|
|
1465
|
-
if (existsSync(directoryPath)) return directoryPath;
|
|
1485
|
+
if (existsSync$1(directoryPath)) return directoryPath;
|
|
1466
1486
|
const { buildOutput } = this.getConfig("paths") || {};
|
|
1467
1487
|
if (typeof buildOutput !== "string" || buildOutput.trim().length === 0) return directoryPath;
|
|
1468
1488
|
const relativeSource = relative(process.cwd(), directoryPath);
|
|
1469
1489
|
if (!relativeSource || relativeSource.startsWith("..")) return directoryPath;
|
|
1470
|
-
const mappedDirectory = join(buildOutput, relativeSource);
|
|
1471
|
-
return existsSync(mappedDirectory) ? mappedDirectory : directoryPath;
|
|
1490
|
+
const mappedDirectory = join$1(buildOutput, relativeSource);
|
|
1491
|
+
return existsSync$1(mappedDirectory) ? mappedDirectory : directoryPath;
|
|
1472
1492
|
}
|
|
1473
1493
|
/**
|
|
1474
1494
|
* Resolve a script file path for runtime execution.
|
|
@@ -1479,7 +1499,7 @@ var CliApp = class {
|
|
|
1479
1499
|
* @returns
|
|
1480
1500
|
*/
|
|
1481
1501
|
resolveRuntimeScriptPath(filePath) {
|
|
1482
|
-
const extension = extname(filePath).toLowerCase();
|
|
1502
|
+
const extension = extname$1(filePath).toLowerCase();
|
|
1483
1503
|
const isTsFile = extension === ".ts" || extension === ".mts" || extension === ".cts";
|
|
1484
1504
|
const candidates = [];
|
|
1485
1505
|
if (isTsFile) {
|
|
@@ -1490,15 +1510,15 @@ var CliApp = class {
|
|
|
1490
1510
|
if (typeof buildOutput === "string" && buildOutput.trim().length > 0) {
|
|
1491
1511
|
const relativeSource = relative(process.cwd(), filePath);
|
|
1492
1512
|
if (relativeSource && !relativeSource.startsWith("..")) {
|
|
1493
|
-
const mappedFile = join(buildOutput, relativeSource);
|
|
1494
|
-
const mappedExtension = extname(mappedFile).toLowerCase();
|
|
1513
|
+
const mappedFile = join$1(buildOutput, relativeSource);
|
|
1514
|
+
const mappedExtension = extname$1(mappedFile).toLowerCase();
|
|
1495
1515
|
if (mappedExtension === ".ts" || mappedExtension === ".mts" || mappedExtension === ".cts") {
|
|
1496
1516
|
const mappedBase = mappedFile.slice(0, -mappedExtension.length);
|
|
1497
1517
|
candidates.push(`${mappedBase}.js`, `${mappedBase}.cjs`, `${mappedBase}.mjs`);
|
|
1498
1518
|
} else candidates.push(mappedFile);
|
|
1499
1519
|
}
|
|
1500
1520
|
}
|
|
1501
|
-
const runtimeMatch = candidates.find((path) => existsSync(path));
|
|
1521
|
+
const runtimeMatch = candidates.find((path) => existsSync$1(path));
|
|
1502
1522
|
if (runtimeMatch) return runtimeMatch;
|
|
1503
1523
|
return filePath;
|
|
1504
1524
|
}
|
|
@@ -1510,14 +1530,14 @@ var CliApp = class {
|
|
|
1510
1530
|
* @param replacements
|
|
1511
1531
|
*/
|
|
1512
1532
|
generateFile(stubPath, outputPath, replacements, options) {
|
|
1513
|
-
if (existsSync(outputPath) && !options?.force) {
|
|
1533
|
+
if (existsSync$1(outputPath) && !options?.force) {
|
|
1514
1534
|
this.command.error(`Error: ${this.formatPathForLog(outputPath)} already exists.`);
|
|
1515
1535
|
process.exit(1);
|
|
1516
|
-
} else if (existsSync(outputPath) && options?.force) rmSync(outputPath);
|
|
1517
|
-
let content = readFileSync(stubPath, "utf-8");
|
|
1536
|
+
} else if (existsSync$1(outputPath) && options?.force) rmSync$1(outputPath);
|
|
1537
|
+
let content = readFileSync$1(stubPath, "utf-8");
|
|
1518
1538
|
for (const [key, value] of Object.entries(replacements)) content = content.replace(new RegExp(`{{${key}}}`, "g"), value);
|
|
1519
1539
|
this.ensureDirectory(outputPath);
|
|
1520
|
-
writeFileSync(outputPath, content);
|
|
1540
|
+
writeFileSync$1(outputPath, content);
|
|
1521
1541
|
return outputPath;
|
|
1522
1542
|
}
|
|
1523
1543
|
/**
|
|
@@ -1539,7 +1559,7 @@ var CliApp = class {
|
|
|
1539
1559
|
* @returns
|
|
1540
1560
|
*/
|
|
1541
1561
|
resolveStubPath(stubName) {
|
|
1542
|
-
return join(this.resolveConfigPath("stubs", getDefaultStubsPath()), stubName);
|
|
1562
|
+
return join$1(this.resolveConfigPath("stubs", getDefaultStubsPath()), stubName);
|
|
1543
1563
|
}
|
|
1544
1564
|
/**
|
|
1545
1565
|
* Generate a factory file for a given model name.
|
|
@@ -1553,9 +1573,9 @@ var CliApp = class {
|
|
|
1553
1573
|
const factoryName = `${baseName}Factory`;
|
|
1554
1574
|
const modelName = options.modelName ? str(options.modelName).pascal() : baseName;
|
|
1555
1575
|
const outputExt = this.resolveOutputExt();
|
|
1556
|
-
const outputPath = join(this.resolveConfigPath("factories", join(process.cwd(), "database", "factories")), `${factoryName}.${outputExt}`);
|
|
1557
|
-
const modelPath = join(this.resolveConfigPath("models", join(process.cwd(), "src", "models")), `${modelName}.${outputExt}`);
|
|
1558
|
-
const relativeImport = options.modelImportPath ?? `./${this.stripKnownSourceExtension(relative(dirname(outputPath), modelPath).replace(/\\/g, "/"))}${outputExt === "js" ? ".js" : ""}`;
|
|
1576
|
+
const outputPath = join$1(this.resolveConfigPath("factories", join$1(process.cwd(), "database", "factories")), `${factoryName}.${outputExt}`);
|
|
1577
|
+
const modelPath = join$1(this.resolveConfigPath("models", join$1(process.cwd(), "src", "models")), `${modelName}.${outputExt}`);
|
|
1578
|
+
const relativeImport = options.modelImportPath ?? `./${this.stripKnownSourceExtension(relative(dirname$1(outputPath), modelPath).replace(/\\/g, "/"))}${outputExt === "js" ? ".js" : ""}`;
|
|
1559
1579
|
const stubPath = this.resolveStubPath(outputExt === "js" ? "factory.js.stub" : "factory.stub");
|
|
1560
1580
|
return {
|
|
1561
1581
|
name: factoryName,
|
|
@@ -1576,7 +1596,7 @@ var CliApp = class {
|
|
|
1576
1596
|
makeSeeder(name, options = {}) {
|
|
1577
1597
|
const seederName = `${str(name.replace(/Seeder$/, "")).pascal()}Seeder`;
|
|
1578
1598
|
const outputExt = this.resolveOutputExt();
|
|
1579
|
-
const outputPath = join(this.resolveConfigPath("seeders", join(process.cwd(), "database", "seeders")), `${seederName}.${outputExt}`);
|
|
1599
|
+
const outputPath = join$1(this.resolveConfigPath("seeders", join$1(process.cwd(), "database", "seeders")), `${seederName}.${outputExt}`);
|
|
1580
1600
|
const stubPath = this.resolveStubPath(outputExt === "js" ? "seeder.js.stub" : "seeder.stub");
|
|
1581
1601
|
return {
|
|
1582
1602
|
name: seederName,
|
|
@@ -1591,7 +1611,7 @@ var CliApp = class {
|
|
|
1591
1611
|
*/
|
|
1592
1612
|
makeMigration(name) {
|
|
1593
1613
|
const generated = generateMigrationFile(name, {
|
|
1594
|
-
directory: this.resolveConfigPath("migrations", join(process.cwd(), "database", "migrations")),
|
|
1614
|
+
directory: this.resolveConfigPath("migrations", join$1(process.cwd(), "database", "migrations")),
|
|
1595
1615
|
extension: this.resolveOutputExt()
|
|
1596
1616
|
});
|
|
1597
1617
|
return {
|
|
@@ -1611,13 +1631,13 @@ var CliApp = class {
|
|
|
1611
1631
|
const modelName = `${baseName}`;
|
|
1612
1632
|
const delegateName = str(baseName).camel().plural().toString();
|
|
1613
1633
|
const outputExt = this.resolveOutputExt();
|
|
1614
|
-
const outputPath = join(this.resolveConfigPath("models", join(process.cwd(), "src", "models")), `${modelName}.${outputExt}`);
|
|
1634
|
+
const outputPath = join$1(this.resolveConfigPath("models", join$1(process.cwd(), "src", "models")), `${modelName}.${outputExt}`);
|
|
1615
1635
|
const shouldBuildFactory = options.all || options.factory;
|
|
1616
1636
|
const shouldBuildSeeder = options.all || options.seeder;
|
|
1617
1637
|
const shouldBuildMigration = options.all || options.migration;
|
|
1618
1638
|
const factoryName = `${baseName}Factory`;
|
|
1619
|
-
const factoryPath = join(this.resolveConfigPath("factories", join(process.cwd(), "database", "factories")), `${factoryName}.${outputExt}`);
|
|
1620
|
-
const factoryImportPath = `./${relative(dirname(outputPath), factoryPath).replace(/\\/g, "/").replace(/\.(ts|tsx|mts|cts|js|mjs|cjs)$/i, "")}${outputExt === "js" ? ".js" : ""}`;
|
|
1639
|
+
const factoryPath = join$1(this.resolveConfigPath("factories", join$1(process.cwd(), "database", "factories")), `${factoryName}.${outputExt}`);
|
|
1640
|
+
const factoryImportPath = `./${relative(dirname$1(outputPath), factoryPath).replace(/\\/g, "/").replace(/\.(ts|tsx|mts|cts|js|mjs|cjs)$/i, "")}${outputExt === "js" ? ".js" : ""}`;
|
|
1621
1641
|
const stubPath = this.resolveStubPath(outputExt === "js" ? "model.js.stub" : "model.stub");
|
|
1622
1642
|
const modelPath = this.generateFile(stubPath, outputPath, {
|
|
1623
1643
|
ModelName: modelName,
|
|
@@ -1639,7 +1659,7 @@ var CliApp = class {
|
|
|
1639
1659
|
if (shouldBuildFactory) created.factory = this.makeFactory(baseName, {
|
|
1640
1660
|
force: options.force,
|
|
1641
1661
|
modelName,
|
|
1642
|
-
modelImportPath: `./${relative(dirname(factoryPath), outputPath).replace(/\\/g, "/").replace(/\.(ts|tsx|mts|cts|js|mjs|cjs)$/i, "")}${outputExt === "js" ? ".js" : ""}`
|
|
1662
|
+
modelImportPath: `./${relative(dirname$1(factoryPath), outputPath).replace(/\\/g, "/").replace(/\.(ts|tsx|mts|cts|js|mjs|cjs)$/i, "")}${outputExt === "js" ? ".js" : ""}`
|
|
1643
1663
|
});
|
|
1644
1664
|
if (shouldBuildSeeder) created.seeder = this.makeSeeder(baseName, { force: options.force });
|
|
1645
1665
|
if (shouldBuildMigration) created.migration = this.makeMigration(`create ${delegateName} table`);
|
|
@@ -1654,26 +1674,28 @@ var CliApp = class {
|
|
|
1654
1674
|
* @param delegateName The name of the delegate (table) to ensure in the Prisma schema.
|
|
1655
1675
|
*/
|
|
1656
1676
|
ensurePrismaModelEntry(modelName, delegateName) {
|
|
1657
|
-
const schemaPath = join(process.cwd(), "prisma", "schema.prisma");
|
|
1658
|
-
if (!existsSync(schemaPath)) return {
|
|
1677
|
+
const schemaPath = join$1(process.cwd(), "prisma", "schema.prisma");
|
|
1678
|
+
if (!existsSync$1(schemaPath)) return {
|
|
1659
1679
|
path: schemaPath,
|
|
1660
1680
|
updated: false
|
|
1661
1681
|
};
|
|
1662
|
-
const source = readFileSync(schemaPath, "utf-8");
|
|
1682
|
+
const source = readFileSync$1(schemaPath, "utf-8");
|
|
1663
1683
|
const existingByTable = findModelBlock(source, delegateName);
|
|
1664
1684
|
const existingByName = new RegExp(`model\\s+${modelName}\\s*\\{`, "m").test(source);
|
|
1665
1685
|
if (existingByTable || existingByName) return {
|
|
1666
1686
|
path: schemaPath,
|
|
1667
1687
|
updated: false
|
|
1668
1688
|
};
|
|
1669
|
-
writeFileSync(schemaPath, applyCreateTableOperation(source, {
|
|
1689
|
+
writeFileSync$1(schemaPath, applyCreateTableOperation(source, {
|
|
1670
1690
|
type: "createTable",
|
|
1671
1691
|
table: delegateName,
|
|
1672
1692
|
columns: [{
|
|
1673
1693
|
name: "id",
|
|
1674
1694
|
type: "id",
|
|
1675
1695
|
primary: true
|
|
1676
|
-
}]
|
|
1696
|
+
}],
|
|
1697
|
+
indexes: [],
|
|
1698
|
+
foreignKeys: []
|
|
1677
1699
|
}));
|
|
1678
1700
|
return {
|
|
1679
1701
|
path: schemaPath,
|
|
@@ -1725,14 +1747,14 @@ var CliApp = class {
|
|
|
1725
1747
|
body.split("\n").forEach((rawLine) => {
|
|
1726
1748
|
const line = rawLine.trim();
|
|
1727
1749
|
if (!line || line.startsWith("@@") || line.startsWith("//")) return;
|
|
1728
|
-
const fieldMatch = line.match(/^(\w+)\s+([A-Za-z]+)(\?)
|
|
1750
|
+
const fieldMatch = line.match(/^(\w+)\s+([A-Za-z]+)(\?)?(?:\s|$)/);
|
|
1729
1751
|
if (!fieldMatch) return;
|
|
1730
1752
|
const fieldType = fieldMatch[2];
|
|
1731
1753
|
if (!scalarTypes.has(fieldType)) return;
|
|
1732
1754
|
fields.push({
|
|
1733
1755
|
name: fieldMatch[1],
|
|
1734
1756
|
type: this.prismaTypeToTs(fieldType),
|
|
1735
|
-
|
|
1757
|
+
nullable: Boolean(fieldMatch[3])
|
|
1736
1758
|
});
|
|
1737
1759
|
});
|
|
1738
1760
|
models.push({
|
|
@@ -1799,18 +1821,18 @@ var CliApp = class {
|
|
|
1799
1821
|
* @returns An object with details about the synchronization process, including updated and skipped files.
|
|
1800
1822
|
*/
|
|
1801
1823
|
syncModelsFromPrisma(options = {}) {
|
|
1802
|
-
const schemaPath = options.schemaPath ?? join(process.cwd(), "prisma", "schema.prisma");
|
|
1803
|
-
const modelsDir = options.modelsDir ?? this.resolveConfigPath("models", join(process.cwd(), "src", "models"));
|
|
1804
|
-
if (!existsSync(schemaPath)) throw new Error(`Prisma schema file not found: ${schemaPath}`);
|
|
1805
|
-
if (!existsSync(modelsDir)) throw new Error(`Models directory not found: ${modelsDir}`);
|
|
1806
|
-
const schema = readFileSync(schemaPath, "utf-8");
|
|
1824
|
+
const schemaPath = options.schemaPath ?? join$1(process.cwd(), "prisma", "schema.prisma");
|
|
1825
|
+
const modelsDir = options.modelsDir ?? this.resolveConfigPath("models", join$1(process.cwd(), "src", "models"));
|
|
1826
|
+
if (!existsSync$1(schemaPath)) throw new Error(`Prisma schema file not found: ${schemaPath}`);
|
|
1827
|
+
if (!existsSync$1(modelsDir)) throw new Error(`Models directory not found: ${modelsDir}`);
|
|
1828
|
+
const schema = readFileSync$1(schemaPath, "utf-8");
|
|
1807
1829
|
const prismaModels = this.parsePrismaModels(schema);
|
|
1808
|
-
const modelFiles = readdirSync(modelsDir).filter((file) => file.endsWith(".ts"));
|
|
1830
|
+
const modelFiles = readdirSync$1(modelsDir).filter((file) => file.endsWith(".ts"));
|
|
1809
1831
|
const updated = [];
|
|
1810
1832
|
const skipped = [];
|
|
1811
1833
|
modelFiles.forEach((file) => {
|
|
1812
|
-
const filePath = join(modelsDir, file);
|
|
1813
|
-
const source = readFileSync(filePath, "utf-8");
|
|
1834
|
+
const filePath = join$1(modelsDir, file);
|
|
1835
|
+
const source = readFileSync$1(filePath, "utf-8");
|
|
1814
1836
|
const classMatch = source.match(/export\s+class\s+(\w+)\s+extends\s+Model<'([^']+)'>/);
|
|
1815
1837
|
if (!classMatch) {
|
|
1816
1838
|
skipped.push(filePath);
|
|
@@ -1823,13 +1845,13 @@ var CliApp = class {
|
|
|
1823
1845
|
skipped.push(filePath);
|
|
1824
1846
|
return;
|
|
1825
1847
|
}
|
|
1826
|
-
const declarations = prismaModel.fields.map((field) => `declare ${field.name}${field.
|
|
1848
|
+
const declarations = prismaModel.fields.map((field) => `declare ${field.name}: ${field.type}${field.nullable ? " | null" : ""}`);
|
|
1827
1849
|
const synced = this.syncModelDeclarations(source, declarations);
|
|
1828
1850
|
if (!synced.updated) {
|
|
1829
1851
|
skipped.push(filePath);
|
|
1830
1852
|
return;
|
|
1831
1853
|
}
|
|
1832
|
-
writeFileSync(filePath, synced.content);
|
|
1854
|
+
writeFileSync$1(filePath, synced.content);
|
|
1833
1855
|
updated.push(filePath);
|
|
1834
1856
|
});
|
|
1835
1857
|
return {
|
|
@@ -1861,23 +1883,23 @@ var InitCommand = class extends Command {
|
|
|
1861
1883
|
*/
|
|
1862
1884
|
async handle() {
|
|
1863
1885
|
this.app.command = this;
|
|
1864
|
-
const outputDir = join
|
|
1886
|
+
const outputDir = join(process.cwd(), "arkormx.config.js");
|
|
1865
1887
|
const { stubs } = getUserConfig("paths") ?? {};
|
|
1866
1888
|
const stubsDir = typeof stubs === "string" && stubs.trim().length > 0 ? stubs : getDefaultStubsPath();
|
|
1867
|
-
const preferredStubPath = join
|
|
1868
|
-
const legacyStubPath = join
|
|
1869
|
-
const stubPath = existsSync(preferredStubPath) ? preferredStubPath : legacyStubPath;
|
|
1870
|
-
if (existsSync(outputDir) && !this.option("force")) {
|
|
1889
|
+
const preferredStubPath = join(stubsDir, "arkormx.config.stub");
|
|
1890
|
+
const legacyStubPath = join(stubsDir, "arkorm.config.stub");
|
|
1891
|
+
const stubPath = existsSync$1(preferredStubPath) ? preferredStubPath : legacyStubPath;
|
|
1892
|
+
if (existsSync$1(outputDir) && !this.option("force")) {
|
|
1871
1893
|
this.error("Error: Arkormˣ has already been initialized. Use --force to reinitialize.");
|
|
1872
1894
|
process.exit(1);
|
|
1873
1895
|
}
|
|
1874
1896
|
this.app.ensureDirectory(outputDir);
|
|
1875
|
-
if (existsSync(outputDir) && this.option("force")) copyFileSync(outputDir, outputDir.replace(/\.js$/, `.backup.${Date.now()}.js`));
|
|
1876
|
-
if (!existsSync(stubPath)) {
|
|
1897
|
+
if (existsSync$1(outputDir) && this.option("force")) copyFileSync(outputDir, outputDir.replace(/\.js$/, `.backup.${Date.now()}.js`));
|
|
1898
|
+
if (!existsSync$1(stubPath)) {
|
|
1877
1899
|
this.error(`Error: Missing config stub at ${preferredStubPath} (or ${legacyStubPath})`);
|
|
1878
1900
|
process.exit(1);
|
|
1879
1901
|
}
|
|
1880
|
-
writeFileSync(outputDir, readFileSync(stubPath, "utf-8"));
|
|
1902
|
+
writeFileSync$1(outputDir, readFileSync$1(stubPath, "utf-8"));
|
|
1881
1903
|
this.success("Arkormˣ initialized successfully!");
|
|
1882
1904
|
}
|
|
1883
1905
|
};
|
|
@@ -2007,39 +2029,43 @@ var MakeSeederCommand = class extends Command {
|
|
|
2007
2029
|
//#region src/helpers/migration-history.ts
|
|
2008
2030
|
const DEFAULT_STATE = {
|
|
2009
2031
|
version: 1,
|
|
2010
|
-
migrations: []
|
|
2032
|
+
migrations: [],
|
|
2033
|
+
runs: []
|
|
2011
2034
|
};
|
|
2012
2035
|
const resolveMigrationStateFilePath = (cwd, configuredPath) => {
|
|
2013
2036
|
if (configuredPath && configuredPath.trim().length > 0) return resolve(configuredPath);
|
|
2014
|
-
return join
|
|
2037
|
+
return join(cwd, ".arkormx", "migrations.applied.json");
|
|
2015
2038
|
};
|
|
2016
2039
|
const buildMigrationIdentity = (filePath, className) => {
|
|
2017
2040
|
const fileName = filePath.split("/").pop()?.split("\\").pop() ?? filePath;
|
|
2018
|
-
return `${fileName.slice(0, fileName.length - extname
|
|
2041
|
+
return `${fileName.slice(0, fileName.length - extname(fileName).length)}:${className}`;
|
|
2019
2042
|
};
|
|
2020
2043
|
const computeMigrationChecksum = (filePath) => {
|
|
2021
|
-
const source = readFileSync
|
|
2044
|
+
const source = readFileSync(filePath, "utf-8");
|
|
2022
2045
|
return createHash("sha256").update(source).digest("hex");
|
|
2023
2046
|
};
|
|
2024
2047
|
const readAppliedMigrationsState = (stateFilePath) => {
|
|
2025
|
-
if (!existsSync
|
|
2048
|
+
if (!existsSync(stateFilePath)) return { ...DEFAULT_STATE };
|
|
2026
2049
|
try {
|
|
2027
|
-
const parsed = JSON.parse(readFileSync
|
|
2050
|
+
const parsed = JSON.parse(readFileSync(stateFilePath, "utf-8"));
|
|
2028
2051
|
if (!Array.isArray(parsed.migrations)) return { ...DEFAULT_STATE };
|
|
2029
2052
|
return {
|
|
2030
2053
|
version: 1,
|
|
2031
2054
|
migrations: parsed.migrations.filter((migration) => {
|
|
2032
2055
|
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");
|
|
2033
|
-
})
|
|
2056
|
+
}),
|
|
2057
|
+
runs: Array.isArray(parsed.runs) ? parsed.runs.filter((run) => {
|
|
2058
|
+
return typeof run?.id === "string" && typeof run?.appliedAt === "string" && Array.isArray(run?.migrationIds) && run.migrationIds.every((item) => typeof item === "string");
|
|
2059
|
+
}) : []
|
|
2034
2060
|
};
|
|
2035
2061
|
} catch {
|
|
2036
2062
|
return { ...DEFAULT_STATE };
|
|
2037
2063
|
}
|
|
2038
2064
|
};
|
|
2039
2065
|
const writeAppliedMigrationsState = (stateFilePath, state) => {
|
|
2040
|
-
const directory = dirname
|
|
2041
|
-
if (!existsSync
|
|
2042
|
-
writeFileSync
|
|
2066
|
+
const directory = dirname(stateFilePath);
|
|
2067
|
+
if (!existsSync(directory)) mkdirSync(directory, { recursive: true });
|
|
2068
|
+
writeFileSync(stateFilePath, JSON.stringify(state, null, 2));
|
|
2043
2069
|
};
|
|
2044
2070
|
const isMigrationApplied = (state, identity, checksum) => {
|
|
2045
2071
|
const matched = state.migrations.find((migration) => migration.id === identity);
|
|
@@ -2056,9 +2082,40 @@ const markMigrationApplied = (state, entry) => {
|
|
|
2056
2082
|
next.push(entry);
|
|
2057
2083
|
return {
|
|
2058
2084
|
version: 1,
|
|
2059
|
-
migrations: next
|
|
2085
|
+
migrations: next,
|
|
2086
|
+
runs: state.runs ?? []
|
|
2087
|
+
};
|
|
2088
|
+
};
|
|
2089
|
+
const removeAppliedMigration = (state, identity) => {
|
|
2090
|
+
return {
|
|
2091
|
+
version: 1,
|
|
2092
|
+
migrations: state.migrations.filter((migration) => migration.id !== identity),
|
|
2093
|
+
runs: (state.runs ?? []).map((run) => ({
|
|
2094
|
+
...run,
|
|
2095
|
+
migrationIds: run.migrationIds.filter((id) => id !== identity)
|
|
2096
|
+
})).filter((run) => run.migrationIds.length > 0)
|
|
2097
|
+
};
|
|
2098
|
+
};
|
|
2099
|
+
const buildMigrationRunId = () => {
|
|
2100
|
+
return `run_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`;
|
|
2101
|
+
};
|
|
2102
|
+
const markMigrationRun = (state, run) => {
|
|
2103
|
+
const nextRuns = (state.runs ?? []).filter((existing) => existing.id !== run.id);
|
|
2104
|
+
nextRuns.push(run);
|
|
2105
|
+
return {
|
|
2106
|
+
version: 1,
|
|
2107
|
+
migrations: state.migrations,
|
|
2108
|
+
runs: nextRuns
|
|
2060
2109
|
};
|
|
2061
2110
|
};
|
|
2111
|
+
const getLastMigrationRun = (state) => {
|
|
2112
|
+
const runs = state.runs ?? [];
|
|
2113
|
+
if (runs.length === 0) return void 0;
|
|
2114
|
+
return [...runs].sort((left, right) => right.appliedAt.localeCompare(left.appliedAt))[0];
|
|
2115
|
+
};
|
|
2116
|
+
const getLatestAppliedMigrations = (state, steps) => {
|
|
2117
|
+
return [...state.migrations].sort((left, right) => right.appliedAt.localeCompare(left.appliedAt)).slice(0, Math.max(0, steps));
|
|
2118
|
+
};
|
|
2062
2119
|
|
|
2063
2120
|
//#endregion
|
|
2064
2121
|
//#region src/database/Migration.ts
|
|
@@ -2107,15 +2164,14 @@ var MigrateCommand = class extends Command {
|
|
|
2107
2164
|
*/
|
|
2108
2165
|
async handle() {
|
|
2109
2166
|
this.app.command = this;
|
|
2110
|
-
const configuredMigrationsDir = this.app.getConfig("paths")?.migrations ?? join
|
|
2167
|
+
const configuredMigrationsDir = this.app.getConfig("paths")?.migrations ?? join(process.cwd(), "database", "migrations");
|
|
2111
2168
|
const migrationsDir = this.app.resolveRuntimeDirectoryPath(configuredMigrationsDir);
|
|
2112
|
-
if (!existsSync
|
|
2113
|
-
const schemaPath = this.option("schema") ? resolve(String(this.option("schema"))) : join
|
|
2169
|
+
if (!existsSync(migrationsDir)) return void this.error(`Error: Migrations directory not found: ${this.app.formatPathForLog(configuredMigrationsDir)}`);
|
|
2170
|
+
const schemaPath = this.option("schema") ? resolve(String(this.option("schema"))) : join(process.cwd(), "prisma", "schema.prisma");
|
|
2114
2171
|
const classes = this.option("all") || !this.argument("name") ? await this.loadAllMigrations(migrationsDir) : (await this.loadNamedMigration(migrationsDir, this.argument("name"))).filter(([cls]) => cls !== void 0);
|
|
2115
2172
|
if (classes.length === 0) return void this.error("Error: No migration classes found to run.");
|
|
2116
|
-
const shouldTrackApplied = Boolean(this.option("all") || !this.argument("name") || this.option("state-file"));
|
|
2117
2173
|
const stateFilePath = resolveMigrationStateFilePath(process.cwd(), this.option("state-file") ? String(this.option("state-file")) : void 0);
|
|
2118
|
-
let appliedState =
|
|
2174
|
+
let appliedState = readAppliedMigrationsState(stateFilePath);
|
|
2119
2175
|
const skipped = [];
|
|
2120
2176
|
const changed = [];
|
|
2121
2177
|
const pending = classes.filter(([migrationClass, file]) => {
|
|
@@ -2142,6 +2198,7 @@ var MigrateCommand = class extends Command {
|
|
|
2142
2198
|
write: true
|
|
2143
2199
|
});
|
|
2144
2200
|
if (appliedState) {
|
|
2201
|
+
const runAppliedIds = [];
|
|
2145
2202
|
for (const [migrationClass, file] of pending) {
|
|
2146
2203
|
const identity = buildMigrationIdentity(file, migrationClass.name);
|
|
2147
2204
|
appliedState = markMigrationApplied(appliedState, {
|
|
@@ -2151,7 +2208,13 @@ var MigrateCommand = class extends Command {
|
|
|
2151
2208
|
appliedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2152
2209
|
checksum: computeMigrationChecksum(file)
|
|
2153
2210
|
});
|
|
2211
|
+
runAppliedIds.push(identity);
|
|
2154
2212
|
}
|
|
2213
|
+
appliedState = markMigrationRun(appliedState, {
|
|
2214
|
+
id: buildMigrationRunId(),
|
|
2215
|
+
appliedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2216
|
+
migrationIds: runAppliedIds
|
|
2217
|
+
});
|
|
2155
2218
|
writeAppliedMigrationsState(stateFilePath, appliedState);
|
|
2156
2219
|
}
|
|
2157
2220
|
if (!this.option("skip-generate")) runPrismaCommand(["generate"], process.cwd());
|
|
@@ -2171,7 +2234,7 @@ var MigrateCommand = class extends Command {
|
|
|
2171
2234
|
* @param migrationsDir The directory to load migration classes from.
|
|
2172
2235
|
*/
|
|
2173
2236
|
async loadAllMigrations(migrationsDir) {
|
|
2174
|
-
const files = readdirSync
|
|
2237
|
+
const files = readdirSync(migrationsDir).filter((file) => /\.(ts|js|mjs|cjs)$/i.test(file)).sort((left, right) => left.localeCompare(right)).map((file) => this.app.resolveRuntimeScriptPath(join(migrationsDir, file)));
|
|
2175
2238
|
return (await Promise.all(files.map(async (file) => (await this.loadMigrationClassesFromFile(file)).map((cls) => [cls, file])))).flat();
|
|
2176
2239
|
}
|
|
2177
2240
|
/**
|
|
@@ -2193,7 +2256,7 @@ var MigrateCommand = class extends Command {
|
|
|
2193
2256
|
`${base}Migration.js`,
|
|
2194
2257
|
`${base}Migration.mjs`,
|
|
2195
2258
|
`${base}Migration.cjs`
|
|
2196
|
-
].map((file) => join
|
|
2259
|
+
].map((file) => join(migrationsDir, file)).find((file) => existsSync(file));
|
|
2197
2260
|
if (!target) return [[void 0, name]];
|
|
2198
2261
|
const runtimeTarget = this.app.resolveRuntimeScriptPath(target);
|
|
2199
2262
|
return (await this.loadMigrationClassesFromFile(runtimeTarget)).map((cls) => [cls, runtimeTarget]);
|
|
@@ -2215,6 +2278,91 @@ var MigrateCommand = class extends Command {
|
|
|
2215
2278
|
}
|
|
2216
2279
|
};
|
|
2217
2280
|
|
|
2281
|
+
//#endregion
|
|
2282
|
+
//#region src/cli/commands/MigrateRollbackCommand.ts
|
|
2283
|
+
/**
|
|
2284
|
+
* Rollback migration classes from the Prisma schema and run Prisma workflow.
|
|
2285
|
+
* By default, rolls back classes applied in the last migrate run.
|
|
2286
|
+
*
|
|
2287
|
+
* @author Legacy (3m1n3nc3)
|
|
2288
|
+
* @since 0.2.4
|
|
2289
|
+
*/
|
|
2290
|
+
var MigrateRollbackCommand = class extends Command {
|
|
2291
|
+
signature = `migrate:rollback
|
|
2292
|
+
{--step= : Number of latest applied migration classes to rollback}
|
|
2293
|
+
{--dry-run : Preview rollback targets without applying changes}
|
|
2294
|
+
{--deploy : Use prisma migrate deploy instead of migrate dev}
|
|
2295
|
+
{--skip-generate : Skip prisma generate}
|
|
2296
|
+
{--skip-migrate : Skip prisma migrate command}
|
|
2297
|
+
{--state-file= : Path to applied migration state file}
|
|
2298
|
+
{--schema= : Explicit prisma schema path}
|
|
2299
|
+
{--migration-name= : Name for prisma migrate dev}
|
|
2300
|
+
`;
|
|
2301
|
+
description = "Rollback migration classes from schema.prisma and run Prisma workflow";
|
|
2302
|
+
async handle() {
|
|
2303
|
+
this.app.command = this;
|
|
2304
|
+
const configuredMigrationsDir = this.app.getConfig("paths")?.migrations ?? join(process.cwd(), "database", "migrations");
|
|
2305
|
+
const migrationsDir = this.app.resolveRuntimeDirectoryPath(configuredMigrationsDir);
|
|
2306
|
+
if (!existsSync(migrationsDir)) return void this.error(`Error: Migrations directory not found: ${this.app.formatPathForLog(configuredMigrationsDir)}`);
|
|
2307
|
+
const schemaPath = this.option("schema") ? resolve(String(this.option("schema"))) : join(process.cwd(), "prisma", "schema.prisma");
|
|
2308
|
+
const stateFilePath = resolveMigrationStateFilePath(process.cwd(), this.option("state-file") ? String(this.option("state-file")) : void 0);
|
|
2309
|
+
let appliedState = readAppliedMigrationsState(stateFilePath);
|
|
2310
|
+
const stepOption = this.option("step");
|
|
2311
|
+
const stepCount = stepOption == null ? void 0 : Number(stepOption);
|
|
2312
|
+
if (stepCount != null && (!Number.isFinite(stepCount) || stepCount <= 0 || !Number.isInteger(stepCount))) return void this.error("Error: --step must be a positive integer.");
|
|
2313
|
+
const targets = stepCount ? getLatestAppliedMigrations(appliedState, stepCount) : (() => {
|
|
2314
|
+
const lastRun = getLastMigrationRun(appliedState);
|
|
2315
|
+
if (!lastRun) return [];
|
|
2316
|
+
return lastRun.migrationIds.map((id) => appliedState.migrations.find((migration) => migration.id === id)).filter((migration) => Boolean(migration));
|
|
2317
|
+
})();
|
|
2318
|
+
if (targets.length === 0) return void this.error("Error: No tracked migrations available to rollback.");
|
|
2319
|
+
const available = await this.loadAllMigrations(migrationsDir);
|
|
2320
|
+
const rollbackClasses = targets.map((target) => {
|
|
2321
|
+
return available.find(([migrationClass, file]) => {
|
|
2322
|
+
return buildMigrationIdentity(file, migrationClass.name) === target.id || migrationClass.name === target.className;
|
|
2323
|
+
});
|
|
2324
|
+
}).filter((entry) => Boolean(entry));
|
|
2325
|
+
if (rollbackClasses.length === 0) return void this.error("Error: Unable to resolve rollback migration classes from tracked history.");
|
|
2326
|
+
if (this.option("dry-run")) {
|
|
2327
|
+
this.success(`Dry run: ${rollbackClasses.length} migration(s) would be rolled back.`);
|
|
2328
|
+
rollbackClasses.forEach(([_, file]) => this.success(this.app.splitLogger("WouldRollback", file)));
|
|
2329
|
+
return;
|
|
2330
|
+
}
|
|
2331
|
+
for (const [MigrationClassItem] of rollbackClasses) await applyMigrationRollbackToPrismaSchema(MigrationClassItem, {
|
|
2332
|
+
schemaPath,
|
|
2333
|
+
write: true
|
|
2334
|
+
});
|
|
2335
|
+
for (const [migrationClass, file] of rollbackClasses) {
|
|
2336
|
+
const identity = buildMigrationIdentity(file, migrationClass.name);
|
|
2337
|
+
appliedState = removeAppliedMigration(appliedState, identity);
|
|
2338
|
+
}
|
|
2339
|
+
writeAppliedMigrationsState(stateFilePath, appliedState);
|
|
2340
|
+
if (!this.option("skip-generate")) runPrismaCommand(["generate"], process.cwd());
|
|
2341
|
+
if (!this.option("skip-migrate")) if (this.option("deploy")) runPrismaCommand(["migrate", "deploy"], process.cwd());
|
|
2342
|
+
else runPrismaCommand([
|
|
2343
|
+
"migrate",
|
|
2344
|
+
"dev",
|
|
2345
|
+
"--name",
|
|
2346
|
+
this.option("migration-name") ? String(this.option("migration-name")) : `arkorm_cli_rollback_${Date.now()}`
|
|
2347
|
+
], process.cwd());
|
|
2348
|
+
this.success(`Rolled back ${rollbackClasses.length} migration(s).`);
|
|
2349
|
+
rollbackClasses.forEach(([_, file]) => this.success(this.app.splitLogger("RolledBack", file)));
|
|
2350
|
+
}
|
|
2351
|
+
async loadAllMigrations(migrationsDir) {
|
|
2352
|
+
const files = readdirSync(migrationsDir).filter((file) => /\.(ts|js|mjs|cjs)$/i.test(file)).sort((left, right) => left.localeCompare(right)).map((file) => this.app.resolveRuntimeScriptPath(join(migrationsDir, file)));
|
|
2353
|
+
return (await Promise.all(files.map(async (file) => (await this.loadMigrationClassesFromFile(file)).map((cls) => [cls, file])))).flat();
|
|
2354
|
+
}
|
|
2355
|
+
async loadMigrationClassesFromFile(filePath) {
|
|
2356
|
+
const imported = await import(`${pathToFileURL$1(resolve(filePath)).href}?arkorm_rollback=${Date.now()}`);
|
|
2357
|
+
return Object.values(imported).filter((value) => {
|
|
2358
|
+
if (typeof value !== "function") return false;
|
|
2359
|
+
const candidate = value;
|
|
2360
|
+
const prototype = candidate.prototype;
|
|
2361
|
+
return candidate[MIGRATION_BRAND] === true || typeof prototype?.up === "function" && typeof prototype?.down === "function";
|
|
2362
|
+
});
|
|
2363
|
+
}
|
|
2364
|
+
};
|
|
2365
|
+
|
|
2218
2366
|
//#endregion
|
|
2219
2367
|
//#region src/cli/commands/MigrationHistoryCommand.ts
|
|
2220
2368
|
/**
|
|
@@ -2235,11 +2383,11 @@ var MigrationHistoryCommand = class extends Command {
|
|
|
2235
2383
|
this.app.command = this;
|
|
2236
2384
|
const stateFilePath = resolveMigrationStateFilePath(process.cwd(), this.option("state-file") ? String(this.option("state-file")) : void 0);
|
|
2237
2385
|
if (this.option("delete")) {
|
|
2238
|
-
if (!existsSync
|
|
2386
|
+
if (!existsSync(stateFilePath)) {
|
|
2239
2387
|
this.success(`No migration state file found at ${this.app.formatPathForLog(stateFilePath)}`);
|
|
2240
2388
|
return;
|
|
2241
2389
|
}
|
|
2242
|
-
rmSync
|
|
2390
|
+
rmSync(stateFilePath);
|
|
2243
2391
|
this.success(`Deleted migration state file: ${this.app.formatPathForLog(stateFilePath)}`);
|
|
2244
2392
|
return;
|
|
2245
2393
|
}
|
|
@@ -2266,7 +2414,7 @@ var MigrationHistoryCommand = class extends Command {
|
|
|
2266
2414
|
return;
|
|
2267
2415
|
}
|
|
2268
2416
|
state.migrations.sort((left, right) => left.appliedAt.localeCompare(right.appliedAt)).forEach((migration) => {
|
|
2269
|
-
this.success(this.app.splitLogger("Applied", `${migration.id} @ ${migration.appliedAt}`));
|
|
2417
|
+
this.success(this.app.splitLogger("Applied:", `${migration.id} @ ${migration.appliedAt}`));
|
|
2270
2418
|
});
|
|
2271
2419
|
}
|
|
2272
2420
|
};
|
|
@@ -2366,9 +2514,9 @@ var SeedCommand = class extends Command {
|
|
|
2366
2514
|
*/
|
|
2367
2515
|
async handle() {
|
|
2368
2516
|
this.app.command = this;
|
|
2369
|
-
const configuredSeedersDir = this.app.getConfig("paths")?.seeders ?? join
|
|
2517
|
+
const configuredSeedersDir = this.app.getConfig("paths")?.seeders ?? join(process.cwd(), "database", "seeders");
|
|
2370
2518
|
const seedersDir = this.app.resolveRuntimeDirectoryPath(configuredSeedersDir);
|
|
2371
|
-
if (!existsSync
|
|
2519
|
+
if (!existsSync(seedersDir)) return void this.error(`ERROR: Seeders directory not found: ${this.app.formatPathForLog(configuredSeedersDir)}`);
|
|
2372
2520
|
const classes = this.option("all") ? await this.loadAllSeeders(seedersDir) : await this.loadNamedSeeder(seedersDir, this.argument("name") ?? "DatabaseSeeder");
|
|
2373
2521
|
if (classes.length === 0) return void this.error("ERROR: No seeder classes found to run.");
|
|
2374
2522
|
for (const SeederClassItem of classes) await new SeederClassItem().run();
|
|
@@ -2382,7 +2530,7 @@ var SeedCommand = class extends Command {
|
|
|
2382
2530
|
* @returns
|
|
2383
2531
|
*/
|
|
2384
2532
|
async loadAllSeeders(seedersDir) {
|
|
2385
|
-
const files = readdirSync
|
|
2533
|
+
const files = readdirSync(seedersDir).filter((file) => /\.(ts|js|mjs|cjs)$/i.test(file)).map((file) => this.app.resolveRuntimeScriptPath(join(seedersDir, file)));
|
|
2386
2534
|
return (await Promise.all(files.map(async (file) => await this.loadSeederClassesFromFile(file)))).flat();
|
|
2387
2535
|
}
|
|
2388
2536
|
/**
|
|
@@ -2403,7 +2551,7 @@ var SeedCommand = class extends Command {
|
|
|
2403
2551
|
`${base}Seeder.js`,
|
|
2404
2552
|
`${base}Seeder.mjs`,
|
|
2405
2553
|
`${base}Seeder.cjs`
|
|
2406
|
-
].map((file) => join
|
|
2554
|
+
].map((file) => join(seedersDir, file)).find((file) => existsSync(file));
|
|
2407
2555
|
if (!target) return [];
|
|
2408
2556
|
const runtimeTarget = this.app.resolveRuntimeScriptPath(target);
|
|
2409
2557
|
return await this.loadSeederClassesFromFile(runtimeTarget);
|
|
@@ -5239,4 +5387,4 @@ var Model = class Model {
|
|
|
5239
5387
|
};
|
|
5240
5388
|
|
|
5241
5389
|
//#endregion
|
|
5242
|
-
export { ArkormCollection, ArkormException, CliApp, ForeignKeyBuilder, InitCommand, InlineFactory, LengthAwarePaginator, MIGRATION_BRAND, MakeFactoryCommand, MakeMigrationCommand, MakeModelCommand, MakeSeederCommand, MigrateCommand, Migration, MigrationHistoryCommand, Model, ModelFactory, ModelNotFoundException, ModelsSyncCommand, PRISMA_MODEL_REGEX, Paginator, QueryBuilder, SEEDER_BRAND, SchemaBuilder, SeedCommand, Seeder, TableBuilder, URLDriver, applyAlterTableOperation, applyCreateTableOperation, applyDropTableOperation, applyMigrationToPrismaSchema, applyOperationsToPrismaSchema, buildFieldLine, buildIndexLine, buildInverseRelationLine, buildMigrationIdentity, buildMigrationSource, buildModelBlock, buildRelationLine, computeMigrationChecksum, configureArkormRuntime, createMigrationTimestamp, createPrismaAdapter, createPrismaDelegateMap, defineConfig, defineFactory, deriveCollectionFieldName, deriveInverseRelationAlias, deriveRelationFieldName, ensureArkormConfigLoading, escapeRegex, findAppliedMigration, findModelBlock, formatDefaultValue, formatRelationAction, generateMigrationFile, getDefaultStubsPath, getMigrationPlan, getRuntimePaginationURLDriverFactory, getRuntimePrismaClient, getUserConfig, inferDelegateName, isDelegateLike, isMigrationApplied, loadArkormConfig, markMigrationApplied, pad, readAppliedMigrationsState, resetArkormRuntimeForTests, resolveCast, resolveMigrationClassName, resolveMigrationStateFilePath, resolvePrismaType, runMigrationWithPrisma, runPrismaCommand, toMigrationFileSlug, toModelName, writeAppliedMigrationsState };
|
|
5390
|
+
export { ArkormCollection, ArkormException, CliApp, ForeignKeyBuilder, InitCommand, InlineFactory, LengthAwarePaginator, MIGRATION_BRAND, MakeFactoryCommand, MakeMigrationCommand, MakeModelCommand, MakeSeederCommand, MigrateCommand, MigrateRollbackCommand, Migration, MigrationHistoryCommand, Model, ModelFactory, ModelNotFoundException, ModelsSyncCommand, PRISMA_MODEL_REGEX, Paginator, QueryBuilder, SEEDER_BRAND, SchemaBuilder, SeedCommand, Seeder, TableBuilder, URLDriver, applyAlterTableOperation, applyCreateTableOperation, applyDropTableOperation, applyMigrationRollbackToPrismaSchema, applyMigrationToPrismaSchema, applyOperationsToPrismaSchema, buildFieldLine, buildIndexLine, buildInverseRelationLine, buildMigrationIdentity, buildMigrationRunId, buildMigrationSource, buildModelBlock, buildRelationLine, computeMigrationChecksum, configureArkormRuntime, createMigrationTimestamp, createPrismaAdapter, createPrismaDelegateMap, defineConfig, defineFactory, deriveCollectionFieldName, deriveInverseRelationAlias, deriveRelationFieldName, ensureArkormConfigLoading, escapeRegex, findAppliedMigration, findModelBlock, formatDefaultValue, formatRelationAction, generateMigrationFile, getDefaultStubsPath, getLastMigrationRun, getLatestAppliedMigrations, getMigrationPlan, getRuntimePaginationURLDriverFactory, getRuntimePrismaClient, getUserConfig, inferDelegateName, isDelegateLike, isMigrationApplied, loadArkormConfig, markMigrationApplied, markMigrationRun, pad, readAppliedMigrationsState, removeAppliedMigration, resetArkormRuntimeForTests, resolveCast, resolveMigrationClassName, resolveMigrationStateFilePath, resolvePrismaType, runMigrationWithPrisma, runPrismaCommand, toMigrationFileSlug, toModelName, writeAppliedMigrationsState };
|