@oamm/textor 1.0.10 → 1.0.11

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.
@@ -647,7 +647,8 @@ async function verifyFileIntegrity(filePath, expectedHash, options = {}) {
647
647
  acceptChanges = false,
648
648
  normalization = 'normalizeEOL',
649
649
  owner = null,
650
- actualOwner = null
650
+ actualOwner = null,
651
+ signatures = []
651
652
  } = options;
652
653
 
653
654
  if (force) return { valid: true };
@@ -660,7 +661,7 @@ async function verifyFileIntegrity(filePath, expectedHash, options = {}) {
660
661
  };
661
662
  }
662
663
 
663
- const isGenerated = await isTextorGenerated(filePath);
664
+ const isGenerated = await isTextorGenerated(filePath, signatures);
664
665
  if (!isGenerated) {
665
666
  return {
666
667
  valid: false,
@@ -693,7 +694,7 @@ async function verifyFileIntegrity(filePath, expectedHash, options = {}) {
693
694
  }
694
695
 
695
696
  async function safeDelete(filePath, options = {}) {
696
- const { force = false, expectedHash = null, acceptChanges = false, owner = null, actualOwner = null } = options;
697
+ const { force = false, expectedHash = null, acceptChanges = false, owner = null, actualOwner = null, signatures = [] } = options;
697
698
 
698
699
  if (!existsSync(filePath)) {
699
700
  return { deleted: false, reason: 'not-found' };
@@ -703,7 +704,8 @@ async function safeDelete(filePath, options = {}) {
703
704
  force,
704
705
  acceptChanges,
705
706
  owner,
706
- actualOwner
707
+ actualOwner,
708
+ signatures
707
709
  });
708
710
  if (!integrity.valid) {
709
711
  return { deleted: false, reason: integrity.reason, message: integrity.message };
@@ -745,7 +747,8 @@ async function isSafeToDeleteDir(dirPath, stateFiles = {}, options = {}) {
745
747
  const fileState = stateFiles[normalizedPath];
746
748
  const integrity = await verifyFileIntegrity(filePath, fileState?.hash, {
747
749
  ...options,
748
- actualOwner: fileState?.owner
750
+ actualOwner: fileState?.owner,
751
+ signatures: options.signatures || []
749
752
  });
750
753
  return integrity.valid;
751
754
  })
@@ -841,7 +844,8 @@ async function safeMove(fromPath, toPath, options = {}) {
841
844
  acceptChanges,
842
845
  normalization,
843
846
  owner,
844
- actualOwner
847
+ actualOwner,
848
+ signatures: options.signatures || []
845
849
  });
846
850
  if (!integrity.valid) {
847
851
  throw new Error(integrity.message);
@@ -2060,7 +2064,8 @@ async function addSectionCommand(route, featurePath, options) {
2060
2064
 
2061
2065
  if (routeFilePath) {
2062
2066
  if (existsSync(routeFilePath)) {
2063
- const isGenerated = await isTextorGenerated(routeFilePath);
2067
+ const configSignatures = Object.values(config.signatures || {});
2068
+ const isGenerated = await isTextorGenerated(routeFilePath, configSignatures);
2064
2069
  if (!isGenerated && !options.force) {
2065
2070
  throw new Error(`File already exists: ${routeFilePath}\nUse --force to overwrite.`);
2066
2071
  }
@@ -2526,6 +2531,7 @@ async function removeSectionCommand(route, featurePath, options) {
2526
2531
 
2527
2532
  const pagesRoot = resolvePath(config, 'pages');
2528
2533
  const featuresRoot = resolvePath(config, 'features');
2534
+ const configSignatures = Object.values(config.signatures || {});
2529
2535
 
2530
2536
  // Find route file in state if possible
2531
2537
  let routeFilePath = null;
@@ -2575,7 +2581,8 @@ async function removeSectionCommand(route, featurePath, options) {
2575
2581
  acceptChanges: options.acceptChanges,
2576
2582
  normalization: config.hashing?.normalization,
2577
2583
  owner: normalizedRoute,
2578
- actualOwner: fileState?.owner
2584
+ actualOwner: fileState?.owner,
2585
+ signatures: configSignatures
2579
2586
  });
2580
2587
 
2581
2588
  if (result.deleted) {
@@ -2592,7 +2599,8 @@ async function removeSectionCommand(route, featurePath, options) {
2592
2599
  stateFiles: state.files,
2593
2600
  acceptChanges: options.acceptChanges,
2594
2601
  normalization: config.hashing?.normalization,
2595
- owner: normalizedRoute
2602
+ owner: normalizedRoute,
2603
+ signatures: configSignatures
2596
2604
  });
2597
2605
 
2598
2606
  if (result.deleted) {
@@ -2819,6 +2827,7 @@ async function moveSectionCommand(fromRoute, fromFeature, toRoute, toFeature, op
2819
2827
 
2820
2828
  const pagesRoot = resolvePath(config, 'pages');
2821
2829
  const featuresRoot = resolvePath(config, 'features');
2830
+ const configSignatures = Object.values(config.signatures || {});
2822
2831
 
2823
2832
  const fromSection = findSection(state, actualFromRoute);
2824
2833
  const routeExtension = (fromSection && fromSection.extension) || config.naming.routeExtension;
@@ -2860,7 +2869,8 @@ async function moveSectionCommand(fromRoute, fromFeature, toRoute, toFeature, op
2860
2869
  expectedHash: routeFileState?.hash,
2861
2870
  acceptChanges: options.acceptChanges,
2862
2871
  owner: normalizedFromRoute,
2863
- actualOwner: routeFileState?.owner
2872
+ actualOwner: routeFileState?.owner,
2873
+ signatures: configSignatures
2864
2874
  });
2865
2875
  movedFiles.push({ from: fromRoutePath, to: toRoutePath });
2866
2876
 
@@ -2957,7 +2967,8 @@ async function moveSectionCommand(fromRoute, fromFeature, toRoute, toFeature, op
2957
2967
  ...options,
2958
2968
  fromName: fromFeatureComponentName,
2959
2969
  toName: toFeatureComponentName,
2960
- owner: normalizedFromRoute
2970
+ owner: normalizedFromRoute,
2971
+ signatures: configSignatures
2961
2972
  });
2962
2973
  movedFiles.push({ from: fromFeaturePath, to: toFeaturePath });
2963
2974
 
@@ -3666,6 +3677,7 @@ async function createComponentCommand(componentName, options) {
3666
3677
  async function removeComponentCommand(identifier, options) {
3667
3678
  try {
3668
3679
  const config = await loadConfig();
3680
+ const configSignatures = Object.values(config.signatures || {});
3669
3681
 
3670
3682
  if (config.git?.requireCleanRepo && !await isRepoClean()) {
3671
3683
  throw new Error('Git repository is not clean. Please commit or stash your changes before proceeding.');
@@ -3695,7 +3707,8 @@ async function removeComponentCommand(identifier, options) {
3695
3707
  stateFiles: state.files,
3696
3708
  acceptChanges: options.acceptChanges,
3697
3709
  normalization: config.hashing?.normalization,
3698
- owner: identifier
3710
+ owner: identifier,
3711
+ signatures: configSignatures
3699
3712
  });
3700
3713
 
3701
3714
  if (result.deleted || (result.reason === 'not-found' && component)) {
@@ -3744,7 +3757,8 @@ async function listSectionsCommand() {
3744
3757
  console.log(' No pages directory found.');
3745
3758
  } else {
3746
3759
  const extensions = [config.naming.routeExtension, '.ts', '.js'];
3747
- const sections = await findGeneratedFiles(pagesRoot, extensions);
3760
+ const signatures = Object.values(config.signatures || {});
3761
+ const sections = await findGeneratedFiles(pagesRoot, extensions, signatures);
3748
3762
 
3749
3763
  if (sections.length === 0) {
3750
3764
  console.log(' No Textor-managed sections found.');
@@ -3848,7 +3862,7 @@ async function listSectionsCommand() {
3848
3862
  }
3849
3863
  }
3850
3864
 
3851
- async function findGeneratedFiles(dir, extensions) {
3865
+ async function findGeneratedFiles(dir, extensions, signatures) {
3852
3866
  const results = [];
3853
3867
  const entries = await readdir(dir);
3854
3868
  const exts = Array.isArray(extensions) ? extensions : [extensions];
@@ -3858,9 +3872,9 @@ async function findGeneratedFiles(dir, extensions) {
3858
3872
  const stats = await stat(fullPath);
3859
3873
 
3860
3874
  if (stats.isDirectory()) {
3861
- results.push(...await findGeneratedFiles(fullPath, exts));
3875
+ results.push(...await findGeneratedFiles(fullPath, exts, signatures));
3862
3876
  } else if (exts.some(ext => entry.endsWith(ext))) {
3863
- if (await isTextorGenerated(fullPath)) {
3877
+ if (await isTextorGenerated(fullPath, signatures)) {
3864
3878
  results.push(fullPath);
3865
3879
  }
3866
3880
  }
@@ -3918,11 +3932,12 @@ async function validateStateCommand(options) {
3918
3932
 
3919
3933
  if (options.fix) {
3920
3934
  let fixedCount = 0;
3935
+ const signatures = Object.values(config.signatures || {});
3921
3936
 
3922
3937
  // Fix modified files if they still have the Textor signature
3923
3938
  for (const mod of results.modified) {
3924
3939
  const fullPath = path.join(process.cwd(), mod.path);
3925
- if (await isTextorGenerated(fullPath)) {
3940
+ if (await isTextorGenerated(fullPath, signatures)) {
3926
3941
  state.files[mod.path].hash = mod.newHash;
3927
3942
  fixedCount++;
3928
3943
  }
@@ -1 +1 @@
1
- {"version":3,"file":"textor.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"textor.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/dist/index.cjs CHANGED
@@ -578,7 +578,7 @@ async function isTextorGenerated(filePath, customSignatures = []) {
578
578
  }
579
579
  }
580
580
  async function verifyFileIntegrity(filePath, expectedHash, options = {}) {
581
- const { force = false, acceptChanges = false, normalization = 'normalizeEOL', owner = null, actualOwner = null } = options;
581
+ const { force = false, acceptChanges = false, normalization = 'normalizeEOL', owner = null, actualOwner = null, signatures = [] } = options;
582
582
  if (force)
583
583
  return { valid: true };
584
584
  if (owner && actualOwner && owner !== actualOwner) {
@@ -588,7 +588,7 @@ async function verifyFileIntegrity(filePath, expectedHash, options = {}) {
588
588
  message: `Refusing to operate on ${filePath} - owned by ${actualOwner}, but requested by ${owner}. Use --force to override.`
589
589
  };
590
590
  }
591
- const isGenerated = await isTextorGenerated(filePath);
591
+ const isGenerated = await isTextorGenerated(filePath, signatures);
592
592
  if (!isGenerated) {
593
593
  return {
594
594
  valid: false,
@@ -617,7 +617,7 @@ async function verifyFileIntegrity(filePath, expectedHash, options = {}) {
617
617
  return { valid: true };
618
618
  }
619
619
  async function safeDelete(filePath, options = {}) {
620
- const { force = false, expectedHash = null, acceptChanges = false, owner = null, actualOwner = null } = options;
620
+ const { force = false, expectedHash = null, acceptChanges = false, owner = null, actualOwner = null, signatures = [] } = options;
621
621
  if (!fs.existsSync(filePath)) {
622
622
  return { deleted: false, reason: 'not-found' };
623
623
  }
@@ -625,7 +625,8 @@ async function safeDelete(filePath, options = {}) {
625
625
  force,
626
626
  acceptChanges,
627
627
  owner,
628
- actualOwner
628
+ actualOwner,
629
+ signatures
629
630
  });
630
631
  if (!integrity.valid) {
631
632
  return { deleted: false, reason: integrity.reason, message: integrity.message };
@@ -657,7 +658,8 @@ async function isSafeToDeleteDir(dirPath, stateFiles = {}, options = {}) {
657
658
  const fileState = stateFiles[normalizedPath];
658
659
  const integrity = await verifyFileIntegrity(filePath, fileState?.hash, {
659
660
  ...options,
660
- actualOwner: fileState?.owner
661
+ actualOwner: fileState?.owner,
662
+ signatures: options.signatures || []
661
663
  });
662
664
  return integrity.valid;
663
665
  }));
@@ -722,7 +724,8 @@ async function safeMove(fromPath, toPath, options = {}) {
722
724
  acceptChanges,
723
725
  normalization,
724
726
  owner,
725
- actualOwner
727
+ actualOwner,
728
+ signatures: options.signatures || []
726
729
  });
727
730
  if (!integrity.valid) {
728
731
  throw new Error(integrity.message);
@@ -1774,7 +1777,8 @@ async function addSectionCommand(route, featurePath, options) {
1774
1777
  }
1775
1778
  if (routeFilePath) {
1776
1779
  if (fs.existsSync(routeFilePath)) {
1777
- const isGenerated = await isTextorGenerated(routeFilePath);
1780
+ const configSignatures = Object.values(config.signatures || {});
1781
+ const isGenerated = await isTextorGenerated(routeFilePath, configSignatures);
1778
1782
  if (!isGenerated && !options.force) {
1779
1783
  throw new Error(`File already exists: ${routeFilePath}\nUse --force to overwrite.`);
1780
1784
  }
@@ -2154,6 +2158,7 @@ async function removeSectionCommand(route, featurePath, options) {
2154
2158
  const normalizedFeaturePath = featureToDirectoryPath(targetFeaturePath);
2155
2159
  const pagesRoot = resolvePath(config, 'pages');
2156
2160
  const featuresRoot = resolvePath(config, 'features');
2161
+ const configSignatures = Object.values(config.signatures || {});
2157
2162
  // Find route file in state if possible
2158
2163
  let routeFilePath = null;
2159
2164
  const routeRelPath = Object.keys(state.files).find(f => {
@@ -2195,7 +2200,8 @@ async function removeSectionCommand(route, featurePath, options) {
2195
2200
  acceptChanges: options.acceptChanges,
2196
2201
  normalization: config.hashing?.normalization,
2197
2202
  owner: normalizedRoute,
2198
- actualOwner: fileState?.owner
2203
+ actualOwner: fileState?.owner,
2204
+ signatures: configSignatures
2199
2205
  });
2200
2206
  if (result.deleted) {
2201
2207
  deletedFiles.push(routeFilePath);
@@ -2211,7 +2217,8 @@ async function removeSectionCommand(route, featurePath, options) {
2211
2217
  stateFiles: state.files,
2212
2218
  acceptChanges: options.acceptChanges,
2213
2219
  normalization: config.hashing?.normalization,
2214
- owner: normalizedRoute
2220
+ owner: normalizedRoute,
2221
+ signatures: configSignatures
2215
2222
  });
2216
2223
  if (result.deleted) {
2217
2224
  deletedDirs.push(featureDirPath);
@@ -2407,6 +2414,7 @@ async function moveSectionCommand(fromRoute, fromFeature, toRoute, toFeature, op
2407
2414
  const normalizedToFeature = actualToFeature ? featureToDirectoryPath(actualToFeature) : null;
2408
2415
  const pagesRoot = resolvePath(config, 'pages');
2409
2416
  const featuresRoot = resolvePath(config, 'features');
2417
+ const configSignatures = Object.values(config.signatures || {});
2410
2418
  const fromSection = findSection(state, actualFromRoute);
2411
2419
  const routeExtension = (fromSection && fromSection.extension) || config.naming.routeExtension;
2412
2420
  const fromRouteFile = routeToFilePath(normalizedFromRoute, {
@@ -2439,7 +2447,8 @@ async function moveSectionCommand(fromRoute, fromFeature, toRoute, toFeature, op
2439
2447
  expectedHash: routeFileState?.hash,
2440
2448
  acceptChanges: options.acceptChanges,
2441
2449
  owner: normalizedFromRoute,
2442
- actualOwner: routeFileState?.owner
2450
+ actualOwner: routeFileState?.owner,
2451
+ signatures: configSignatures
2443
2452
  });
2444
2453
  movedFiles.push({ from: fromRoutePath, to: toRoutePath });
2445
2454
  // Update state for moved route file
@@ -2518,7 +2527,8 @@ async function moveSectionCommand(fromRoute, fromFeature, toRoute, toFeature, op
2518
2527
  ...options,
2519
2528
  fromName: fromFeatureComponentName,
2520
2529
  toName: toFeatureComponentName,
2521
- owner: normalizedFromRoute
2530
+ owner: normalizedFromRoute,
2531
+ signatures: configSignatures
2522
2532
  });
2523
2533
  movedFiles.push({ from: fromFeaturePath, to: toFeaturePath });
2524
2534
  await cleanupEmptyDirs(path.dirname(fromFeaturePath), featuresRoot);
@@ -3047,6 +3057,7 @@ async function createComponentCommand(componentName, options) {
3047
3057
  async function removeComponentCommand(identifier, options) {
3048
3058
  try {
3049
3059
  const config = await loadConfig();
3060
+ const configSignatures = Object.values(config.signatures || {});
3050
3061
  if (config.git?.requireCleanRepo && !await isRepoClean()) {
3051
3062
  throw new Error('Git repository is not clean. Please commit or stash your changes before proceeding.');
3052
3063
  }
@@ -3071,7 +3082,8 @@ async function removeComponentCommand(identifier, options) {
3071
3082
  stateFiles: state.files,
3072
3083
  acceptChanges: options.acceptChanges,
3073
3084
  normalization: config.hashing?.normalization,
3074
- owner: identifier
3085
+ owner: identifier,
3086
+ signatures: configSignatures
3075
3087
  });
3076
3088
  if (result.deleted || (result.reason === 'not-found' && component)) {
3077
3089
  if (result.deleted) {
@@ -3120,7 +3132,8 @@ async function listSectionsCommand() {
3120
3132
  }
3121
3133
  else {
3122
3134
  const extensions = [config.naming.routeExtension, '.ts', '.js'];
3123
- const sections = await findGeneratedFiles(pagesRoot, extensions);
3135
+ const signatures = Object.values(config.signatures || {});
3136
+ const sections = await findGeneratedFiles(pagesRoot, extensions, signatures);
3124
3137
  if (sections.length === 0) {
3125
3138
  console.log(' No Textor-managed sections found.');
3126
3139
  }
@@ -3215,7 +3228,7 @@ async function listSectionsCommand() {
3215
3228
  process.exit(1);
3216
3229
  }
3217
3230
  }
3218
- async function findGeneratedFiles(dir, extensions) {
3231
+ async function findGeneratedFiles(dir, extensions, signatures) {
3219
3232
  const results = [];
3220
3233
  const entries = await promises.readdir(dir);
3221
3234
  const exts = Array.isArray(extensions) ? extensions : [extensions];
@@ -3223,10 +3236,10 @@ async function findGeneratedFiles(dir, extensions) {
3223
3236
  const fullPath = path.join(dir, entry);
3224
3237
  const stats = await promises.stat(fullPath);
3225
3238
  if (stats.isDirectory()) {
3226
- results.push(...await findGeneratedFiles(fullPath, exts));
3239
+ results.push(...await findGeneratedFiles(fullPath, exts, signatures));
3227
3240
  }
3228
3241
  else if (exts.some(ext => entry.endsWith(ext))) {
3229
- if (await isTextorGenerated(fullPath)) {
3242
+ if (await isTextorGenerated(fullPath, signatures)) {
3230
3243
  results.push(fullPath);
3231
3244
  }
3232
3245
  }
@@ -3275,10 +3288,11 @@ async function validateStateCommand(options) {
3275
3288
  }
3276
3289
  if (options.fix) {
3277
3290
  let fixedCount = 0;
3291
+ const signatures = Object.values(config.signatures || {});
3278
3292
  // Fix modified files if they still have the Textor signature
3279
3293
  for (const mod of results.modified) {
3280
3294
  const fullPath = path.join(process.cwd(), mod.path);
3281
- if (await isTextorGenerated(fullPath)) {
3295
+ if (await isTextorGenerated(fullPath, signatures)) {
3282
3296
  state.files[mod.path].hash = mod.newHash;
3283
3297
  fixedCount++;
3284
3298
  }