@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.cjs +353 -41
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +57 -1
- package/dist/index.d.ts +57 -1
- package/dist/index.js +346 -37
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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
|
|
800
|
-
import { join as
|
|
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 =
|
|
866
|
-
if (!
|
|
1087
|
+
const pkgPath = join4(projectPath, "package.json");
|
|
1088
|
+
if (!existsSync4(pkgPath)) return versions;
|
|
867
1089
|
try {
|
|
868
|
-
const pkg = JSON.parse(
|
|
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
|
|
1163
|
-
import { join as
|
|
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 =
|
|
1171
|
-
this.statePath =
|
|
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 (!
|
|
1512
|
+
if (!existsSync5(this.statePath)) return null;
|
|
1207
1513
|
try {
|
|
1208
|
-
return JSON.parse(
|
|
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 (
|
|
1541
|
+
if (existsSync5(this.statePath)) {
|
|
1236
1542
|
writeFileSync(this.statePath, "");
|
|
1237
1543
|
}
|
|
1238
1544
|
}
|
|
1239
1545
|
saveState(state) {
|
|
1240
|
-
if (!
|
|
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
|
|
1249
|
-
import { join as
|
|
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 =
|
|
1271
|
-
if (!
|
|
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(
|
|
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 =
|
|
1308
|
-
if (!
|
|
1309
|
-
const pkgText =
|
|
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
|
|
1370
|
-
import { join as
|
|
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 =
|
|
1400
|
-
if (!
|
|
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(
|
|
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,
|