@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.
package/dist/index.js CHANGED
@@ -576,7 +576,7 @@ async function isTextorGenerated(filePath, customSignatures = []) {
576
576
  }
577
577
  }
578
578
  async function verifyFileIntegrity(filePath, expectedHash, options = {}) {
579
- const { force = false, acceptChanges = false, normalization = 'normalizeEOL', owner = null, actualOwner = null } = options;
579
+ const { force = false, acceptChanges = false, normalization = 'normalizeEOL', owner = null, actualOwner = null, signatures = [] } = options;
580
580
  if (force)
581
581
  return { valid: true };
582
582
  if (owner && actualOwner && owner !== actualOwner) {
@@ -586,7 +586,7 @@ async function verifyFileIntegrity(filePath, expectedHash, options = {}) {
586
586
  message: `Refusing to operate on ${filePath} - owned by ${actualOwner}, but requested by ${owner}. Use --force to override.`
587
587
  };
588
588
  }
589
- const isGenerated = await isTextorGenerated(filePath);
589
+ const isGenerated = await isTextorGenerated(filePath, signatures);
590
590
  if (!isGenerated) {
591
591
  return {
592
592
  valid: false,
@@ -615,7 +615,7 @@ async function verifyFileIntegrity(filePath, expectedHash, options = {}) {
615
615
  return { valid: true };
616
616
  }
617
617
  async function safeDelete(filePath, options = {}) {
618
- const { force = false, expectedHash = null, acceptChanges = false, owner = null, actualOwner = null } = options;
618
+ const { force = false, expectedHash = null, acceptChanges = false, owner = null, actualOwner = null, signatures = [] } = options;
619
619
  if (!existsSync(filePath)) {
620
620
  return { deleted: false, reason: 'not-found' };
621
621
  }
@@ -623,7 +623,8 @@ async function safeDelete(filePath, options = {}) {
623
623
  force,
624
624
  acceptChanges,
625
625
  owner,
626
- actualOwner
626
+ actualOwner,
627
+ signatures
627
628
  });
628
629
  if (!integrity.valid) {
629
630
  return { deleted: false, reason: integrity.reason, message: integrity.message };
@@ -655,7 +656,8 @@ async function isSafeToDeleteDir(dirPath, stateFiles = {}, options = {}) {
655
656
  const fileState = stateFiles[normalizedPath];
656
657
  const integrity = await verifyFileIntegrity(filePath, fileState?.hash, {
657
658
  ...options,
658
- actualOwner: fileState?.owner
659
+ actualOwner: fileState?.owner,
660
+ signatures: options.signatures || []
659
661
  });
660
662
  return integrity.valid;
661
663
  }));
@@ -720,7 +722,8 @@ async function safeMove(fromPath, toPath, options = {}) {
720
722
  acceptChanges,
721
723
  normalization,
722
724
  owner,
723
- actualOwner
725
+ actualOwner,
726
+ signatures: options.signatures || []
724
727
  });
725
728
  if (!integrity.valid) {
726
729
  throw new Error(integrity.message);
@@ -1772,7 +1775,8 @@ async function addSectionCommand(route, featurePath, options) {
1772
1775
  }
1773
1776
  if (routeFilePath) {
1774
1777
  if (existsSync(routeFilePath)) {
1775
- const isGenerated = await isTextorGenerated(routeFilePath);
1778
+ const configSignatures = Object.values(config.signatures || {});
1779
+ const isGenerated = await isTextorGenerated(routeFilePath, configSignatures);
1776
1780
  if (!isGenerated && !options.force) {
1777
1781
  throw new Error(`File already exists: ${routeFilePath}\nUse --force to overwrite.`);
1778
1782
  }
@@ -2152,6 +2156,7 @@ async function removeSectionCommand(route, featurePath, options) {
2152
2156
  const normalizedFeaturePath = featureToDirectoryPath(targetFeaturePath);
2153
2157
  const pagesRoot = resolvePath(config, 'pages');
2154
2158
  const featuresRoot = resolvePath(config, 'features');
2159
+ const configSignatures = Object.values(config.signatures || {});
2155
2160
  // Find route file in state if possible
2156
2161
  let routeFilePath = null;
2157
2162
  const routeRelPath = Object.keys(state.files).find(f => {
@@ -2193,7 +2198,8 @@ async function removeSectionCommand(route, featurePath, options) {
2193
2198
  acceptChanges: options.acceptChanges,
2194
2199
  normalization: config.hashing?.normalization,
2195
2200
  owner: normalizedRoute,
2196
- actualOwner: fileState?.owner
2201
+ actualOwner: fileState?.owner,
2202
+ signatures: configSignatures
2197
2203
  });
2198
2204
  if (result.deleted) {
2199
2205
  deletedFiles.push(routeFilePath);
@@ -2209,7 +2215,8 @@ async function removeSectionCommand(route, featurePath, options) {
2209
2215
  stateFiles: state.files,
2210
2216
  acceptChanges: options.acceptChanges,
2211
2217
  normalization: config.hashing?.normalization,
2212
- owner: normalizedRoute
2218
+ owner: normalizedRoute,
2219
+ signatures: configSignatures
2213
2220
  });
2214
2221
  if (result.deleted) {
2215
2222
  deletedDirs.push(featureDirPath);
@@ -2405,6 +2412,7 @@ async function moveSectionCommand(fromRoute, fromFeature, toRoute, toFeature, op
2405
2412
  const normalizedToFeature = actualToFeature ? featureToDirectoryPath(actualToFeature) : null;
2406
2413
  const pagesRoot = resolvePath(config, 'pages');
2407
2414
  const featuresRoot = resolvePath(config, 'features');
2415
+ const configSignatures = Object.values(config.signatures || {});
2408
2416
  const fromSection = findSection(state, actualFromRoute);
2409
2417
  const routeExtension = (fromSection && fromSection.extension) || config.naming.routeExtension;
2410
2418
  const fromRouteFile = routeToFilePath(normalizedFromRoute, {
@@ -2437,7 +2445,8 @@ async function moveSectionCommand(fromRoute, fromFeature, toRoute, toFeature, op
2437
2445
  expectedHash: routeFileState?.hash,
2438
2446
  acceptChanges: options.acceptChanges,
2439
2447
  owner: normalizedFromRoute,
2440
- actualOwner: routeFileState?.owner
2448
+ actualOwner: routeFileState?.owner,
2449
+ signatures: configSignatures
2441
2450
  });
2442
2451
  movedFiles.push({ from: fromRoutePath, to: toRoutePath });
2443
2452
  // Update state for moved route file
@@ -2516,7 +2525,8 @@ async function moveSectionCommand(fromRoute, fromFeature, toRoute, toFeature, op
2516
2525
  ...options,
2517
2526
  fromName: fromFeatureComponentName,
2518
2527
  toName: toFeatureComponentName,
2519
- owner: normalizedFromRoute
2528
+ owner: normalizedFromRoute,
2529
+ signatures: configSignatures
2520
2530
  });
2521
2531
  movedFiles.push({ from: fromFeaturePath, to: toFeaturePath });
2522
2532
  await cleanupEmptyDirs(path.dirname(fromFeaturePath), featuresRoot);
@@ -3045,6 +3055,7 @@ async function createComponentCommand(componentName, options) {
3045
3055
  async function removeComponentCommand(identifier, options) {
3046
3056
  try {
3047
3057
  const config = await loadConfig();
3058
+ const configSignatures = Object.values(config.signatures || {});
3048
3059
  if (config.git?.requireCleanRepo && !await isRepoClean()) {
3049
3060
  throw new Error('Git repository is not clean. Please commit or stash your changes before proceeding.');
3050
3061
  }
@@ -3069,7 +3080,8 @@ async function removeComponentCommand(identifier, options) {
3069
3080
  stateFiles: state.files,
3070
3081
  acceptChanges: options.acceptChanges,
3071
3082
  normalization: config.hashing?.normalization,
3072
- owner: identifier
3083
+ owner: identifier,
3084
+ signatures: configSignatures
3073
3085
  });
3074
3086
  if (result.deleted || (result.reason === 'not-found' && component)) {
3075
3087
  if (result.deleted) {
@@ -3118,7 +3130,8 @@ async function listSectionsCommand() {
3118
3130
  }
3119
3131
  else {
3120
3132
  const extensions = [config.naming.routeExtension, '.ts', '.js'];
3121
- const sections = await findGeneratedFiles(pagesRoot, extensions);
3133
+ const signatures = Object.values(config.signatures || {});
3134
+ const sections = await findGeneratedFiles(pagesRoot, extensions, signatures);
3122
3135
  if (sections.length === 0) {
3123
3136
  console.log(' No Textor-managed sections found.');
3124
3137
  }
@@ -3213,7 +3226,7 @@ async function listSectionsCommand() {
3213
3226
  process.exit(1);
3214
3227
  }
3215
3228
  }
3216
- async function findGeneratedFiles(dir, extensions) {
3229
+ async function findGeneratedFiles(dir, extensions, signatures) {
3217
3230
  const results = [];
3218
3231
  const entries = await readdir(dir);
3219
3232
  const exts = Array.isArray(extensions) ? extensions : [extensions];
@@ -3221,10 +3234,10 @@ async function findGeneratedFiles(dir, extensions) {
3221
3234
  const fullPath = path.join(dir, entry);
3222
3235
  const stats = await stat(fullPath);
3223
3236
  if (stats.isDirectory()) {
3224
- results.push(...await findGeneratedFiles(fullPath, exts));
3237
+ results.push(...await findGeneratedFiles(fullPath, exts, signatures));
3225
3238
  }
3226
3239
  else if (exts.some(ext => entry.endsWith(ext))) {
3227
- if (await isTextorGenerated(fullPath)) {
3240
+ if (await isTextorGenerated(fullPath, signatures)) {
3228
3241
  results.push(fullPath);
3229
3242
  }
3230
3243
  }
@@ -3273,10 +3286,11 @@ async function validateStateCommand(options) {
3273
3286
  }
3274
3287
  if (options.fix) {
3275
3288
  let fixedCount = 0;
3289
+ const signatures = Object.values(config.signatures || {});
3276
3290
  // Fix modified files if they still have the Textor signature
3277
3291
  for (const mod of results.modified) {
3278
3292
  const fullPath = path.join(process.cwd(), mod.path);
3279
- if (await isTextorGenerated(fullPath)) {
3293
+ if (await isTextorGenerated(fullPath, signatures)) {
3280
3294
  state.files[mod.path].hash = mod.newHash;
3281
3295
  fixedCount++;
3282
3296
  }