@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/bin/textor.js +32 -17
- package/dist/bin/textor.js.map +1 -1
- package/dist/index.cjs +31 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +31 -17
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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
|
|
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
|
|
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
|
}
|