@oamm/textor 1.0.3 → 1.0.4
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/README.md +10 -0
- package/dist/bin/textor.js +73 -7
- package/dist/bin/textor.js.map +1 -1
- package/dist/index.cjs +73 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +73 -8
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -269,6 +269,16 @@ pnpm textor upgrade-config
|
|
|
269
269
|
**Options:**
|
|
270
270
|
- `--dry-run`: Print the upgraded config without writing it.
|
|
271
271
|
|
|
272
|
+
### normalize-state
|
|
273
|
+
Normalize `.textor/state.json` to use project-relative paths (helpful when moving between machines).
|
|
274
|
+
|
|
275
|
+
```bash
|
|
276
|
+
pnpm textor normalize-state
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
**Options:**
|
|
280
|
+
- `--dry-run`: Print the normalized state without writing it.
|
|
281
|
+
|
|
272
282
|
## 🏗️ Technical Architecture
|
|
273
283
|
|
|
274
284
|
Textor is designed with enterprise-grade robustness, moving beyond simple scaffolding to provide a reliable refactoring engine.
|
package/dist/bin/textor.js
CHANGED
|
@@ -1458,6 +1458,7 @@ async function loadState() {
|
|
|
1458
1458
|
const content = await readFile(statePath, 'utf-8');
|
|
1459
1459
|
const state = JSON.parse(content);
|
|
1460
1460
|
if (!state.files) state.files = {};
|
|
1461
|
+
normalizeStatePaths(state);
|
|
1461
1462
|
return state;
|
|
1462
1463
|
} catch (error) {
|
|
1463
1464
|
return { sections: [], components: [], files: {} };
|
|
@@ -1507,24 +1508,62 @@ async function registerFile(filePath, { kind, template, hash, templateVersion =
|
|
|
1507
1508
|
|
|
1508
1509
|
async function addSectionToState(section) {
|
|
1509
1510
|
const state = await loadState();
|
|
1511
|
+
const normalizedSection = { ...section };
|
|
1512
|
+
if (normalizedSection.featurePath) {
|
|
1513
|
+
normalizedSection.featurePath = normalizeStatePath(normalizedSection.featurePath);
|
|
1514
|
+
}
|
|
1510
1515
|
// Avoid duplicates by route OR by featurePath if route is null
|
|
1511
|
-
if (
|
|
1512
|
-
state.sections = state.sections.filter(s => s.route !==
|
|
1516
|
+
if (normalizedSection.route) {
|
|
1517
|
+
state.sections = state.sections.filter(s => s.route !== normalizedSection.route);
|
|
1513
1518
|
} else {
|
|
1514
|
-
state.sections = state.sections.filter(s => s.featurePath !==
|
|
1519
|
+
state.sections = state.sections.filter(s => s.featurePath !== normalizedSection.featurePath || s.route);
|
|
1515
1520
|
}
|
|
1516
|
-
state.sections.push(
|
|
1521
|
+
state.sections.push(normalizedSection);
|
|
1517
1522
|
await saveState(state);
|
|
1518
1523
|
}
|
|
1519
1524
|
|
|
1520
1525
|
async function addComponentToState(component) {
|
|
1521
1526
|
const state = await loadState();
|
|
1527
|
+
const normalizedComponent = { ...component };
|
|
1528
|
+
if (normalizedComponent.path) {
|
|
1529
|
+
normalizedComponent.path = normalizeStatePath(normalizedComponent.path);
|
|
1530
|
+
}
|
|
1522
1531
|
// Avoid duplicates by name
|
|
1523
|
-
state.components = state.components.filter(c => c.name !==
|
|
1524
|
-
state.components.push(
|
|
1532
|
+
state.components = state.components.filter(c => c.name !== normalizedComponent.name);
|
|
1533
|
+
state.components.push(normalizedComponent);
|
|
1525
1534
|
await saveState(state);
|
|
1526
1535
|
}
|
|
1527
1536
|
|
|
1537
|
+
function normalizeStatePath(filePath) {
|
|
1538
|
+
if (!filePath || typeof filePath !== 'string') return filePath;
|
|
1539
|
+
const relative = path.isAbsolute(filePath)
|
|
1540
|
+
? path.relative(process.cwd(), filePath)
|
|
1541
|
+
: filePath;
|
|
1542
|
+
return relative.replace(/\\/g, '/');
|
|
1543
|
+
}
|
|
1544
|
+
|
|
1545
|
+
function normalizeStatePaths(state) {
|
|
1546
|
+
if (!state || typeof state !== 'object') return;
|
|
1547
|
+
if (Array.isArray(state.sections)) {
|
|
1548
|
+
state.sections = state.sections.map(section => {
|
|
1549
|
+
if (!section || typeof section !== 'object') return section;
|
|
1550
|
+
if (!section.featurePath) return section;
|
|
1551
|
+
const normalized = normalizeStatePath(section.featurePath);
|
|
1552
|
+
if (normalized === section.featurePath) return section;
|
|
1553
|
+
return { ...section, featurePath: normalized };
|
|
1554
|
+
});
|
|
1555
|
+
}
|
|
1556
|
+
if (Array.isArray(state.components)) {
|
|
1557
|
+
state.components = state.components.map(component => {
|
|
1558
|
+
if (!component || typeof component !== 'object') return component;
|
|
1559
|
+
if (!component.path) return component;
|
|
1560
|
+
const normalized = normalizeStatePath(component.path);
|
|
1561
|
+
if (normalized === component.path) return component;
|
|
1562
|
+
return { ...component, path: normalized };
|
|
1563
|
+
});
|
|
1564
|
+
}
|
|
1565
|
+
}
|
|
1566
|
+
|
|
1528
1567
|
function findSection(state, identifier) {
|
|
1529
1568
|
return state.sections.find(s => s.route === identifier || s.name === identifier || s.featurePath === identifier);
|
|
1530
1569
|
}
|
|
@@ -3298,7 +3337,7 @@ async function removeComponentCommand(identifier, options) {
|
|
|
3298
3337
|
let componentDir;
|
|
3299
3338
|
|
|
3300
3339
|
if (component) {
|
|
3301
|
-
componentDir = component.path;
|
|
3340
|
+
componentDir = path.resolve(process.cwd(), component.path);
|
|
3302
3341
|
} else {
|
|
3303
3342
|
// Fallback: try to guess path if not in state
|
|
3304
3343
|
const componentsRoot = path.resolve(process.cwd(), config.paths.components);
|
|
@@ -4032,6 +4071,27 @@ async function upgradeConfigCommand(options) {
|
|
|
4032
4071
|
}
|
|
4033
4072
|
}
|
|
4034
4073
|
|
|
4074
|
+
async function normalizeStateCommand(options) {
|
|
4075
|
+
try {
|
|
4076
|
+
const state = await loadState();
|
|
4077
|
+
|
|
4078
|
+
if (options.dryRun) {
|
|
4079
|
+
console.log('Dry run - normalized state:');
|
|
4080
|
+
console.log(JSON.stringify(state, null, 2));
|
|
4081
|
+
return;
|
|
4082
|
+
}
|
|
4083
|
+
|
|
4084
|
+
await saveState(state);
|
|
4085
|
+
console.log('State normalized successfully.');
|
|
4086
|
+
} catch (error) {
|
|
4087
|
+
console.error('Error:', error.message);
|
|
4088
|
+
if (typeof process.exit === 'function' && process.env.NODE_ENV !== 'test') {
|
|
4089
|
+
process.exit(1);
|
|
4090
|
+
}
|
|
4091
|
+
throw error;
|
|
4092
|
+
}
|
|
4093
|
+
}
|
|
4094
|
+
|
|
4035
4095
|
const program = new Command();
|
|
4036
4096
|
|
|
4037
4097
|
program
|
|
@@ -4157,5 +4217,11 @@ program
|
|
|
4157
4217
|
.option('--dry-run', 'Show the upgraded config without writing to disk')
|
|
4158
4218
|
.action(upgradeConfigCommand);
|
|
4159
4219
|
|
|
4220
|
+
program
|
|
4221
|
+
.command('normalize-state')
|
|
4222
|
+
.description('Normalize state paths to be project-relative')
|
|
4223
|
+
.option('--dry-run', 'Show the normalized state without writing to disk')
|
|
4224
|
+
.action(normalizeStateCommand);
|
|
4225
|
+
|
|
4160
4226
|
program.parse();
|
|
4161
4227
|
//# sourceMappingURL=textor.js.map
|
package/dist/bin/textor.js.map
CHANGED
|
@@ -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
|
@@ -1291,6 +1291,7 @@ async function loadState() {
|
|
|
1291
1291
|
const state = JSON.parse(content);
|
|
1292
1292
|
if (!state.files)
|
|
1293
1293
|
state.files = {};
|
|
1294
|
+
normalizeStatePaths(state);
|
|
1294
1295
|
return state;
|
|
1295
1296
|
}
|
|
1296
1297
|
catch (error) {
|
|
@@ -1331,23 +1332,67 @@ async function registerFile(filePath, { kind, template, hash, templateVersion =
|
|
|
1331
1332
|
}
|
|
1332
1333
|
async function addSectionToState(section) {
|
|
1333
1334
|
const state = await loadState();
|
|
1335
|
+
const normalizedSection = { ...section };
|
|
1336
|
+
if (normalizedSection.featurePath) {
|
|
1337
|
+
normalizedSection.featurePath = normalizeStatePath(normalizedSection.featurePath);
|
|
1338
|
+
}
|
|
1334
1339
|
// Avoid duplicates by route OR by featurePath if route is null
|
|
1335
|
-
if (
|
|
1336
|
-
state.sections = state.sections.filter(s => s.route !==
|
|
1340
|
+
if (normalizedSection.route) {
|
|
1341
|
+
state.sections = state.sections.filter(s => s.route !== normalizedSection.route);
|
|
1337
1342
|
}
|
|
1338
1343
|
else {
|
|
1339
|
-
state.sections = state.sections.filter(s => s.featurePath !==
|
|
1344
|
+
state.sections = state.sections.filter(s => s.featurePath !== normalizedSection.featurePath || s.route);
|
|
1340
1345
|
}
|
|
1341
|
-
state.sections.push(
|
|
1346
|
+
state.sections.push(normalizedSection);
|
|
1342
1347
|
await saveState(state);
|
|
1343
1348
|
}
|
|
1344
1349
|
async function addComponentToState(component) {
|
|
1345
1350
|
const state = await loadState();
|
|
1351
|
+
const normalizedComponent = { ...component };
|
|
1352
|
+
if (normalizedComponent.path) {
|
|
1353
|
+
normalizedComponent.path = normalizeStatePath(normalizedComponent.path);
|
|
1354
|
+
}
|
|
1346
1355
|
// Avoid duplicates by name
|
|
1347
|
-
state.components = state.components.filter(c => c.name !==
|
|
1348
|
-
state.components.push(
|
|
1356
|
+
state.components = state.components.filter(c => c.name !== normalizedComponent.name);
|
|
1357
|
+
state.components.push(normalizedComponent);
|
|
1349
1358
|
await saveState(state);
|
|
1350
1359
|
}
|
|
1360
|
+
function normalizeStatePath(filePath) {
|
|
1361
|
+
if (!filePath || typeof filePath !== 'string')
|
|
1362
|
+
return filePath;
|
|
1363
|
+
const relative = path.isAbsolute(filePath)
|
|
1364
|
+
? path.relative(process.cwd(), filePath)
|
|
1365
|
+
: filePath;
|
|
1366
|
+
return relative.replace(/\\/g, '/');
|
|
1367
|
+
}
|
|
1368
|
+
function normalizeStatePaths(state) {
|
|
1369
|
+
if (!state || typeof state !== 'object')
|
|
1370
|
+
return;
|
|
1371
|
+
if (Array.isArray(state.sections)) {
|
|
1372
|
+
state.sections = state.sections.map(section => {
|
|
1373
|
+
if (!section || typeof section !== 'object')
|
|
1374
|
+
return section;
|
|
1375
|
+
if (!section.featurePath)
|
|
1376
|
+
return section;
|
|
1377
|
+
const normalized = normalizeStatePath(section.featurePath);
|
|
1378
|
+
if (normalized === section.featurePath)
|
|
1379
|
+
return section;
|
|
1380
|
+
return { ...section, featurePath: normalized };
|
|
1381
|
+
});
|
|
1382
|
+
}
|
|
1383
|
+
if (Array.isArray(state.components)) {
|
|
1384
|
+
state.components = state.components.map(component => {
|
|
1385
|
+
if (!component || typeof component !== 'object')
|
|
1386
|
+
return component;
|
|
1387
|
+
if (!component.path)
|
|
1388
|
+
return component;
|
|
1389
|
+
const normalized = normalizeStatePath(component.path);
|
|
1390
|
+
if (normalized === component.path)
|
|
1391
|
+
return component;
|
|
1392
|
+
return { ...component, path: normalized };
|
|
1393
|
+
});
|
|
1394
|
+
}
|
|
1395
|
+
}
|
|
1351
1396
|
function findSection(state, identifier) {
|
|
1352
1397
|
return state.sections.find(s => s.route === identifier || s.name === identifier || s.featurePath === identifier);
|
|
1353
1398
|
}
|
|
@@ -2712,7 +2757,7 @@ async function removeComponentCommand(identifier, options) {
|
|
|
2712
2757
|
const component = findComponent(state, identifier);
|
|
2713
2758
|
let componentDir;
|
|
2714
2759
|
if (component) {
|
|
2715
|
-
componentDir = component.path;
|
|
2760
|
+
componentDir = path.resolve(process.cwd(), component.path);
|
|
2716
2761
|
}
|
|
2717
2762
|
else {
|
|
2718
2763
|
// Fallback: try to guess path if not in state
|
|
@@ -3376,12 +3421,33 @@ async function upgradeConfigCommand(options) {
|
|
|
3376
3421
|
}
|
|
3377
3422
|
}
|
|
3378
3423
|
|
|
3424
|
+
async function normalizeStateCommand(options) {
|
|
3425
|
+
try {
|
|
3426
|
+
const state = await loadState();
|
|
3427
|
+
if (options.dryRun) {
|
|
3428
|
+
console.log('Dry run - normalized state:');
|
|
3429
|
+
console.log(JSON.stringify(state, null, 2));
|
|
3430
|
+
return;
|
|
3431
|
+
}
|
|
3432
|
+
await saveState(state);
|
|
3433
|
+
console.log('State normalized successfully.');
|
|
3434
|
+
}
|
|
3435
|
+
catch (error) {
|
|
3436
|
+
console.error('Error:', error.message);
|
|
3437
|
+
if (typeof process.exit === 'function' && process.env.NODE_ENV !== 'test') {
|
|
3438
|
+
process.exit(1);
|
|
3439
|
+
}
|
|
3440
|
+
throw error;
|
|
3441
|
+
}
|
|
3442
|
+
}
|
|
3443
|
+
|
|
3379
3444
|
exports.addSectionCommand = addSectionCommand;
|
|
3380
3445
|
exports.adoptCommand = adoptCommand;
|
|
3381
3446
|
exports.createComponentCommand = createComponentCommand;
|
|
3382
3447
|
exports.initCommand = initCommand;
|
|
3383
3448
|
exports.listSectionsCommand = listSectionsCommand;
|
|
3384
3449
|
exports.moveSectionCommand = moveSectionCommand;
|
|
3450
|
+
exports.normalizeStateCommand = normalizeStateCommand;
|
|
3385
3451
|
exports.removeComponentCommand = removeComponentCommand;
|
|
3386
3452
|
exports.removeSectionCommand = removeSectionCommand;
|
|
3387
3453
|
exports.statusCommand = statusCommand;
|