@schemashift/core 0.8.0 → 0.10.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.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Project, CallExpression, Node, SourceFile } from 'ts-morph';
2
2
 
3
- type SchemaLibrary = 'zod' | 'zod-v3' | 'yup' | 'joi' | 'io-ts' | 'valibot' | 'v4' | 'unknown';
3
+ type SchemaLibrary = 'zod' | 'zod-v3' | 'yup' | 'joi' | 'io-ts' | 'valibot' | 'arktype' | 'superstruct' | 'effect' | 'v4' | 'unknown';
4
4
  interface SchemaInfo {
5
5
  name: string;
6
6
  filePath: string;
@@ -143,6 +143,144 @@ declare function transformMethodChain(chain: CallChainInfo, newBase: string, fac
143
143
  args: string[];
144
144
  }[] | null | undefined): string;
145
145
 
146
+ interface AuditEntryMetadata {
147
+ gitCommit?: string;
148
+ gitBranch?: string;
149
+ ciJobId?: string;
150
+ ciProvider?: string;
151
+ hostname?: string;
152
+ nodeVersion?: string;
153
+ schemashiftVersion?: string;
154
+ }
155
+ interface AuditEntry {
156
+ timestamp: string;
157
+ migrationId: string;
158
+ filePath: string;
159
+ action: 'transform' | 'rollback' | 'skip';
160
+ from: string;
161
+ to: string;
162
+ success: boolean;
163
+ beforeHash: string;
164
+ afterHash?: string;
165
+ warningCount: number;
166
+ errorCount: number;
167
+ riskScore?: number;
168
+ user?: string;
169
+ duration?: number;
170
+ metadata?: AuditEntryMetadata;
171
+ }
172
+ interface AuditLog {
173
+ version: number;
174
+ entries: AuditEntry[];
175
+ }
176
+ declare class MigrationAuditLog {
177
+ private logDir;
178
+ private logPath;
179
+ constructor(projectPath: string);
180
+ /**
181
+ * Append a new entry to the audit log.
182
+ */
183
+ append(entry: AuditEntry): void;
184
+ /**
185
+ * Create an audit entry for a file transformation.
186
+ */
187
+ createEntry(params: {
188
+ migrationId: string;
189
+ filePath: string;
190
+ from: string;
191
+ to: string;
192
+ originalCode: string;
193
+ transformedCode?: string;
194
+ success: boolean;
195
+ warningCount: number;
196
+ errorCount: number;
197
+ riskScore?: number;
198
+ duration?: number;
199
+ metadata?: AuditEntryMetadata;
200
+ }): AuditEntry;
201
+ /**
202
+ * Read the current audit log.
203
+ */
204
+ read(): AuditLog;
205
+ /**
206
+ * Get entries for a specific migration.
207
+ */
208
+ getByMigration(migrationId: string): AuditEntry[];
209
+ /**
210
+ * Get summary statistics for the audit log.
211
+ */
212
+ getSummary(): {
213
+ totalMigrations: number;
214
+ totalFiles: number;
215
+ successCount: number;
216
+ failureCount: number;
217
+ migrationPaths: string[];
218
+ };
219
+ /**
220
+ * Export audit log as JSON string.
221
+ */
222
+ exportJson(): string;
223
+ /**
224
+ * Export audit log as CSV string.
225
+ */
226
+ exportCsv(): string;
227
+ /**
228
+ * Get entries filtered by date range.
229
+ */
230
+ getByDateRange(start: Date, end: Date): AuditEntry[];
231
+ /**
232
+ * Clear the audit log.
233
+ */
234
+ clear(): void;
235
+ private collectMetadata;
236
+ private write;
237
+ private hashContent;
238
+ private getCurrentUser;
239
+ }
240
+
241
+ interface BehavioralWarning {
242
+ category: BehavioralCategory;
243
+ message: string;
244
+ detail: string;
245
+ filePath: string;
246
+ lineNumber?: number;
247
+ severity: 'info' | 'warning' | 'error';
248
+ migration: string;
249
+ }
250
+ type BehavioralCategory = 'type-coercion' | 'error-handling' | 'default-values' | 'error-format' | 'form-input' | 'validation-behavior' | 'null-handling';
251
+ interface BehavioralAnalysisResult {
252
+ warnings: BehavioralWarning[];
253
+ migrationPath: string;
254
+ summary: string;
255
+ }
256
+ declare class BehavioralWarningAnalyzer {
257
+ analyze(sourceFiles: SourceFile[], from: SchemaLibrary, to: SchemaLibrary): BehavioralAnalysisResult;
258
+ private fileUsesLibrary;
259
+ private generateSummary;
260
+ }
261
+
262
+ interface BundleSizeEstimate {
263
+ from: LibraryBundleInfo;
264
+ to: LibraryBundleInfo;
265
+ estimatedDelta: number;
266
+ deltaPercent: number;
267
+ summary: string;
268
+ caveats: string[];
269
+ }
270
+ interface LibraryBundleInfo {
271
+ library: string;
272
+ minifiedGzipKb: number;
273
+ treeShakable: boolean;
274
+ estimatedUsedKb: number;
275
+ }
276
+ declare class BundleEstimator {
277
+ estimate(sourceFiles: SourceFile[], from: SchemaLibrary, to: SchemaLibrary): BundleSizeEstimate;
278
+ private countUsedValidators;
279
+ private getLibraryInfo;
280
+ private generateCaveats;
281
+ private generateSummary;
282
+ }
283
+
146
284
  interface TransformHandler {
147
285
  transform(sourceFile: SourceFile, options: TransformOptions): TransformResult;
148
286
  }
@@ -200,6 +338,10 @@ interface EcosystemReport {
200
338
  }
201
339
  declare class EcosystemAnalyzer {
202
340
  analyze(projectPath: string, from: string, to: string): EcosystemReport;
341
+ /**
342
+ * Returns a list of npm install commands needed to resolve ecosystem issues.
343
+ */
344
+ getUpgradeCommands(report: EcosystemReport): string[];
203
345
  }
204
346
 
205
347
  interface VersionIssue {
@@ -340,10 +482,47 @@ interface MonorepoInfo {
340
482
  packages: MonorepoPackage[];
341
483
  suggestedOrder: string[];
342
484
  }
485
+ /**
486
+ * Groups monorepo packages into parallelizable batches.
487
+ * Packages within the same batch have no dependencies on each other.
488
+ * Batches must be executed in order (batch 0 first, then batch 1, etc.).
489
+ */
490
+ interface ParallelBatch {
491
+ /** Batch index (0-based, execute in order) */
492
+ index: number;
493
+ /** Package names that can be processed in parallel */
494
+ packages: string[];
495
+ }
496
+ /**
497
+ * Computes parallel execution batches from a topological ordering.
498
+ * Packages are grouped by their "depth" in the dependency graph — packages
499
+ * at the same depth have no mutual dependencies and can run concurrently.
500
+ */
501
+ declare function computeParallelBatches(packages: MonorepoPackage[], suggestedOrder: string[]): ParallelBatch[];
502
+ type WorkspaceManager = 'npm' | 'pnpm' | 'yarn';
343
503
  declare class MonorepoResolver {
344
504
  detect(projectPath: string): boolean;
505
+ /**
506
+ * Detect which workspace manager is being used.
507
+ */
508
+ detectManager(projectPath: string): WorkspaceManager;
345
509
  analyze(projectPath: string): MonorepoInfo;
346
510
  private suggestOrder;
511
+ /**
512
+ * Resolve workspace glob patterns from any supported format.
513
+ * Supports: npm/yarn workspaces (package.json), pnpm-workspace.yaml
514
+ */
515
+ private resolveWorkspaceGlobs;
516
+ /**
517
+ * Parse pnpm-workspace.yaml to extract workspace package globs.
518
+ * Simple YAML parsing for the common format:
519
+ * ```
520
+ * packages:
521
+ * - 'packages/*'
522
+ * - 'apps/*'
523
+ * ```
524
+ */
525
+ private parsePnpmWorkspace;
347
526
  private resolveWorkspaceDirs;
348
527
  }
349
528
 
@@ -403,6 +582,67 @@ interface FormLibraryDetection {
403
582
  }
404
583
  declare function detectFormLibraries(sourceFile: SourceFile): FormLibraryDetection[];
405
584
 
585
+ interface SchemaSnapshot {
586
+ version: number;
587
+ timestamp: string;
588
+ projectPath: string;
589
+ schemas: SchemaFileSnapshot[];
590
+ }
591
+ interface SchemaFileSnapshot {
592
+ filePath: string;
593
+ library: string;
594
+ contentHash: string;
595
+ schemaCount: number;
596
+ schemaNames: string[];
597
+ }
598
+ interface DriftResult {
599
+ hasDrift: boolean;
600
+ added: SchemaFileSnapshot[];
601
+ removed: SchemaFileSnapshot[];
602
+ modified: DriftModification[];
603
+ unchanged: number;
604
+ totalFiles: number;
605
+ snapshotTimestamp: string;
606
+ }
607
+ interface DriftModification {
608
+ filePath: string;
609
+ library: string;
610
+ previousHash: string;
611
+ currentHash: string;
612
+ previousSchemaCount: number;
613
+ currentSchemaCount: number;
614
+ addedSchemas: string[];
615
+ removedSchemas: string[];
616
+ }
617
+ declare class DriftDetector {
618
+ private snapshotDir;
619
+ private snapshotPath;
620
+ constructor(projectPath: string);
621
+ /**
622
+ * Take a snapshot of the current schema state
623
+ */
624
+ snapshot(files: string[], projectPath: string): SchemaSnapshot;
625
+ /**
626
+ * Save a snapshot to disk
627
+ */
628
+ saveSnapshot(snapshot: SchemaSnapshot): void;
629
+ /**
630
+ * Load saved snapshot from disk
631
+ */
632
+ loadSnapshot(): SchemaSnapshot | null;
633
+ /**
634
+ * Compare current state against saved snapshot
635
+ */
636
+ detect(currentFiles: string[], projectPath: string): DriftResult;
637
+ /**
638
+ * Compare two snapshots and return drift results
639
+ */
640
+ compareSnapshots(baseline: SchemaSnapshot, current: SchemaSnapshot): DriftResult;
641
+ private extractSchemaNames;
642
+ private detectLibraryFromContent;
643
+ private hashContent;
644
+ }
645
+
406
646
  interface FormResolverResult {
407
647
  success: boolean;
408
648
  transformedCode: string;
@@ -428,14 +668,64 @@ interface GovernanceResult {
428
668
  schemasChecked: number;
429
669
  passed: boolean;
430
670
  }
671
+ /**
672
+ * Custom governance rule function interface.
673
+ * Plugins can define rules as functions that receive a source file and config,
674
+ * and return violations found.
675
+ */
676
+ type GovernanceRuleFunction = (sourceFile: SourceFile, config: GovernanceRuleConfig) => GovernanceViolation[];
431
677
  declare class GovernanceEngine {
432
678
  private rules;
679
+ private customRuleFunctions;
433
680
  configure(rules: Record<string, GovernanceRuleConfig>): void;
681
+ /**
682
+ * Register a custom governance rule function.
683
+ * Custom rules are executed per-file alongside built-in rules.
684
+ */
685
+ registerRule(name: string, fn: GovernanceRuleFunction): void;
434
686
  analyze(project: Project): GovernanceResult;
435
687
  private detectFileLibrary;
688
+ private measureNestingDepth;
689
+ private detectDynamicSchemas;
690
+ private getSchemaPrefix;
436
691
  private isSchemaExpression;
437
692
  }
438
693
 
694
+ /**
695
+ * Governance Rule Templates
696
+ *
697
+ * Pre-built governance rules for common enterprise policies.
698
+ * These can be registered into the GovernanceEngine for quick setup.
699
+ *
700
+ * Template categories:
701
+ * - Security: Prevent unsafe patterns (XSS, injection, DoS)
702
+ * - Quality: Enforce code quality standards
703
+ * - Compliance: Support SOX, HIPAA, GDPR requirements
704
+ * - Performance: Prevent known performance pitfalls
705
+ */
706
+ interface GovernanceTemplate {
707
+ name: string;
708
+ description: string;
709
+ category: 'security' | 'quality' | 'compliance' | 'performance';
710
+ rule: GovernanceRuleFunction;
711
+ }
712
+ /**
713
+ * All available governance rule templates
714
+ */
715
+ declare const GOVERNANCE_TEMPLATES: GovernanceTemplate[];
716
+ /**
717
+ * Get a governance template by name
718
+ */
719
+ declare function getGovernanceTemplate(name: string): GovernanceTemplate | undefined;
720
+ /**
721
+ * Get all templates for a category
722
+ */
723
+ declare function getGovernanceTemplatesByCategory(category: GovernanceTemplate['category']): GovernanceTemplate[];
724
+ /**
725
+ * Get all available template names
726
+ */
727
+ declare function getGovernanceTemplateNames(): string[];
728
+
439
729
  interface IncrementalState {
440
730
  migrationId: string;
441
731
  from: SchemaLibrary;
@@ -476,6 +766,39 @@ declare class PackageUpdater {
476
766
  apply(projectPath: string, plan: PackageUpdatePlan): void;
477
767
  }
478
768
 
769
+ interface PerformanceWarning {
770
+ category: PerformanceCategory;
771
+ message: string;
772
+ detail: string;
773
+ filePath: string;
774
+ lineNumber?: number;
775
+ severity: 'info' | 'warning' | 'error';
776
+ }
777
+ type PerformanceCategory = 'jit-overhead' | 'cold-start' | 'repeated-parsing' | 'schema-creation' | 'dynamic-schemas';
778
+ interface PerformanceAnalysisResult {
779
+ warnings: PerformanceWarning[];
780
+ parseCallSites: number;
781
+ dynamicSchemaCount: number;
782
+ recommendation: string;
783
+ summary: string;
784
+ }
785
+ /**
786
+ * Analyzes performance implications of schema library migration.
787
+ *
788
+ * Key considerations:
789
+ * - Zod v4 uses JIT compilation: 17x slower schema creation, 8x faster repeated parsing
790
+ * - Valibot is ~2x faster than Zod v3, similar to v4 for runtime
791
+ * - Serverless/edge: Zod v4 JIT penalizes cold starts
792
+ * - Long-lived servers: Zod v4 JIT amortizes well over repeated parses
793
+ */
794
+ declare class PerformanceAnalyzer {
795
+ analyze(sourceFiles: SourceFile[], from: SchemaLibrary, to: SchemaLibrary): PerformanceAnalysisResult;
796
+ private detectDynamicSchemas;
797
+ private addMigrationWarnings;
798
+ private getRecommendation;
799
+ private generateSummary;
800
+ }
801
+
479
802
  interface SchemaShiftPlugin {
480
803
  name: string;
481
804
  version: string;
@@ -485,6 +808,10 @@ interface SchemaShiftPlugin {
485
808
  handler: TransformHandler;
486
809
  }>;
487
810
  rules?: CustomRule[];
811
+ governanceRules?: Array<{
812
+ name: string;
813
+ fn: GovernanceRuleFunction;
814
+ }>;
488
815
  }
489
816
  interface PluginLoadResult {
490
817
  loaded: SchemaShiftPlugin[];
@@ -502,7 +829,69 @@ interface StandardSchemaInfo {
502
829
  version: string;
503
830
  }>;
504
831
  recommendation: string;
832
+ adoptionPath?: string;
833
+ interopTools: string[];
505
834
  }
506
835
  declare function detectStandardSchema(projectPath: string): StandardSchemaInfo;
507
836
 
508
- export { type AnalysisResult, type CallChainInfo, type ChainResult, type ChainStep, type ChainStepResult, type ChainValidation, CompatibilityAnalyzer, type CompatibilityResult, type ComplexityEstimate, ComplexityEstimator, type ComplexityWarning, type CustomRule, type DependencyGraphResult, type DetailedAnalysisResult, DetailedAnalyzer, EcosystemAnalyzer, type EcosystemIssue, type EcosystemReport, type EffortLevel, type FileComplexity, type FormLibraryDetection, FormResolverMigrator, type FormResolverResult, GovernanceEngine, type GovernanceResult, type GovernanceRuleConfig, type GovernanceViolation, type IncrementalState, IncrementalTracker, type LibraryVersionInfo, type MethodCallInfo, MigrationChain, type MigrationReadiness, type MonorepoInfo, type MonorepoPackage, MonorepoResolver, type PackageUpdatePlan, PackageUpdater, type PluginLoadResult, PluginLoader, SchemaAnalyzer, type SchemaComplexity, SchemaDependencyResolver, type SchemaInfo, type SchemaLibrary, type SchemaShiftConfig, type SchemaShiftPlugin, type StandardSchemaInfo, TransformEngine, type TransformError, type TransformHandler, type TransformOptions, type TransformResult, type VersionIssue, type WarningSuppressionRule, buildCallChain, detectFormLibraries, detectSchemaLibrary, detectStandardSchema, isInsideComment, isInsideStringLiteral, loadConfig, parseCallChain, shouldSuppressWarning, startsWithBase, transformMethodChain, validateConfig };
837
+ interface ScaffoldedTest {
838
+ filePath: string;
839
+ testCode: string;
840
+ schemaCount: number;
841
+ }
842
+ interface TestScaffoldResult {
843
+ tests: ScaffoldedTest[];
844
+ totalSchemas: number;
845
+ summary: string;
846
+ }
847
+ /**
848
+ * Generates test files that validate pre/post migration behavior equivalence.
849
+ *
850
+ * For each schema file, generates a test that:
851
+ * 1. Imports the schema
852
+ * 2. Tests validation of sample data (valid + invalid)
853
+ * 3. Verifies error behavior is consistent
854
+ */
855
+ declare class TestScaffolder {
856
+ scaffold(sourceFiles: SourceFile[], from: SchemaLibrary, to: SchemaLibrary): TestScaffoldResult;
857
+ private extractSchemaNames;
858
+ private getLibraryPrefixes;
859
+ private generateTestFile;
860
+ private getParseMethod;
861
+ private getErrorClass;
862
+ private generateSchemaTests;
863
+ }
864
+
865
+ interface DuplicateTypeCandidate {
866
+ typeName: string;
867
+ typeFilePath: string;
868
+ typeLineNumber: number;
869
+ schemaName: string;
870
+ schemaFilePath: string;
871
+ schemaLineNumber: number;
872
+ matchedFields: string[];
873
+ confidence: 'high' | 'medium' | 'low';
874
+ suggestion: string;
875
+ }
876
+ interface TypeDedupResult {
877
+ candidates: DuplicateTypeCandidate[];
878
+ summary: string;
879
+ }
880
+ /**
881
+ * Detects TypeScript interfaces/types that mirror schema shapes.
882
+ *
883
+ * In Joi and Yup codebases, developers often maintain duplicate type definitions
884
+ * alongside schemas because those libraries don't infer TypeScript types.
885
+ * After migrating to Zod, these duplicates can be replaced with z.infer<typeof schema>.
886
+ */
887
+ declare class TypeDedupDetector {
888
+ detect(sourceFiles: SourceFile[]): TypeDedupResult;
889
+ private collectTypeDefinitions;
890
+ private collectSchemaDefinitions;
891
+ private extractSchemaFields;
892
+ private findMatches;
893
+ private getMatchedFields;
894
+ private namesRelated;
895
+ }
896
+
897
+ export { type AnalysisResult, type AuditEntry, type AuditEntryMetadata, type AuditLog, type BehavioralAnalysisResult, type BehavioralCategory, type BehavioralWarning, BehavioralWarningAnalyzer, BundleEstimator, type BundleSizeEstimate, type CallChainInfo, type ChainResult, type ChainStep, type ChainStepResult, type ChainValidation, CompatibilityAnalyzer, type CompatibilityResult, type ComplexityEstimate, ComplexityEstimator, type ComplexityWarning, type CustomRule, type DependencyGraphResult, type DetailedAnalysisResult, DetailedAnalyzer, DriftDetector, type DriftModification, type DriftResult, type DuplicateTypeCandidate, EcosystemAnalyzer, type EcosystemIssue, type EcosystemReport, type EffortLevel, type FileComplexity, type FormLibraryDetection, FormResolverMigrator, type FormResolverResult, GOVERNANCE_TEMPLATES, GovernanceEngine, type GovernanceResult, type GovernanceRuleConfig, type GovernanceRuleFunction, type GovernanceTemplate, type GovernanceViolation, type IncrementalState, IncrementalTracker, type LibraryBundleInfo, type LibraryVersionInfo, type MethodCallInfo, MigrationAuditLog, MigrationChain, type MigrationReadiness, type MonorepoInfo, type MonorepoPackage, MonorepoResolver, type PackageUpdatePlan, PackageUpdater, type ParallelBatch, type PerformanceAnalysisResult, PerformanceAnalyzer, type PerformanceCategory, type PerformanceWarning, type PluginLoadResult, PluginLoader, type ScaffoldedTest, SchemaAnalyzer, type SchemaComplexity, SchemaDependencyResolver, type SchemaFileSnapshot, type SchemaInfo, type SchemaLibrary, type SchemaShiftConfig, type SchemaShiftPlugin, type SchemaSnapshot, type StandardSchemaInfo, type TestScaffoldResult, TestScaffolder, TransformEngine, type TransformError, type TransformHandler, type TransformOptions, type TransformResult, TypeDedupDetector, type TypeDedupResult, type VersionIssue, type WarningSuppressionRule, type WorkspaceManager, buildCallChain, computeParallelBatches, detectFormLibraries, detectSchemaLibrary, detectStandardSchema, getGovernanceTemplate, getGovernanceTemplateNames, getGovernanceTemplatesByCategory, isInsideComment, isInsideStringLiteral, loadConfig, parseCallChain, shouldSuppressWarning, startsWithBase, transformMethodChain, validateConfig };