@schemashift/core 0.7.0 → 0.8.0

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.js CHANGED
@@ -345,7 +345,8 @@ var ECOSYSTEM_RULES = [
345
345
  check: () => ({
346
346
  issue: "drizzle-zod may not support Zod v4. Check for a compatible version before upgrading.",
347
347
  suggestion: "Upgrade drizzle-zod to the latest version that supports Zod v4, or use --legacy-peer-deps.",
348
- severity: "warning"
348
+ severity: "warning",
349
+ upgradeCommand: "npm install drizzle-zod@latest"
349
350
  })
350
351
  },
351
352
  {
@@ -355,7 +356,8 @@ var ECOSYSTEM_RULES = [
355
356
  check: () => ({
356
357
  issue: "zod-prisma generates Zod v3 schemas. Generated files will need regeneration after upgrading to Zod v4.",
357
358
  suggestion: "Upgrade zod-prisma to a v4-compatible version and regenerate schemas.",
358
- severity: "warning"
359
+ severity: "warning",
360
+ upgradeCommand: "npm install zod-prisma@latest"
359
361
  })
360
362
  },
361
363
  {
@@ -365,7 +367,8 @@ var ECOSYSTEM_RULES = [
365
367
  check: () => ({
366
368
  issue: "zod-prisma-types generates Zod v3 schemas. Generated files will need regeneration.",
367
369
  suggestion: "Check for a Zod v4-compatible version of zod-prisma-types.",
368
- severity: "warning"
370
+ severity: "warning",
371
+ upgradeCommand: "npm install zod-prisma-types@latest"
369
372
  })
370
373
  },
371
374
  // API framework integrations
@@ -380,7 +383,8 @@ var ECOSYSTEM_RULES = [
380
383
  return {
381
384
  issue: `tRPC v${major} expects Zod v3 types. A v3 ZodType is not assignable to a v4 ZodType.`,
382
385
  suggestion: "Upgrade to tRPC v11+ which supports Zod v4 via Standard Schema.",
383
- severity: "error"
386
+ severity: "error",
387
+ upgradeCommand: "npm install @trpc/server@latest"
384
388
  };
385
389
  }
386
390
  return {
@@ -397,7 +401,8 @@ var ECOSYSTEM_RULES = [
397
401
  check: () => ({
398
402
  issue: "trpc-ui breaks entirely with Zod v4 schemas.",
399
403
  suggestion: "Check for a Zod v4-compatible version of trpc-ui before upgrading.",
400
- severity: "error"
404
+ severity: "error",
405
+ upgradeCommand: "npm install trpc-ui@latest"
401
406
  })
402
407
  },
403
408
  // Validation utilities
@@ -412,7 +417,8 @@ var ECOSYSTEM_RULES = [
412
417
  return {
413
418
  issue: `zod-validation-error v${major} is not compatible with Zod v4.`,
414
419
  suggestion: "Upgrade zod-validation-error to v5.0.0+ for Zod v4 support.",
415
- severity: "error"
420
+ severity: "error",
421
+ upgradeCommand: "npm install zod-validation-error@^5.0.0"
416
422
  };
417
423
  }
418
424
  return null;
@@ -428,13 +434,15 @@ var ECOSYSTEM_RULES = [
428
434
  return {
429
435
  issue: "@hookform/resolvers zodResolver may need updating for Zod v4.",
430
436
  suggestion: "Upgrade @hookform/resolvers to the latest version with Zod v4 support.",
431
- severity: "warning"
437
+ severity: "warning",
438
+ upgradeCommand: "npm install @hookform/resolvers@latest"
432
439
  };
433
440
  }
434
441
  return {
435
442
  issue: "@hookform/resolvers will need its resolver import updated for the new schema library.",
436
443
  suggestion: "Switch from the old resolver (e.g., yupResolver) to zodResolver from @hookform/resolvers/zod.",
437
- severity: "warning"
444
+ severity: "warning",
445
+ upgradeCommand: "npm install @hookform/resolvers@latest"
438
446
  };
439
447
  }
440
448
  },
@@ -466,7 +474,8 @@ var ECOSYSTEM_RULES = [
466
474
  check: () => ({
467
475
  issue: "zod-openapi may not support Zod v4 yet.",
468
476
  suggestion: "Check for a Zod v4-compatible version of zod-openapi.",
469
- severity: "warning"
477
+ severity: "warning",
478
+ upgradeCommand: "npm install zod-openapi@latest"
470
479
  })
471
480
  },
472
481
  {
@@ -476,7 +485,8 @@ var ECOSYSTEM_RULES = [
476
485
  check: () => ({
477
486
  issue: "@asteasolutions/zod-to-openapi may not support Zod v4 yet.",
478
487
  suggestion: "Check for a Zod v4-compatible version of @asteasolutions/zod-to-openapi.",
479
- severity: "warning"
488
+ severity: "warning",
489
+ upgradeCommand: "npm install @asteasolutions/zod-to-openapi@latest"
480
490
  })
481
491
  }
482
492
  ];
@@ -510,7 +520,8 @@ var EcosystemAnalyzer = class {
510
520
  issue: result.issue,
511
521
  suggestion: result.suggestion,
512
522
  severity: result.severity,
513
- category: rule.category
523
+ category: rule.category,
524
+ ...result.upgradeCommand ? { upgradeCommand: result.upgradeCommand } : {}
514
525
  };
515
526
  dependencies.push(issue);
516
527
  if (result.severity === "error") {
@@ -648,6 +659,120 @@ var CompatibilityAnalyzer = class {
648
659
  }
649
660
  };
650
661
 
662
+ // src/complexity-estimator.ts
663
+ var SCHEMA_FACTORY_PATTERN = /z\.(object|string|number|boolean|array|enum|union|discriminatedUnion|intersection|lazy|tuple|record|literal|nativeEnum|any|unknown|void|null|undefined|never|date|bigint|symbol|function|promise|map|set|custom|preprocess|pipeline|brand|coerce)\s*\(/g;
664
+ var ADVANCED_PATTERNS = [
665
+ [/z\.discriminatedUnion\s*\(/g, "discriminatedUnion"],
666
+ [/z\.intersection\s*\(/g, "intersection"],
667
+ [/z\.lazy\s*\(/g, "recursive"],
668
+ [/\.brand\s*[<(]/g, "branded"],
669
+ [/\.superRefine\s*\(/g, "superRefine"],
670
+ [/\.transform\s*\(/g, "transform"],
671
+ [/\.pipe\s*\(/g, "pipe"],
672
+ [/\.refine\s*\(/g, "refine"]
673
+ ];
674
+ function countMatches(text, pattern) {
675
+ pattern.lastIndex = 0;
676
+ let count = 0;
677
+ while (pattern.exec(text)) count++;
678
+ return count;
679
+ }
680
+ function getMaxChainDepth(text) {
681
+ let maxDepth = 0;
682
+ const lines = text.split("\n");
683
+ for (const line of lines) {
684
+ const dotCalls = line.match(/\.\w+\s*\(/g);
685
+ if (dotCalls && dotCalls.length > maxDepth) {
686
+ maxDepth = dotCalls.length;
687
+ }
688
+ }
689
+ return maxDepth;
690
+ }
691
+ var ComplexityEstimator = class {
692
+ estimate(files) {
693
+ const fileResults = [];
694
+ const warnings = [];
695
+ const riskAreas = [];
696
+ let totalSchemas = 0;
697
+ let advancedPatternCount = 0;
698
+ let hasDeepDiscriminatedUnions = false;
699
+ for (const file of files) {
700
+ const text = file.getFullText();
701
+ const filePath = file.getFilePath();
702
+ const lineCount = file.getEndLineNumber();
703
+ const schemaCount = countMatches(text, new RegExp(SCHEMA_FACTORY_PATTERN.source, "g"));
704
+ totalSchemas += schemaCount;
705
+ const advancedPatterns = [];
706
+ for (const [pattern, name] of ADVANCED_PATTERNS) {
707
+ const count = countMatches(text, new RegExp(pattern.source, "g"));
708
+ if (count > 0) {
709
+ advancedPatterns.push(name);
710
+ advancedPatternCount += count;
711
+ }
712
+ }
713
+ const chainDepth = getMaxChainDepth(text);
714
+ fileResults.push({ filePath, schemaCount, advancedPatterns, chainDepth, lineCount });
715
+ if (lineCount > 500) {
716
+ warnings.push({
717
+ file: filePath,
718
+ message: `Large file (${lineCount} lines) may be difficult to migrate in one pass`,
719
+ severity: "warning"
720
+ });
721
+ }
722
+ if (schemaCount > 50) {
723
+ warnings.push({
724
+ file: filePath,
725
+ message: `High schema density (${schemaCount} schemas) \u2014 consider splitting before migration`,
726
+ severity: "warning"
727
+ });
728
+ }
729
+ if (chainDepth > 20) {
730
+ warnings.push({
731
+ file: filePath,
732
+ message: `Long method chain (${chainDepth} calls) \u2014 higher transformation risk`,
733
+ severity: "warning"
734
+ });
735
+ }
736
+ const duCount = countMatches(text, /z\.discriminatedUnion\s*\(/g);
737
+ if (duCount > 10) {
738
+ hasDeepDiscriminatedUnions = true;
739
+ warnings.push({
740
+ file: filePath,
741
+ message: `${duCount} discriminated unions \u2014 TypeScript TS2589 performance risk in Zod v4`,
742
+ severity: "error"
743
+ });
744
+ }
745
+ if (advancedPatterns.includes("recursive")) {
746
+ riskAreas.push(`Recursive schemas in ${filePath}`);
747
+ }
748
+ if (advancedPatterns.includes("branded")) {
749
+ riskAreas.push(`Branded types in ${filePath}`);
750
+ }
751
+ }
752
+ const effort = this.calculateEffort(
753
+ totalSchemas,
754
+ advancedPatternCount,
755
+ hasDeepDiscriminatedUnions
756
+ );
757
+ return {
758
+ effort,
759
+ totalSchemas,
760
+ totalFiles: files.length,
761
+ advancedPatternCount,
762
+ files: fileResults,
763
+ warnings,
764
+ riskAreas
765
+ };
766
+ }
767
+ calculateEffort(totalSchemas, advancedCount, hasDeepDU) {
768
+ if (totalSchemas >= 500 && hasDeepDU) return "extreme";
769
+ if (totalSchemas >= 200 || advancedCount >= 20) return "high";
770
+ if (totalSchemas >= 50 || advancedCount >= 5) return "moderate";
771
+ if (totalSchemas >= 10) return "low";
772
+ return "trivial";
773
+ }
774
+ };
775
+
651
776
  // src/config.ts
652
777
  import { cosmiconfig } from "cosmiconfig";
653
778
  function validateConfig(config) {
@@ -709,6 +834,8 @@ async function loadConfig(configPath) {
709
834
  }
710
835
 
711
836
  // src/dependency-graph.ts
837
+ import { existsSync as existsSync3, readdirSync, readFileSync as readFileSync3 } from "fs";
838
+ import { join as join3, resolve } from "path";
712
839
  var SchemaDependencyResolver = class {
713
840
  resolve(project, filePaths) {
714
841
  const fileSet = new Set(filePaths);
@@ -794,10 +921,105 @@ var SchemaDependencyResolver = class {
794
921
  return parts.slice(-2).join("/");
795
922
  }
796
923
  };
924
+ var SCHEMA_PACKAGES = /* @__PURE__ */ new Set(["zod", "yup", "joi", "io-ts", "valibot", "@effect/schema"]);
925
+ var MonorepoResolver = class {
926
+ detect(projectPath) {
927
+ const pkgPath = join3(projectPath, "package.json");
928
+ if (!existsSync3(pkgPath)) return false;
929
+ try {
930
+ const pkg = JSON.parse(readFileSync3(pkgPath, "utf-8"));
931
+ return !!pkg.workspaces;
932
+ } catch {
933
+ return false;
934
+ }
935
+ }
936
+ analyze(projectPath) {
937
+ const pkgPath = join3(projectPath, "package.json");
938
+ if (!existsSync3(pkgPath)) {
939
+ return { isMonorepo: false, packages: [], suggestedOrder: [] };
940
+ }
941
+ let workspaceGlobs;
942
+ try {
943
+ const pkg = JSON.parse(readFileSync3(pkgPath, "utf-8"));
944
+ if (!pkg.workspaces) {
945
+ return { isMonorepo: false, packages: [], suggestedOrder: [] };
946
+ }
947
+ workspaceGlobs = Array.isArray(pkg.workspaces) ? pkg.workspaces : pkg.workspaces.packages;
948
+ } catch {
949
+ return { isMonorepo: false, packages: [], suggestedOrder: [] };
950
+ }
951
+ const packages = [];
952
+ const resolvedDirs = this.resolveWorkspaceDirs(projectPath, workspaceGlobs);
953
+ for (const dir of resolvedDirs) {
954
+ const wsPkgPath = join3(dir, "package.json");
955
+ if (!existsSync3(wsPkgPath)) continue;
956
+ try {
957
+ const wsPkg = JSON.parse(readFileSync3(wsPkgPath, "utf-8"));
958
+ if (!wsPkg.name) continue;
959
+ const allDeps = { ...wsPkg.dependencies, ...wsPkg.devDependencies };
960
+ const depNames = Object.keys(allDeps);
961
+ const schemaLibrary = depNames.find((d) => SCHEMA_PACKAGES.has(d));
962
+ packages.push({
963
+ name: wsPkg.name,
964
+ path: dir,
965
+ schemaLibrary,
966
+ dependencies: depNames
967
+ });
968
+ } catch {
969
+ }
970
+ }
971
+ const suggestedOrder = this.suggestOrder(packages);
972
+ return { isMonorepo: true, packages, suggestedOrder };
973
+ }
974
+ suggestOrder(packages) {
975
+ const nameSet = new Set(packages.map((p) => p.name));
976
+ const depMap = /* @__PURE__ */ new Map();
977
+ for (const pkg of packages) {
978
+ const internalDeps = pkg.dependencies.filter((d) => nameSet.has(d));
979
+ depMap.set(pkg.name, internalDeps);
980
+ }
981
+ const visited = /* @__PURE__ */ new Set();
982
+ const sorted = [];
983
+ const visit = (name) => {
984
+ if (visited.has(name)) return;
985
+ visited.add(name);
986
+ for (const dep of depMap.get(name) ?? []) {
987
+ visit(dep);
988
+ }
989
+ sorted.push(name);
990
+ };
991
+ for (const pkg of packages) {
992
+ visit(pkg.name);
993
+ }
994
+ return sorted;
995
+ }
996
+ resolveWorkspaceDirs(projectPath, globs) {
997
+ const dirs = [];
998
+ for (const glob of globs) {
999
+ const clean = glob.replace(/\/?\*$/, "");
1000
+ const base = resolve(projectPath, clean);
1001
+ if (!existsSync3(base)) continue;
1002
+ if (glob.endsWith("*")) {
1003
+ try {
1004
+ const entries = readdirSync(base, { withFileTypes: true });
1005
+ for (const entry of entries) {
1006
+ if (entry.isDirectory()) {
1007
+ dirs.push(join3(base, entry.name));
1008
+ }
1009
+ }
1010
+ } catch {
1011
+ }
1012
+ } else {
1013
+ dirs.push(base);
1014
+ }
1015
+ }
1016
+ return dirs;
1017
+ }
1018
+ };
797
1019
 
798
1020
  // src/detailed-analyzer.ts
799
- import { existsSync as existsSync3, readFileSync as readFileSync3 } from "fs";
800
- import { join as join3 } from "path";
1021
+ import { existsSync as existsSync4, readFileSync as readFileSync4 } from "fs";
1022
+ import { join as join4 } from "path";
801
1023
  var COMPLEXITY_CHAIN_WEIGHT = 2;
802
1024
  var COMPLEXITY_DEPTH_WEIGHT = 3;
803
1025
  var COMPLEXITY_VALIDATION_WEIGHT = 1;
@@ -862,10 +1084,10 @@ var DetailedAnalyzer = class {
862
1084
  }
863
1085
  detectLibraryVersions(projectPath) {
864
1086
  const versions = [];
865
- const pkgPath = join3(projectPath, "package.json");
866
- if (!existsSync3(pkgPath)) return versions;
1087
+ const pkgPath = join4(projectPath, "package.json");
1088
+ if (!existsSync4(pkgPath)) return versions;
867
1089
  try {
868
- const pkg = JSON.parse(readFileSync3(pkgPath, "utf-8"));
1090
+ const pkg = JSON.parse(readFileSync4(pkgPath, "utf-8"));
869
1091
  const knownLibs = ["zod", "yup", "joi", "io-ts", "valibot"];
870
1092
  const allDeps = {
871
1093
  ...pkg.dependencies,
@@ -1038,6 +1260,90 @@ var DetailedAnalyzer = class {
1038
1260
  }
1039
1261
  };
1040
1262
 
1263
+ // src/form-resolver-migrator.ts
1264
+ var RESOLVER_MAPPINGS = {
1265
+ "yup->zod": [
1266
+ {
1267
+ fromImport: "@hookform/resolvers/yup",
1268
+ toImport: "@hookform/resolvers/zod",
1269
+ fromResolver: "yupResolver",
1270
+ toResolver: "zodResolver"
1271
+ }
1272
+ ],
1273
+ "joi->zod": [
1274
+ {
1275
+ fromImport: "@hookform/resolvers/joi",
1276
+ toImport: "@hookform/resolvers/zod",
1277
+ fromResolver: "joiResolver",
1278
+ toResolver: "zodResolver"
1279
+ }
1280
+ ],
1281
+ "zod->valibot": [
1282
+ {
1283
+ fromImport: "@hookform/resolvers/zod",
1284
+ toImport: "@hookform/resolvers/valibot",
1285
+ fromResolver: "zodResolver",
1286
+ toResolver: "valibotResolver"
1287
+ }
1288
+ ]
1289
+ };
1290
+ var TODO_PATTERNS = [
1291
+ {
1292
+ pattern: /from\s+['"]formik['"]/,
1293
+ comment: "/* TODO(schemashift): Formik is unmaintained. Consider migrating to React Hook Form with zodResolver */"
1294
+ },
1295
+ {
1296
+ pattern: /from\s+['"]@mantine\/form['"]/,
1297
+ comment: "/* TODO(schemashift): Update @mantine/form to use Zod schema adapter */"
1298
+ }
1299
+ ];
1300
+ var FormResolverMigrator = class {
1301
+ migrate(sourceFile, from, to) {
1302
+ const migration = `${from}->${to}`;
1303
+ let code = sourceFile.getFullText();
1304
+ const changes = [];
1305
+ const warnings = [];
1306
+ const mappings = RESOLVER_MAPPINGS[migration];
1307
+ if (mappings) {
1308
+ for (const mapping of mappings) {
1309
+ if (code.includes(mapping.fromImport)) {
1310
+ code = code.replaceAll(mapping.fromImport, mapping.toImport);
1311
+ code = code.replaceAll(mapping.fromResolver, mapping.toResolver);
1312
+ changes.push(
1313
+ `Replaced ${mapping.fromResolver} import from '${mapping.fromImport}' with ${mapping.toResolver} from '${mapping.toImport}'`
1314
+ );
1315
+ }
1316
+ }
1317
+ }
1318
+ const lines = code.split("\n");
1319
+ const insertions = [];
1320
+ for (let i = 0; i < lines.length; i++) {
1321
+ const line = lines[i] ?? "";
1322
+ for (const { pattern, comment } of TODO_PATTERNS) {
1323
+ if (pattern.test(line) && !code.includes(comment)) {
1324
+ insertions.push({ index: i, comment });
1325
+ warnings.push(comment.replace(/\/\*\s*|\s*\*\//g, "").trim());
1326
+ }
1327
+ }
1328
+ }
1329
+ for (let i = insertions.length - 1; i >= 0; i--) {
1330
+ const insertion = insertions[i];
1331
+ if (!insertion) continue;
1332
+ lines.splice(insertion.index, 0, insertion.comment);
1333
+ changes.push(`Added TODO comment for ${lines[insertion.index + 1]?.trim()}`);
1334
+ }
1335
+ if (insertions.length > 0) {
1336
+ code = lines.join("\n");
1337
+ }
1338
+ return {
1339
+ success: true,
1340
+ transformedCode: code,
1341
+ changes,
1342
+ warnings
1343
+ };
1344
+ }
1345
+ };
1346
+
1041
1347
  // src/governance.ts
1042
1348
  var GovernanceEngine = class {
1043
1349
  rules = /* @__PURE__ */ new Map();
@@ -1159,16 +1465,16 @@ var GovernanceEngine = class {
1159
1465
  };
1160
1466
 
1161
1467
  // src/incremental.ts
1162
- import { existsSync as existsSync4, mkdirSync, readFileSync as readFileSync4, writeFileSync } from "fs";
1163
- import { join as join4 } from "path";
1468
+ import { existsSync as existsSync5, mkdirSync, readFileSync as readFileSync5, writeFileSync } from "fs";
1469
+ import { join as join5 } from "path";
1164
1470
  var STATE_DIR = ".schemashift";
1165
1471
  var STATE_FILE = "incremental.json";
1166
1472
  var IncrementalTracker = class {
1167
1473
  stateDir;
1168
1474
  statePath;
1169
1475
  constructor(projectPath) {
1170
- this.stateDir = join4(projectPath, STATE_DIR);
1171
- this.statePath = join4(this.stateDir, STATE_FILE);
1476
+ this.stateDir = join5(projectPath, STATE_DIR);
1477
+ this.statePath = join5(this.stateDir, STATE_FILE);
1172
1478
  }
1173
1479
  start(files, from, to) {
1174
1480
  const state = {
@@ -1203,9 +1509,9 @@ var IncrementalTracker = class {
1203
1509
  this.saveState(state);
1204
1510
  }
1205
1511
  getState() {
1206
- if (!existsSync4(this.statePath)) return null;
1512
+ if (!existsSync5(this.statePath)) return null;
1207
1513
  try {
1208
- return JSON.parse(readFileSync4(this.statePath, "utf-8"));
1514
+ return JSON.parse(readFileSync5(this.statePath, "utf-8"));
1209
1515
  } catch {
1210
1516
  return null;
1211
1517
  }
@@ -1232,12 +1538,12 @@ var IncrementalTracker = class {
1232
1538
  };
1233
1539
  }
1234
1540
  clear() {
1235
- if (existsSync4(this.statePath)) {
1541
+ if (existsSync5(this.statePath)) {
1236
1542
  writeFileSync(this.statePath, "");
1237
1543
  }
1238
1544
  }
1239
1545
  saveState(state) {
1240
- if (!existsSync4(this.stateDir)) {
1546
+ if (!existsSync5(this.stateDir)) {
1241
1547
  mkdirSync(this.stateDir, { recursive: true });
1242
1548
  }
1243
1549
  writeFileSync(this.statePath, JSON.stringify(state, null, 2));
@@ -1245,8 +1551,8 @@ var IncrementalTracker = class {
1245
1551
  };
1246
1552
 
1247
1553
  // src/package-updater.ts
1248
- import { existsSync as existsSync5, readFileSync as readFileSync5, writeFileSync as writeFileSync2 } from "fs";
1249
- import { join as join5 } from "path";
1554
+ import { existsSync as existsSync6, readFileSync as readFileSync6, writeFileSync as writeFileSync2 } from "fs";
1555
+ import { join as join6 } from "path";
1250
1556
  var TARGET_VERSIONS = {
1251
1557
  "yup->zod": { zod: "^3.24.0" },
1252
1558
  "joi->zod": { zod: "^3.24.0" },
@@ -1267,14 +1573,14 @@ var PackageUpdater = class {
1267
1573
  const add = {};
1268
1574
  const remove = [];
1269
1575
  const warnings = [];
1270
- const pkgPath = join5(projectPath, "package.json");
1271
- if (!existsSync5(pkgPath)) {
1576
+ const pkgPath = join6(projectPath, "package.json");
1577
+ if (!existsSync6(pkgPath)) {
1272
1578
  warnings.push("No package.json found. Cannot plan dependency updates.");
1273
1579
  return { add, remove, warnings };
1274
1580
  }
1275
1581
  let pkg;
1276
1582
  try {
1277
- pkg = JSON.parse(readFileSync5(pkgPath, "utf-8"));
1583
+ pkg = JSON.parse(readFileSync6(pkgPath, "utf-8"));
1278
1584
  } catch {
1279
1585
  warnings.push("Could not parse package.json.");
1280
1586
  return { add, remove, warnings };
@@ -1304,9 +1610,9 @@ var PackageUpdater = class {
1304
1610
  return { add, remove, warnings };
1305
1611
  }
1306
1612
  apply(projectPath, plan) {
1307
- const pkgPath = join5(projectPath, "package.json");
1308
- if (!existsSync5(pkgPath)) return;
1309
- const pkgText = readFileSync5(pkgPath, "utf-8");
1613
+ const pkgPath = join6(projectPath, "package.json");
1614
+ if (!existsSync6(pkgPath)) return;
1615
+ const pkgText = readFileSync6(pkgPath, "utf-8");
1310
1616
  const pkg = JSON.parse(pkgText);
1311
1617
  if (!pkg.dependencies) pkg.dependencies = {};
1312
1618
  for (const [name, version] of Object.entries(plan.add)) {
@@ -1366,8 +1672,8 @@ var PluginLoader = class {
1366
1672
  };
1367
1673
 
1368
1674
  // src/standard-schema.ts
1369
- import { existsSync as existsSync6, readFileSync as readFileSync6 } from "fs";
1370
- import { join as join6 } from "path";
1675
+ import { existsSync as existsSync7, readFileSync as readFileSync7 } from "fs";
1676
+ import { join as join7 } from "path";
1371
1677
  var STANDARD_SCHEMA_LIBRARIES = {
1372
1678
  zod: { minMajor: 3, minMinor: 23 },
1373
1679
  // Zod v3.23+ and v4+
@@ -1396,13 +1702,13 @@ function isVersionCompatible(version, minMajor, minMinor) {
1396
1702
  return false;
1397
1703
  }
1398
1704
  function detectStandardSchema(projectPath) {
1399
- const pkgPath = join6(projectPath, "package.json");
1400
- if (!existsSync6(pkgPath)) {
1705
+ const pkgPath = join7(projectPath, "package.json");
1706
+ if (!existsSync7(pkgPath)) {
1401
1707
  return { detected: false, compatibleLibraries: [], recommendation: "" };
1402
1708
  }
1403
1709
  let allDeps = {};
1404
1710
  try {
1405
- const pkg = JSON.parse(readFileSync6(pkgPath, "utf-8"));
1711
+ const pkg = JSON.parse(readFileSync7(pkgPath, "utf-8"));
1406
1712
  allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
1407
1713
  } catch {
1408
1714
  return { detected: false, compatibleLibraries: [], recommendation: "" };
@@ -1461,11 +1767,14 @@ var TransformEngine = class {
1461
1767
  };
1462
1768
  export {
1463
1769
  CompatibilityAnalyzer,
1770
+ ComplexityEstimator,
1464
1771
  DetailedAnalyzer,
1465
1772
  EcosystemAnalyzer,
1773
+ FormResolverMigrator,
1466
1774
  GovernanceEngine,
1467
1775
  IncrementalTracker,
1468
1776
  MigrationChain,
1777
+ MonorepoResolver,
1469
1778
  PackageUpdater,
1470
1779
  PluginLoader,
1471
1780
  SchemaAnalyzer,