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/index.mjs CHANGED
@@ -1,11 +1,11 @@
1
- import { copyFileSync, existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync } from "fs";
2
- import path, { dirname, extname, join, relative } from "path";
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$1(process.cwd(), "database", "migrations");
1073
+ const directory = options.directory ?? join(process.cwd(), "database", "migrations");
1074
1074
  const fileName = `${timestamp}_${fileSlug}.${extension}`;
1075
- const filePath = join$1(directory, fileName);
1075
+ const filePath = join(directory, fileName);
1076
1076
  const content = buildMigrationSource(className, extension);
1077
1077
  if (options.write ?? true) {
1078
- if (!existsSync$1(directory)) mkdirSync$1(directory, { recursive: true });
1079
- if (existsSync$1(filePath)) throw new ArkormException(`Migration file already exists: ${filePath}`);
1080
- writeFileSync$1(filePath, content);
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$1(process.cwd(), "prisma", "schema.prisma");
1114
- if (!existsSync$1(schemaPath)) throw new ArkormException(`Prisma schema file not found: ${schemaPath}`);
1115
- const source = readFileSync$1(schemaPath, "utf-8");
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$1(schemaPath, schema);
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$1(cwd, "prisma", "schema.prisma"),
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]+)(\?)?\b/);
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
- optional: Boolean(fieldMatch[3])
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.optional ? "?" : ""}: ${field.type}`);
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$1(process.cwd(), "arkormx.config.js");
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$1(stubsDir, "arkormx.config.stub");
1868
- const legacyStubPath = join$1(stubsDir, "arkorm.config.stub");
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$1(cwd, ".arkormx", "migrations.applied.json");
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$1(fileName).length)}:${className}`;
2041
+ return `${fileName.slice(0, fileName.length - extname(fileName).length)}:${className}`;
2019
2042
  };
2020
2043
  const computeMigrationChecksum = (filePath) => {
2021
- const source = readFileSync$1(filePath, "utf-8");
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$1(stateFilePath)) return { ...DEFAULT_STATE };
2048
+ if (!existsSync(stateFilePath)) return { ...DEFAULT_STATE };
2026
2049
  try {
2027
- const parsed = JSON.parse(readFileSync$1(stateFilePath, "utf-8"));
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$1(stateFilePath);
2041
- if (!existsSync$1(directory)) mkdirSync$1(directory, { recursive: true });
2042
- writeFileSync$1(stateFilePath, JSON.stringify(state, null, 2));
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$1(process.cwd(), "database", "migrations");
2167
+ const configuredMigrationsDir = this.app.getConfig("paths")?.migrations ?? join(process.cwd(), "database", "migrations");
2111
2168
  const migrationsDir = this.app.resolveRuntimeDirectoryPath(configuredMigrationsDir);
2112
- if (!existsSync$1(migrationsDir)) return void this.error(`Error: Migrations directory not found: ${this.app.formatPathForLog(configuredMigrationsDir)}`);
2113
- const schemaPath = this.option("schema") ? resolve(String(this.option("schema"))) : join$1(process.cwd(), "prisma", "schema.prisma");
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 = shouldTrackApplied ? readAppliedMigrationsState(stateFilePath) : void 0;
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$1(migrationsDir).filter((file) => /\.(ts|js|mjs|cjs)$/i.test(file)).sort((left, right) => left.localeCompare(right)).map((file) => this.app.resolveRuntimeScriptPath(join$1(migrationsDir, file)));
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$1(migrationsDir, file)).find((file) => existsSync$1(file));
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$1(stateFilePath)) {
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$1(stateFilePath);
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$1(process.cwd(), "database", "seeders");
2517
+ const configuredSeedersDir = this.app.getConfig("paths")?.seeders ?? join(process.cwd(), "database", "seeders");
2370
2518
  const seedersDir = this.app.resolveRuntimeDirectoryPath(configuredSeedersDir);
2371
- if (!existsSync$1(seedersDir)) return void this.error(`ERROR: Seeders directory not found: ${this.app.formatPathForLog(configuredSeedersDir)}`);
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$1(seedersDir).filter((file) => /\.(ts|js|mjs|cjs)$/i.test(file)).map((file) => this.app.resolveRuntimeScriptPath(join$1(seedersDir, file)));
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$1(seedersDir, file)).find((file) => existsSync$1(file));
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 };