@oamm/textor 1.0.13 → 1.0.16
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 +27 -0
- package/dist/bin/textor.js +242 -109
- package/dist/bin/textor.js.map +1 -1
- package/dist/index.cjs +242 -107
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +11 -2
- package/dist/index.js +242 -108
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/dist/index.d.ts
CHANGED
|
@@ -31,7 +31,7 @@ declare function statusCommand(): Promise<void>;
|
|
|
31
31
|
|
|
32
32
|
declare function syncCommand(options: any): Promise<void>;
|
|
33
33
|
|
|
34
|
-
declare function adoptCommand(
|
|
34
|
+
declare function adoptCommand(kind: any, arg2: any, arg3: any, options: any): Promise<void>;
|
|
35
35
|
|
|
36
36
|
declare function upgradeConfigCommand(options: any): Promise<void>;
|
|
37
37
|
|
|
@@ -53,4 +53,13 @@ declare function pruneMissingCommand(options?: {
|
|
|
53
53
|
*/
|
|
54
54
|
declare function renameCommand(type: any, oldName: any, newName: any, options: any): Promise<void>;
|
|
55
55
|
|
|
56
|
-
|
|
56
|
+
/**
|
|
57
|
+
* Add a new item (hook, api, service, etc.) to an existing feature or component.
|
|
58
|
+
*
|
|
59
|
+
* @param {string} itemType The type of item to add (e.g., 'api', 'hook', 'service')
|
|
60
|
+
* @param {string} targetName The name of the feature or component
|
|
61
|
+
* @param {Object} options Additional options from Commander
|
|
62
|
+
*/
|
|
63
|
+
declare function addItemCommand(itemType: string, targetName: string, options: any): Promise<void>;
|
|
64
|
+
|
|
65
|
+
export { addItemCommand, addSectionCommand, adoptCommand, createComponentCommand, initCommand, listSectionsCommand, moveSectionCommand, normalizeStateCommand, pruneMissingCommand, removeComponentCommand, removeSectionCommand, renameCommand, statusCommand, syncCommand, upgradeConfigCommand, validateStateCommand };
|
package/dist/index.js
CHANGED
|
@@ -635,14 +635,6 @@ async function safeDelete(filePath, options = {}) {
|
|
|
635
635
|
await unlink(filePath);
|
|
636
636
|
return { deleted: true };
|
|
637
637
|
}
|
|
638
|
-
async function ensureNotExists(filePath, force = false) {
|
|
639
|
-
if (existsSync(filePath)) {
|
|
640
|
-
if (!force) {
|
|
641
|
-
throw new Error(`File already exists: ${filePath}\n` +
|
|
642
|
-
`Use --force to overwrite.`);
|
|
643
|
-
}
|
|
644
|
-
}
|
|
645
|
-
}
|
|
646
638
|
async function ensureDir(dirPath) {
|
|
647
639
|
await mkdir(dirPath, { recursive: true });
|
|
648
640
|
}
|
|
@@ -1542,18 +1534,26 @@ function reconstructSections(state, config) {
|
|
|
1542
1534
|
// Keep existing sections if their files still exist
|
|
1543
1535
|
const validSections = (state.sections || []).filter(section => {
|
|
1544
1536
|
// Check if route file exists in state.files
|
|
1545
|
-
const routeFile = Object.keys(files).find(f => {
|
|
1537
|
+
const routeFile = section.route ? Object.keys(files).find(f => {
|
|
1546
1538
|
const normalizedF = f.replace(/\\/g, '/');
|
|
1547
1539
|
const routePath = section.route === '/' ? 'index' : section.route.slice(1);
|
|
1548
1540
|
return normalizedF.startsWith(pagesRoot + '/' + routePath + '.') ||
|
|
1549
1541
|
normalizedF === pagesRoot + '/' + routePath + '/index.astro'; // nested mode
|
|
1550
|
-
});
|
|
1542
|
+
}) : true;
|
|
1551
1543
|
// Check if feature directory has at least one file in state.files
|
|
1552
|
-
const hasFeatureFiles = Object.keys(files).some(f =>
|
|
1544
|
+
const hasFeatureFiles = section.featurePath ? Object.keys(files).some(f => {
|
|
1545
|
+
const normalizedF = f.replace(/\\/g, '/');
|
|
1546
|
+
const featPath = section.featurePath.replace(/\\/g, '/');
|
|
1547
|
+
return normalizedF.startsWith(featPath + '/') ||
|
|
1548
|
+
normalizedF.startsWith(featuresRoot + '/' + featPath + '/');
|
|
1549
|
+
}) : false;
|
|
1553
1550
|
return routeFile && hasFeatureFiles;
|
|
1554
1551
|
});
|
|
1555
1552
|
const sections = new Map();
|
|
1556
|
-
validSections.forEach(s =>
|
|
1553
|
+
validSections.forEach(s => {
|
|
1554
|
+
const key = s.route || `feature:${s.featurePath}`;
|
|
1555
|
+
sections.set(key, s);
|
|
1556
|
+
});
|
|
1557
1557
|
// Try to discover new sections
|
|
1558
1558
|
for (const filePath in files) {
|
|
1559
1559
|
const normalizedPath = filePath.replace(/\\/g, '/');
|
|
@@ -1794,29 +1794,35 @@ async function addSectionCommand(route, featurePath, options) {
|
|
|
1794
1794
|
}
|
|
1795
1795
|
}
|
|
1796
1796
|
}
|
|
1797
|
-
|
|
1798
|
-
if (
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
if (
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1797
|
+
const featureExists = existsSync(featureFilePath);
|
|
1798
|
+
if (featureExists && !options.force) {
|
|
1799
|
+
console.log(`ℹ Feature already exists at ${featureFilePath}. Entering additive mode.`);
|
|
1800
|
+
}
|
|
1801
|
+
// Check sub-items only if not in force mode
|
|
1802
|
+
if (!options.force) {
|
|
1803
|
+
if (shouldCreateIndex && existsSync(indexFilePath))
|
|
1804
|
+
console.log(` - Skipping existing index: ${indexFilePath}`);
|
|
1805
|
+
if (shouldCreateContext && existsSync(contextFilePath))
|
|
1806
|
+
console.log(` - Skipping existing context: ${contextFilePath}`);
|
|
1807
|
+
if (shouldCreateHooks && existsSync(hookFilePath))
|
|
1808
|
+
console.log(` - Skipping existing hook: ${hookFilePath}`);
|
|
1809
|
+
if (shouldCreateTests && existsSync(testFilePath))
|
|
1810
|
+
console.log(` - Skipping existing test: ${testFilePath}`);
|
|
1811
|
+
if (shouldCreateTypes && existsSync(typesFilePath))
|
|
1812
|
+
console.log(` - Skipping existing types: ${typesFilePath}`);
|
|
1813
|
+
if (shouldCreateApi && existsSync(apiFilePath))
|
|
1814
|
+
console.log(` - Skipping existing api: ${apiFilePath}`);
|
|
1815
|
+
if (shouldCreateServices && existsSync(servicesFilePath))
|
|
1816
|
+
console.log(` - Skipping existing services: ${servicesFilePath}`);
|
|
1817
|
+
if (shouldCreateSchemas && existsSync(schemasFilePath))
|
|
1818
|
+
console.log(` - Skipping existing schemas: ${schemasFilePath}`);
|
|
1819
|
+
if (shouldCreateReadme && existsSync(readmeFilePath))
|
|
1820
|
+
console.log(` - Skipping existing readme: ${readmeFilePath}`);
|
|
1821
|
+
if (shouldCreateStories && existsSync(storiesFilePath))
|
|
1822
|
+
console.log(` - Skipping existing stories: ${storiesFilePath}`);
|
|
1823
|
+
if (shouldCreateScriptsDir && existsSync(scriptsIndexPath))
|
|
1824
|
+
console.log(` - Skipping existing scripts: ${scriptsIndexPath}`);
|
|
1825
|
+
}
|
|
1820
1826
|
let layoutImportPath = null;
|
|
1821
1827
|
const cliProps = options.prop || {};
|
|
1822
1828
|
const rawLayoutProps = { ...configLayoutProps, ...cliProps };
|
|
@@ -1938,15 +1944,17 @@ async function addSectionCommand(route, featurePath, options) {
|
|
|
1938
1944
|
if (shouldCreateTypes)
|
|
1939
1945
|
await ensureDir(typesDirInside);
|
|
1940
1946
|
const featureSignature = getSignature(config, config.naming.featureExtension === '.astro' ? 'astro' : 'tsx');
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1947
|
+
if (!featureExists || options.force) {
|
|
1948
|
+
const featureHash = await writeFileWithSignature(featureFilePath, featureContent, featureSignature, config.hashing?.normalization);
|
|
1949
|
+
await registerFile(featureFilePath, {
|
|
1950
|
+
kind: 'feature',
|
|
1951
|
+
template: 'feature',
|
|
1952
|
+
hash: featureHash,
|
|
1953
|
+
owner: normalizedRoute
|
|
1954
|
+
});
|
|
1955
|
+
writtenFiles.push(featureFilePath);
|
|
1956
|
+
}
|
|
1957
|
+
if (shouldCreateScriptsDir && (!existsSync(scriptsIndexPath) || options.force)) {
|
|
1950
1958
|
const hash = await writeFileWithSignature(scriptsIndexPath, generateScriptsIndexTemplate(), getSignature(config, 'typescript'), config.hashing?.normalization);
|
|
1951
1959
|
await registerFile(scriptsIndexPath, {
|
|
1952
1960
|
kind: 'feature-file',
|
|
@@ -1956,7 +1964,7 @@ async function addSectionCommand(route, featurePath, options) {
|
|
|
1956
1964
|
});
|
|
1957
1965
|
writtenFiles.push(scriptsIndexPath);
|
|
1958
1966
|
}
|
|
1959
|
-
if (shouldCreateIndex) {
|
|
1967
|
+
if (shouldCreateIndex && (!existsSync(indexFilePath) || options.force)) {
|
|
1960
1968
|
const indexContent = generateIndexTemplate(featureComponentName, config.naming.featureExtension);
|
|
1961
1969
|
const hash = await writeFileWithSignature(indexFilePath, indexContent, getSignature(config, 'typescript'), config.hashing?.normalization);
|
|
1962
1970
|
await registerFile(indexFilePath, {
|
|
@@ -1967,7 +1975,7 @@ async function addSectionCommand(route, featurePath, options) {
|
|
|
1967
1975
|
});
|
|
1968
1976
|
writtenFiles.push(indexFilePath);
|
|
1969
1977
|
}
|
|
1970
|
-
if (shouldCreateApi) {
|
|
1978
|
+
if (shouldCreateApi && (!existsSync(apiFilePath) || options.force)) {
|
|
1971
1979
|
const apiContent = generateApiTemplate(featureComponentName);
|
|
1972
1980
|
const hash = await writeFileWithSignature(apiFilePath, apiContent, getSignature(config, 'typescript'), config.hashing?.normalization);
|
|
1973
1981
|
await registerFile(apiFilePath, {
|
|
@@ -1978,7 +1986,7 @@ async function addSectionCommand(route, featurePath, options) {
|
|
|
1978
1986
|
});
|
|
1979
1987
|
writtenFiles.push(apiFilePath);
|
|
1980
1988
|
}
|
|
1981
|
-
if (shouldCreateServices) {
|
|
1989
|
+
if (shouldCreateServices && (!existsSync(servicesFilePath) || options.force)) {
|
|
1982
1990
|
const servicesContent = generateServiceTemplate(featureComponentName);
|
|
1983
1991
|
const hash = await writeFileWithSignature(servicesFilePath, servicesContent, getSignature(config, 'typescript'), config.hashing?.normalization);
|
|
1984
1992
|
await registerFile(servicesFilePath, {
|
|
@@ -1989,7 +1997,7 @@ async function addSectionCommand(route, featurePath, options) {
|
|
|
1989
1997
|
});
|
|
1990
1998
|
writtenFiles.push(servicesFilePath);
|
|
1991
1999
|
}
|
|
1992
|
-
if (shouldCreateSchemas) {
|
|
2000
|
+
if (shouldCreateSchemas && (!existsSync(schemasFilePath) || options.force)) {
|
|
1993
2001
|
const schemasContent = generateSchemaTemplate(featureComponentName);
|
|
1994
2002
|
const hash = await writeFileWithSignature(schemasFilePath, schemasContent, getSignature(config, 'typescript'), config.hashing?.normalization);
|
|
1995
2003
|
await registerFile(schemasFilePath, {
|
|
@@ -2000,7 +2008,7 @@ async function addSectionCommand(route, featurePath, options) {
|
|
|
2000
2008
|
});
|
|
2001
2009
|
writtenFiles.push(schemasFilePath);
|
|
2002
2010
|
}
|
|
2003
|
-
if (shouldCreateHooks) {
|
|
2011
|
+
if (shouldCreateHooks && (!existsSync(hookFilePath) || options.force)) {
|
|
2004
2012
|
const hookName = getHookFunctionName(featureComponentName);
|
|
2005
2013
|
const hookContent = generateHookTemplate(featureComponentName, hookName);
|
|
2006
2014
|
const hash = await writeFileWithSignature(hookFilePath, hookContent, getSignature(config, 'typescript'), config.hashing?.normalization);
|
|
@@ -2012,7 +2020,7 @@ async function addSectionCommand(route, featurePath, options) {
|
|
|
2012
2020
|
});
|
|
2013
2021
|
writtenFiles.push(hookFilePath);
|
|
2014
2022
|
}
|
|
2015
|
-
if (shouldCreateContext) {
|
|
2023
|
+
if (shouldCreateContext && (!existsSync(contextFilePath) || options.force)) {
|
|
2016
2024
|
const contextContent = generateContextTemplate(featureComponentName);
|
|
2017
2025
|
const hash = await writeFileWithSignature(contextFilePath, contextContent, getSignature(config, 'typescript'), config.hashing?.normalization);
|
|
2018
2026
|
await registerFile(contextFilePath, {
|
|
@@ -2023,7 +2031,7 @@ async function addSectionCommand(route, featurePath, options) {
|
|
|
2023
2031
|
});
|
|
2024
2032
|
writtenFiles.push(contextFilePath);
|
|
2025
2033
|
}
|
|
2026
|
-
if (shouldCreateTests) {
|
|
2034
|
+
if (shouldCreateTests && (!existsSync(testFilePath) || options.force)) {
|
|
2027
2035
|
const relativeFeaturePath = `./${path.basename(featureFilePath)}`;
|
|
2028
2036
|
const testContent = generateTestTemplate(featureComponentName, relativeFeaturePath);
|
|
2029
2037
|
const hash = await writeFileWithSignature(testFilePath, testContent, getSignature(config, 'typescript'), config.hashing?.normalization);
|
|
@@ -2035,7 +2043,7 @@ async function addSectionCommand(route, featurePath, options) {
|
|
|
2035
2043
|
});
|
|
2036
2044
|
writtenFiles.push(testFilePath);
|
|
2037
2045
|
}
|
|
2038
|
-
if (shouldCreateTypes) {
|
|
2046
|
+
if (shouldCreateTypes && (!existsSync(typesFilePath) || options.force)) {
|
|
2039
2047
|
const typesContent = generateTypesTemplate(featureComponentName);
|
|
2040
2048
|
const hash = await writeFileWithSignature(typesFilePath, typesContent, getSignature(config, 'typescript'), config.hashing?.normalization);
|
|
2041
2049
|
await registerFile(typesFilePath, {
|
|
@@ -2046,7 +2054,7 @@ async function addSectionCommand(route, featurePath, options) {
|
|
|
2046
2054
|
});
|
|
2047
2055
|
writtenFiles.push(typesFilePath);
|
|
2048
2056
|
}
|
|
2049
|
-
if (shouldCreateReadme) {
|
|
2057
|
+
if (shouldCreateReadme && (!existsSync(readmeFilePath) || options.force)) {
|
|
2050
2058
|
const readmeContent = generateReadmeTemplate(featureComponentName);
|
|
2051
2059
|
const hash = await writeFileWithSignature(readmeFilePath, readmeContent, getSignature(config, 'astro'), config.hashing?.normalization);
|
|
2052
2060
|
await registerFile(readmeFilePath, {
|
|
@@ -2057,7 +2065,7 @@ async function addSectionCommand(route, featurePath, options) {
|
|
|
2057
2065
|
});
|
|
2058
2066
|
writtenFiles.push(readmeFilePath);
|
|
2059
2067
|
}
|
|
2060
|
-
if (shouldCreateStories) {
|
|
2068
|
+
if (shouldCreateStories && (!existsSync(storiesFilePath) || options.force)) {
|
|
2061
2069
|
const relativePath = `./${path.basename(featureFilePath)}`;
|
|
2062
2070
|
const storiesContent = generateStoriesTemplate(featureComponentName, relativePath);
|
|
2063
2071
|
const hash = await writeFileWithSignature(storiesFilePath, storiesContent, getSignature(config, 'typescript'), config.hashing?.normalization);
|
|
@@ -2870,30 +2878,37 @@ async function createComponentCommand(componentName, options) {
|
|
|
2870
2878
|
console.log(` Sub-components: ${subComponentsDir}/`);
|
|
2871
2879
|
return;
|
|
2872
2880
|
}
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
if
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
|
|
2881
|
+
const componentExists = existsSync(componentFilePath);
|
|
2882
|
+
if (componentExists && !options.force) {
|
|
2883
|
+
console.log(`ℹ Component already exists at ${componentFilePath}. Entering additive mode.`);
|
|
2884
|
+
}
|
|
2885
|
+
// Check sub-items only if not in force mode
|
|
2886
|
+
if (!options.force) {
|
|
2887
|
+
if (existsSync(indexFilePath))
|
|
2888
|
+
console.log(` - Skipping existing index: ${indexFilePath}`);
|
|
2889
|
+
if (shouldCreateContext && existsSync(contextFilePath))
|
|
2890
|
+
console.log(` - Skipping existing context: ${contextFilePath}`);
|
|
2891
|
+
if (shouldCreateHook && existsSync(hookFilePath))
|
|
2892
|
+
console.log(` - Skipping existing hook: ${hookFilePath}`);
|
|
2893
|
+
if (shouldCreateTests && existsSync(testFilePath))
|
|
2894
|
+
console.log(` - Skipping existing test: ${testFilePath}`);
|
|
2895
|
+
if (shouldCreateConfig && existsSync(configFilePath))
|
|
2896
|
+
console.log(` - Skipping existing config: ${configFilePath}`);
|
|
2897
|
+
if (shouldCreateConstants && existsSync(constantsFilePath))
|
|
2898
|
+
console.log(` - Skipping existing constants: ${constantsFilePath}`);
|
|
2899
|
+
if (shouldCreateTypes && existsSync(typesFilePath))
|
|
2900
|
+
console.log(` - Skipping existing types: ${typesFilePath}`);
|
|
2901
|
+
if (shouldCreateApi && existsSync(apiFilePath))
|
|
2902
|
+
console.log(` - Skipping existing api: ${apiFilePath}`);
|
|
2903
|
+
if (shouldCreateServices && existsSync(servicesFilePath))
|
|
2904
|
+
console.log(` - Skipping existing services: ${servicesFilePath}`);
|
|
2905
|
+
if (shouldCreateSchemas && existsSync(schemasFilePath))
|
|
2906
|
+
console.log(` - Skipping existing schemas: ${schemasFilePath}`);
|
|
2907
|
+
if (shouldCreateReadme && existsSync(readmeFilePath))
|
|
2908
|
+
console.log(` - Skipping existing readme: ${readmeFilePath}`);
|
|
2909
|
+
if (shouldCreateStories && existsSync(storiesFilePath))
|
|
2910
|
+
console.log(` - Skipping existing stories: ${storiesFilePath}`);
|
|
2911
|
+
}
|
|
2897
2912
|
await ensureDir(componentDir);
|
|
2898
2913
|
if (shouldCreateSubComponentsDir)
|
|
2899
2914
|
await ensureDir(subComponentsDir);
|
|
@@ -2917,24 +2932,29 @@ async function createComponentCommand(componentName, options) {
|
|
|
2917
2932
|
await ensureDir(schemasDirInside);
|
|
2918
2933
|
const componentContent = generateComponentTemplate(normalizedName, framework, config.naming.componentExtension);
|
|
2919
2934
|
const signature = getSignature(config, config.naming.componentExtension === '.astro' ? 'astro' : 'tsx');
|
|
2920
|
-
const
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2935
|
+
const writtenFiles = [];
|
|
2936
|
+
if (!componentExists || options.force) {
|
|
2937
|
+
const componentHash = await writeFileWithSignature(componentFilePath, componentContent, signature, config.hashing?.normalization);
|
|
2938
|
+
await registerFile(componentFilePath, {
|
|
2939
|
+
kind: 'component',
|
|
2940
|
+
template: 'component',
|
|
2941
|
+
hash: componentHash,
|
|
2942
|
+
owner: normalizedName
|
|
2943
|
+
});
|
|
2944
|
+
writtenFiles.push(componentFilePath);
|
|
2945
|
+
}
|
|
2946
|
+
if (!existsSync(indexFilePath) || options.force) {
|
|
2947
|
+
const indexContent = generateIndexTemplate(normalizedName, config.naming.componentExtension);
|
|
2948
|
+
const indexHash = await writeFileWithSignature(indexFilePath, indexContent, getSignature(config, 'typescript'), config.hashing?.normalization);
|
|
2949
|
+
await registerFile(indexFilePath, {
|
|
2950
|
+
kind: 'component-file',
|
|
2951
|
+
template: 'index',
|
|
2952
|
+
hash: indexHash,
|
|
2953
|
+
owner: normalizedName
|
|
2954
|
+
});
|
|
2955
|
+
writtenFiles.push(indexFilePath);
|
|
2956
|
+
}
|
|
2957
|
+
if (shouldCreateTypes && (!existsSync(typesFilePath) || options.force)) {
|
|
2938
2958
|
const typesContent = generateTypesTemplate(normalizedName);
|
|
2939
2959
|
const hash = await writeFileWithSignature(typesFilePath, typesContent, getSignature(config, 'typescript'), config.hashing?.normalization);
|
|
2940
2960
|
await registerFile(typesFilePath, {
|
|
@@ -2945,7 +2965,7 @@ async function createComponentCommand(componentName, options) {
|
|
|
2945
2965
|
});
|
|
2946
2966
|
writtenFiles.push(typesFilePath);
|
|
2947
2967
|
}
|
|
2948
|
-
if (shouldCreateContext) {
|
|
2968
|
+
if (shouldCreateContext && (!existsSync(contextFilePath) || options.force)) {
|
|
2949
2969
|
const contextContent = generateContextTemplate(normalizedName);
|
|
2950
2970
|
const hash = await writeFileWithSignature(contextFilePath, contextContent, getSignature(config, 'typescript'), config.hashing?.normalization);
|
|
2951
2971
|
await registerFile(contextFilePath, {
|
|
@@ -2956,7 +2976,7 @@ async function createComponentCommand(componentName, options) {
|
|
|
2956
2976
|
});
|
|
2957
2977
|
writtenFiles.push(contextFilePath);
|
|
2958
2978
|
}
|
|
2959
|
-
if (shouldCreateHook) {
|
|
2979
|
+
if (shouldCreateHook && (!existsSync(hookFilePath) || options.force)) {
|
|
2960
2980
|
const hookName = getHookFunctionName(normalizedName);
|
|
2961
2981
|
const hookContent = generateHookTemplate(normalizedName, hookName);
|
|
2962
2982
|
const hash = await writeFileWithSignature(hookFilePath, hookContent, getSignature(config, 'typescript'), config.hashing?.normalization);
|
|
@@ -2968,7 +2988,7 @@ async function createComponentCommand(componentName, options) {
|
|
|
2968
2988
|
});
|
|
2969
2989
|
writtenFiles.push(hookFilePath);
|
|
2970
2990
|
}
|
|
2971
|
-
if (shouldCreateTests) {
|
|
2991
|
+
if (shouldCreateTests && (!existsSync(testFilePath) || options.force)) {
|
|
2972
2992
|
const relativeComponentPath = `../${normalizedName}${config.naming.componentExtension}`;
|
|
2973
2993
|
const testContent = generateTestTemplate(normalizedName, relativeComponentPath);
|
|
2974
2994
|
const hash = await writeFileWithSignature(testFilePath, testContent, getSignature(config, 'typescript'), config.hashing?.normalization);
|
|
@@ -2980,7 +3000,7 @@ async function createComponentCommand(componentName, options) {
|
|
|
2980
3000
|
});
|
|
2981
3001
|
writtenFiles.push(testFilePath);
|
|
2982
3002
|
}
|
|
2983
|
-
if (shouldCreateConfig) {
|
|
3003
|
+
if (shouldCreateConfig && (!existsSync(configFilePath) || options.force)) {
|
|
2984
3004
|
const configContent = generateConfigTemplate(normalizedName);
|
|
2985
3005
|
const hash = await writeFileWithSignature(configFilePath, configContent, getSignature(config, 'typescript'), config.hashing?.normalization);
|
|
2986
3006
|
await registerFile(configFilePath, {
|
|
@@ -2991,7 +3011,7 @@ async function createComponentCommand(componentName, options) {
|
|
|
2991
3011
|
});
|
|
2992
3012
|
writtenFiles.push(configFilePath);
|
|
2993
3013
|
}
|
|
2994
|
-
if (shouldCreateConstants) {
|
|
3014
|
+
if (shouldCreateConstants && (!existsSync(constantsFilePath) || options.force)) {
|
|
2995
3015
|
const constantsContent = generateConstantsTemplate(normalizedName);
|
|
2996
3016
|
const hash = await writeFileWithSignature(constantsFilePath, constantsContent, getSignature(config, 'typescript'), config.hashing?.normalization);
|
|
2997
3017
|
await registerFile(constantsFilePath, {
|
|
@@ -3002,7 +3022,7 @@ async function createComponentCommand(componentName, options) {
|
|
|
3002
3022
|
});
|
|
3003
3023
|
writtenFiles.push(constantsFilePath);
|
|
3004
3024
|
}
|
|
3005
|
-
if (shouldCreateApi) {
|
|
3025
|
+
if (shouldCreateApi && (!existsSync(apiFilePath) || options.force)) {
|
|
3006
3026
|
const apiContent = generateApiTemplate(normalizedName);
|
|
3007
3027
|
const hash = await writeFileWithSignature(apiFilePath, apiContent, getSignature(config, 'typescript'), config.hashing?.normalization);
|
|
3008
3028
|
await registerFile(apiFilePath, {
|
|
@@ -3013,7 +3033,7 @@ async function createComponentCommand(componentName, options) {
|
|
|
3013
3033
|
});
|
|
3014
3034
|
writtenFiles.push(apiFilePath);
|
|
3015
3035
|
}
|
|
3016
|
-
if (shouldCreateServices) {
|
|
3036
|
+
if (shouldCreateServices && (!existsSync(servicesFilePath) || options.force)) {
|
|
3017
3037
|
const servicesContent = generateServiceTemplate(normalizedName);
|
|
3018
3038
|
const hash = await writeFileWithSignature(servicesFilePath, servicesContent, getSignature(config, 'typescript'), config.hashing?.normalization);
|
|
3019
3039
|
await registerFile(servicesFilePath, {
|
|
@@ -3024,7 +3044,7 @@ async function createComponentCommand(componentName, options) {
|
|
|
3024
3044
|
});
|
|
3025
3045
|
writtenFiles.push(servicesFilePath);
|
|
3026
3046
|
}
|
|
3027
|
-
if (shouldCreateSchemas) {
|
|
3047
|
+
if (shouldCreateSchemas && (!existsSync(schemasFilePath) || options.force)) {
|
|
3028
3048
|
const schemasContent = generateSchemaTemplate(normalizedName);
|
|
3029
3049
|
const hash = await writeFileWithSignature(schemasFilePath, schemasContent, getSignature(config, 'typescript'), config.hashing?.normalization);
|
|
3030
3050
|
await registerFile(schemasFilePath, {
|
|
@@ -3035,7 +3055,7 @@ async function createComponentCommand(componentName, options) {
|
|
|
3035
3055
|
});
|
|
3036
3056
|
writtenFiles.push(schemasFilePath);
|
|
3037
3057
|
}
|
|
3038
|
-
if (shouldCreateReadme) {
|
|
3058
|
+
if (shouldCreateReadme && (!existsSync(readmeFilePath) || options.force)) {
|
|
3039
3059
|
const readmeContent = generateReadmeTemplate(normalizedName);
|
|
3040
3060
|
const hash = await writeFileWithSignature(readmeFilePath, readmeContent, getSignature(config, 'astro'), config.hashing?.normalization);
|
|
3041
3061
|
await registerFile(readmeFilePath, {
|
|
@@ -3046,7 +3066,7 @@ async function createComponentCommand(componentName, options) {
|
|
|
3046
3066
|
});
|
|
3047
3067
|
writtenFiles.push(readmeFilePath);
|
|
3048
3068
|
}
|
|
3049
|
-
if (shouldCreateStories) {
|
|
3069
|
+
if (shouldCreateStories && (!existsSync(storiesFilePath) || options.force)) {
|
|
3050
3070
|
const relativePath = `./${normalizedName}${config.naming.componentExtension}`;
|
|
3051
3071
|
const storiesContent = generateStoriesTemplate(normalizedName, relativePath);
|
|
3052
3072
|
const hash = await writeFileWithSignature(storiesFilePath, storiesContent, getSignature(config, 'typescript'), config.hashing?.normalization);
|
|
@@ -3624,7 +3644,24 @@ async function syncCommand(options) {
|
|
|
3624
3644
|
}
|
|
3625
3645
|
}
|
|
3626
3646
|
|
|
3627
|
-
async function adoptCommand(
|
|
3647
|
+
async function adoptCommand(kind, arg2, arg3, options) {
|
|
3648
|
+
// Handle cases where options is in a different position due to variable arguments
|
|
3649
|
+
if (typeof kind === 'object' && kind !== null && !Array.isArray(kind)) {
|
|
3650
|
+
options = kind;
|
|
3651
|
+
kind = undefined;
|
|
3652
|
+
arg2 = undefined;
|
|
3653
|
+
arg3 = undefined;
|
|
3654
|
+
}
|
|
3655
|
+
else if (typeof arg2 === 'object' && arg2 !== null && !Array.isArray(arg2)) {
|
|
3656
|
+
options = arg2;
|
|
3657
|
+
arg2 = undefined;
|
|
3658
|
+
arg3 = undefined;
|
|
3659
|
+
}
|
|
3660
|
+
else if (typeof arg3 === 'object' && arg3 !== null && !Array.isArray(arg3)) {
|
|
3661
|
+
options = arg3;
|
|
3662
|
+
arg3 = undefined;
|
|
3663
|
+
}
|
|
3664
|
+
options = options || {};
|
|
3628
3665
|
try {
|
|
3629
3666
|
const config = await loadConfig();
|
|
3630
3667
|
const state = await loadState();
|
|
@@ -3634,6 +3671,9 @@ async function adoptCommand(identifier, options) {
|
|
|
3634
3671
|
components: resolvePath(config, 'components')
|
|
3635
3672
|
};
|
|
3636
3673
|
let filesToAdopt = [];
|
|
3674
|
+
let identifier = kind;
|
|
3675
|
+
let customName = null;
|
|
3676
|
+
let sourcePath = null;
|
|
3637
3677
|
if (!identifier && options.all) {
|
|
3638
3678
|
// Adopt all untracked files in all roots
|
|
3639
3679
|
const managedFiles = new Set();
|
|
@@ -3644,6 +3684,46 @@ async function adoptCommand(identifier, options) {
|
|
|
3644
3684
|
}
|
|
3645
3685
|
filesToAdopt = Array.from(managedFiles).filter(f => !state.files[f]);
|
|
3646
3686
|
}
|
|
3687
|
+
else if (kind === 'component' && arg2) {
|
|
3688
|
+
const componentName = arg2;
|
|
3689
|
+
const untrackedFiles = new Set();
|
|
3690
|
+
const compPath = path.join(roots.components, componentName);
|
|
3691
|
+
if (existsSync(compPath)) {
|
|
3692
|
+
await scanDirectoryOrFile(compPath, untrackedFiles, state);
|
|
3693
|
+
}
|
|
3694
|
+
else {
|
|
3695
|
+
throw new Error(`Component directory not found: ${compPath}`);
|
|
3696
|
+
}
|
|
3697
|
+
filesToAdopt = Array.from(untrackedFiles);
|
|
3698
|
+
}
|
|
3699
|
+
else if (kind === 'feature' && arg2 && arg3) {
|
|
3700
|
+
sourcePath = arg2;
|
|
3701
|
+
customName = arg3;
|
|
3702
|
+
const targetPath = path.join(roots.features, customName);
|
|
3703
|
+
const absoluteSource = path.resolve(process.cwd(), sourcePath);
|
|
3704
|
+
const absoluteTarget = path.resolve(targetPath);
|
|
3705
|
+
if (existsSync(absoluteSource)) {
|
|
3706
|
+
if (!options.dryRun && absoluteSource !== absoluteTarget) {
|
|
3707
|
+
if (!existsSync(path.dirname(absoluteTarget))) {
|
|
3708
|
+
await mkdir(path.dirname(absoluteTarget), { recursive: true });
|
|
3709
|
+
}
|
|
3710
|
+
console.log(`Moving files from ${sourcePath} to ${path.relative(process.cwd(), targetPath)}...`);
|
|
3711
|
+
await rename(absoluteSource, absoluteTarget);
|
|
3712
|
+
sourcePath = path.relative(process.cwd(), targetPath);
|
|
3713
|
+
}
|
|
3714
|
+
else if (options.dryRun && absoluteSource !== absoluteTarget) {
|
|
3715
|
+
console.log(`Dry run: would move files from ${sourcePath} to ${path.relative(process.cwd(), targetPath)}`);
|
|
3716
|
+
sourcePath = path.relative(process.cwd(), targetPath);
|
|
3717
|
+
}
|
|
3718
|
+
const untrackedFiles = new Set();
|
|
3719
|
+
const fullPath = absoluteSource !== absoluteTarget && !options.dryRun ? absoluteTarget : absoluteSource;
|
|
3720
|
+
await scanDirectoryOrFile(fullPath, untrackedFiles, state);
|
|
3721
|
+
filesToAdopt = Array.from(untrackedFiles);
|
|
3722
|
+
}
|
|
3723
|
+
else {
|
|
3724
|
+
throw new Error(`Source path not found: ${absoluteSource}`);
|
|
3725
|
+
}
|
|
3726
|
+
}
|
|
3647
3727
|
else if (identifier) {
|
|
3648
3728
|
const untrackedFiles = new Set();
|
|
3649
3729
|
// 1. Try as direct path
|
|
@@ -3985,5 +4065,59 @@ async function renameComponent(oldName, newName, options) {
|
|
|
3985
4065
|
console.log(`✓ Renamed component ${normalizedOldName} to ${normalizedNewName}`);
|
|
3986
4066
|
}
|
|
3987
4067
|
|
|
3988
|
-
|
|
4068
|
+
/**
|
|
4069
|
+
* Add a new item (hook, api, service, etc.) to an existing feature or component.
|
|
4070
|
+
*
|
|
4071
|
+
* @param {string} itemType The type of item to add (e.g., 'api', 'hook', 'service')
|
|
4072
|
+
* @param {string} targetName The name of the feature or component
|
|
4073
|
+
* @param {Object} options Additional options from Commander
|
|
4074
|
+
*/
|
|
4075
|
+
async function addItemCommand(itemType, targetName, options) {
|
|
4076
|
+
try {
|
|
4077
|
+
const state = await loadState();
|
|
4078
|
+
// Normalize itemType
|
|
4079
|
+
let normalizedItem = itemType.toLowerCase();
|
|
4080
|
+
if (normalizedItem === 'test')
|
|
4081
|
+
normalizedItem = 'tests';
|
|
4082
|
+
if (normalizedItem === 'service')
|
|
4083
|
+
normalizedItem = 'services';
|
|
4084
|
+
if (normalizedItem === 'schema')
|
|
4085
|
+
normalizedItem = 'schemas';
|
|
4086
|
+
if (normalizedItem === 'hook')
|
|
4087
|
+
normalizedItem = 'hooks'; // for add-section
|
|
4088
|
+
// Try to find as section (feature) first
|
|
4089
|
+
let section = findSection(state, targetName);
|
|
4090
|
+
let component = findComponent(state, targetName);
|
|
4091
|
+
// If not found by exact name, try to find by featurePath or part of it
|
|
4092
|
+
if (!section && !component) {
|
|
4093
|
+
section = state.sections.find(s => s.featurePath === targetName || s.featurePath.endsWith('/' + targetName));
|
|
4094
|
+
}
|
|
4095
|
+
if (!section && !component) {
|
|
4096
|
+
throw new Error(`Target not found in state: "${targetName}". Please use "add-section" or "create-component" directly if it's not managed by Textor.`);
|
|
4097
|
+
}
|
|
4098
|
+
const flags = { [normalizedItem]: true };
|
|
4099
|
+
// Also set singular for create-component which uses 'hook'
|
|
4100
|
+
if (normalizedItem === 'hooks')
|
|
4101
|
+
flags.hook = true;
|
|
4102
|
+
if (section) {
|
|
4103
|
+
console.log(`ℹ Adding ${normalizedItem} to feature: ${section.featurePath}`);
|
|
4104
|
+
return await addSectionCommand(undefined, section.featurePath, { ...options, ...flags });
|
|
4105
|
+
}
|
|
4106
|
+
if (component) {
|
|
4107
|
+
console.log(`ℹ Adding ${normalizedItem} to component: ${component.name}`);
|
|
4108
|
+
// For create-component, we might need to be careful with flags that are on by default
|
|
4109
|
+
// but getEffectiveOptions should handle it if we pass them explicitly as true.
|
|
4110
|
+
return await createComponentCommand(component.name, { ...options, ...flags });
|
|
4111
|
+
}
|
|
4112
|
+
}
|
|
4113
|
+
catch (error) {
|
|
4114
|
+
console.error('Error:', error.message);
|
|
4115
|
+
if (typeof process.exit === 'function' && process.env.NODE_ENV !== 'test') {
|
|
4116
|
+
process.exit(1);
|
|
4117
|
+
}
|
|
4118
|
+
throw error;
|
|
4119
|
+
}
|
|
4120
|
+
}
|
|
4121
|
+
|
|
4122
|
+
export { addItemCommand, addSectionCommand, adoptCommand, createComponentCommand, initCommand, listSectionsCommand, moveSectionCommand, normalizeStateCommand, pruneMissingCommand, removeComponentCommand, removeSectionCommand, renameCommand, statusCommand, syncCommand, upgradeConfigCommand, validateStateCommand };
|
|
3989
4123
|
//# sourceMappingURL=index.js.map
|