@oamm/textor 1.0.7 → 1.0.8
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 +28 -1
- package/dist/bin/textor.js +144 -63
- package/dist/bin/textor.js.map +1 -1
- package/dist/index.cjs +122 -56
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +122 -56
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -341,6 +341,8 @@ The .textor/config.json file allows full control over the tool's behavior.
|
|
|
341
341
|
"indexFile": "index.astro"
|
|
342
342
|
},
|
|
343
343
|
"importAliases": {
|
|
344
|
+
"layouts": "@/layouts",
|
|
345
|
+
"features": "@/features"
|
|
344
346
|
},
|
|
345
347
|
"naming": {
|
|
346
348
|
"routeExtension": ".astro",
|
|
@@ -459,6 +461,31 @@ The .textor/config.json file allows full control over the tool's behavior.
|
|
|
459
461
|
```
|
|
460
462
|
*Supported formatting tools: prettier, biome, none.*
|
|
461
463
|
|
|
464
|
+
### 7. Layout Parameters
|
|
465
|
+
|
|
466
|
+
You can pass parameters to your layout component by defining `layoutProps` in `.textor/config.json`. These props support variable substitution.
|
|
467
|
+
|
|
468
|
+
```json
|
|
469
|
+
{
|
|
470
|
+
"features": {
|
|
471
|
+
"layout": "AppLayout",
|
|
472
|
+
"layoutProps": {
|
|
473
|
+
"title": "{{componentName}}",
|
|
474
|
+
"description": "Description for {{componentName}}"
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
You can also override these props via the CLI using the `--prop` flag:
|
|
481
|
+
```bash
|
|
482
|
+
pnpm textor add-section /users users/roles --prop title="Custom Title" --prop breadcrumbs='{[{ label: "Users" }]}'
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
Properties that start and end with curly braces `{}` are passed as JavaScript expressions, others as strings.
|
|
486
|
+
|
|
487
|
+
---
|
|
488
|
+
|
|
462
489
|
## 📝 Template Overrides
|
|
463
490
|
|
|
464
491
|
You can customize the code generated by Textor by providing your own templates. Textor looks for override files in the `.textor/templates/` directory at your project root.
|
|
@@ -473,7 +500,7 @@ You can customize the code generated by Textor by providing your own templates.
|
|
|
473
500
|
|
|
474
501
|
| Template Name | File to create in `.textor/templates/` | Available Variables |
|
|
475
502
|
| :--- | :--- | :--- |
|
|
476
|
-
| **Route** | `route.astro` | `{{layoutName}}`, `{{layoutImportPath}}`, `{{featureImportPath}}`, `{{featureComponentName}}` |
|
|
503
|
+
| **Route** | `route.astro` | `{{layoutName}}`, `{{layoutImportPath}}`, `{{featureImportPath}}`, `{{featureComponentName}}`, plus any `layoutProps` |
|
|
477
504
|
| **Feature** | `feature.astro` or `feature.tsx` | `{{componentName}}`, `{{scriptImportPath}}` |
|
|
478
505
|
| **Component** | `component.astro` or `component.tsx` | `{{componentName}}` |
|
|
479
506
|
| **Hook** | `hook.ts` | `{{componentName}}`, `{{hookName}}` |
|
package/dist/bin/textor.js
CHANGED
|
@@ -42,6 +42,7 @@ const CURRENT_CONFIG_VERSION = 2;
|
|
|
42
42
|
* @property {boolean} features.createScriptsDir
|
|
43
43
|
* @property {string} features.scriptsIndexFile
|
|
44
44
|
* @property {string} features.layout
|
|
45
|
+
* @property {Object} features.layoutProps
|
|
45
46
|
* @property {Object} components
|
|
46
47
|
* @property {boolean} components.createSubComponentsDir
|
|
47
48
|
* @property {boolean} components.createContext
|
|
@@ -108,7 +109,8 @@ const DEFAULT_CONFIG = {
|
|
|
108
109
|
createReadme: false,
|
|
109
110
|
createStories: false,
|
|
110
111
|
createIndex: false,
|
|
111
|
-
layout: 'Main'
|
|
112
|
+
layout: 'Main',
|
|
113
|
+
layoutProps: {}
|
|
112
114
|
},
|
|
113
115
|
components: {
|
|
114
116
|
framework: 'react',
|
|
@@ -1020,27 +1022,6 @@ async function formatFiles(filePaths, tool) {
|
|
|
1020
1022
|
}
|
|
1021
1023
|
}
|
|
1022
1024
|
|
|
1023
|
-
var filesystem = /*#__PURE__*/Object.freeze({
|
|
1024
|
-
__proto__: null,
|
|
1025
|
-
calculateHash: calculateHash,
|
|
1026
|
-
cleanupEmptyDirs: cleanupEmptyDirs,
|
|
1027
|
-
ensureDir: ensureDir,
|
|
1028
|
-
ensureNotExists: ensureNotExists,
|
|
1029
|
-
formatFiles: formatFiles,
|
|
1030
|
-
getSignature: getSignature,
|
|
1031
|
-
inferKind: inferKind,
|
|
1032
|
-
isEmptyDir: isEmptyDir,
|
|
1033
|
-
isTextorGenerated: isTextorGenerated,
|
|
1034
|
-
safeDelete: safeDelete,
|
|
1035
|
-
safeDeleteDir: safeDeleteDir,
|
|
1036
|
-
safeMove: safeMove,
|
|
1037
|
-
scanDirectory: scanDirectory,
|
|
1038
|
-
secureJoin: secureJoin,
|
|
1039
|
-
updateSignature: updateSignature,
|
|
1040
|
-
verifyFileIntegrity: verifyFileIntegrity,
|
|
1041
|
-
writeFileWithSignature: writeFileWithSignature
|
|
1042
|
-
});
|
|
1043
|
-
|
|
1044
1025
|
function renderNamePattern(pattern, data = {}, label = 'pattern') {
|
|
1045
1026
|
if (typeof pattern !== 'string') return null;
|
|
1046
1027
|
const trimmed = pattern.trim();
|
|
@@ -1108,13 +1089,15 @@ function getTemplateOverride(templateName, extension, data = {}) {
|
|
|
1108
1089
|
* - layoutImportPath: Path to import the layout
|
|
1109
1090
|
* - featureImportPath: Path to import the feature component
|
|
1110
1091
|
* - featureComponentName: Name of the feature component
|
|
1092
|
+
* - layoutProps: Optional properties for the layout
|
|
1111
1093
|
*/
|
|
1112
|
-
function generateRouteTemplate(layoutName, layoutImportPath, featureImportPath, featureComponentName, extension = '.astro') {
|
|
1094
|
+
function generateRouteTemplate(layoutName, layoutImportPath, featureImportPath, featureComponentName, extension = '.astro', layoutProps = {}) {
|
|
1113
1095
|
const override = getTemplateOverride('route', extension, {
|
|
1114
1096
|
layoutName,
|
|
1115
1097
|
layoutImportPath,
|
|
1116
1098
|
featureImportPath,
|
|
1117
|
-
featureComponentName
|
|
1099
|
+
featureComponentName,
|
|
1100
|
+
...layoutProps
|
|
1118
1101
|
});
|
|
1119
1102
|
if (override) return override;
|
|
1120
1103
|
|
|
@@ -1127,12 +1110,26 @@ import ${featureComponentName} from '${featureImportPath}';
|
|
|
1127
1110
|
`;
|
|
1128
1111
|
}
|
|
1129
1112
|
|
|
1113
|
+
const propsStr = Object.entries(layoutProps)
|
|
1114
|
+
.map(([key, value]) => {
|
|
1115
|
+
if (typeof value === 'string' && value.startsWith('{') && value.endsWith('}')) {
|
|
1116
|
+
return `${key}=${value}`;
|
|
1117
|
+
}
|
|
1118
|
+
if (typeof value === 'string') {
|
|
1119
|
+
return `${key}="${value}"`;
|
|
1120
|
+
}
|
|
1121
|
+
return `${key}={${JSON.stringify(value)}}`;
|
|
1122
|
+
})
|
|
1123
|
+
.join(' ');
|
|
1124
|
+
|
|
1125
|
+
const layoutOpening = propsStr ? `<${layoutName} ${propsStr}>` : `<${layoutName}>`;
|
|
1126
|
+
|
|
1130
1127
|
return `---
|
|
1131
1128
|
import ${layoutName} from '${layoutImportPath}';
|
|
1132
1129
|
import ${featureComponentName} from '${featureImportPath}';
|
|
1133
1130
|
---
|
|
1134
1131
|
|
|
1135
|
-
|
|
1132
|
+
${layoutOpening}
|
|
1136
1133
|
<${featureComponentName} />
|
|
1137
1134
|
</${layoutName}>
|
|
1138
1135
|
`;
|
|
@@ -1343,6 +1340,11 @@ function generateIndexTemplate(componentName, componentExtension) {
|
|
|
1343
1340
|
const override = getTemplateOverride('index', '.ts', { componentName, componentExtension });
|
|
1344
1341
|
if (override) return override;
|
|
1345
1342
|
|
|
1343
|
+
if (componentExtension === '.astro') {
|
|
1344
|
+
return `export * from './types';
|
|
1345
|
+
`;
|
|
1346
|
+
}
|
|
1347
|
+
|
|
1346
1348
|
return `export { default as ${componentName} } from './${componentName}${componentExtension}';
|
|
1347
1349
|
export * from './types';
|
|
1348
1350
|
`;
|
|
@@ -1798,6 +1800,7 @@ async function addSectionCommand(route, featurePath, options) {
|
|
|
1798
1800
|
const {
|
|
1799
1801
|
framework,
|
|
1800
1802
|
layout,
|
|
1803
|
+
layoutProps: configLayoutProps,
|
|
1801
1804
|
createSubComponentsDir: shouldCreateSubComponentsDir,
|
|
1802
1805
|
createScriptsDir: shouldCreateScriptsDir,
|
|
1803
1806
|
createApi: shouldCreateApi,
|
|
@@ -1969,7 +1972,7 @@ async function addSectionCommand(route, featurePath, options) {
|
|
|
1969
1972
|
}
|
|
1970
1973
|
|
|
1971
1974
|
// Update imports in the moved file
|
|
1972
|
-
await updateImportsInFile$
|
|
1975
|
+
await updateImportsInFile$2(reorg.to, reorg.from, reorg.to);
|
|
1973
1976
|
|
|
1974
1977
|
// Update hash in state after import updates
|
|
1975
1978
|
if (state.files[newRelative]) {
|
|
@@ -1998,6 +2001,32 @@ async function addSectionCommand(route, featurePath, options) {
|
|
|
1998
2001
|
if (shouldCreateScriptsDir) await ensureNotExists(scriptsIndexPath, options.force);
|
|
1999
2002
|
|
|
2000
2003
|
let layoutImportPath = null;
|
|
2004
|
+
const cliProps = options.prop || {};
|
|
2005
|
+
const rawLayoutProps = { ...configLayoutProps, ...cliProps };
|
|
2006
|
+
const layoutProps = {};
|
|
2007
|
+
|
|
2008
|
+
// Resolve variables in layoutProps
|
|
2009
|
+
const substitutionData = enrichData({
|
|
2010
|
+
componentName: featureComponentName,
|
|
2011
|
+
layoutName: layout,
|
|
2012
|
+
featureComponentName: featureComponentName
|
|
2013
|
+
});
|
|
2014
|
+
|
|
2015
|
+
for (const [key, value] of Object.entries(rawLayoutProps)) {
|
|
2016
|
+
if (typeof value === 'string') {
|
|
2017
|
+
let resolvedValue = value;
|
|
2018
|
+
for (const [varKey, varValue] of Object.entries(substitutionData)) {
|
|
2019
|
+
const regex = new RegExp(`{{${varKey}}}`, 'g');
|
|
2020
|
+
resolvedValue = resolvedValue.replace(regex, varValue);
|
|
2021
|
+
const underscoreRegex = new RegExp(`__${varKey}__`, 'g');
|
|
2022
|
+
resolvedValue = resolvedValue.replace(underscoreRegex, varValue);
|
|
2023
|
+
}
|
|
2024
|
+
layoutProps[key] = resolvedValue;
|
|
2025
|
+
} else {
|
|
2026
|
+
layoutProps[key] = value;
|
|
2027
|
+
}
|
|
2028
|
+
}
|
|
2029
|
+
|
|
2001
2030
|
if (routeFilePath && layout !== 'none') {
|
|
2002
2031
|
if (config.importAliases.layouts) {
|
|
2003
2032
|
layoutImportPath = `${config.importAliases.layouts}/${layout}.astro`;
|
|
@@ -2010,7 +2039,7 @@ async function addSectionCommand(route, featurePath, options) {
|
|
|
2010
2039
|
let featureImportPath = null;
|
|
2011
2040
|
if (routeFilePath) {
|
|
2012
2041
|
if (config.importAliases.features) {
|
|
2013
|
-
const entryPart = effectiveOptions.entry === 'index' ? '' : `/${featureComponentName}`;
|
|
2042
|
+
const entryPart = effectiveOptions.entry === 'index' ? '/index' : `/${featureComponentName}`;
|
|
2014
2043
|
// In Astro, we can often omit the extension for .tsx files, but not for .astro files if using aliases sometimes.
|
|
2015
2044
|
// However, to be safe, we use the configured extension.
|
|
2016
2045
|
featureImportPath = `${config.importAliases.features}/${normalizedFeaturePath}${entryPart}${config.naming.featureExtension}`;
|
|
@@ -2043,7 +2072,8 @@ async function addSectionCommand(route, featurePath, options) {
|
|
|
2043
2072
|
layoutImportPath,
|
|
2044
2073
|
featureImportPath,
|
|
2045
2074
|
featureComponentName,
|
|
2046
|
-
routeExtension
|
|
2075
|
+
routeExtension,
|
|
2076
|
+
layoutProps
|
|
2047
2077
|
);
|
|
2048
2078
|
routeSignature = getSignature(config, 'astro');
|
|
2049
2079
|
}
|
|
@@ -2328,7 +2358,7 @@ async function addSectionCommand(route, featurePath, options) {
|
|
|
2328
2358
|
}
|
|
2329
2359
|
}
|
|
2330
2360
|
|
|
2331
|
-
async function updateImportsInFile$
|
|
2361
|
+
async function updateImportsInFile$2(filePath, oldFilePath, newFilePath) {
|
|
2332
2362
|
if (!existsSync(filePath)) return;
|
|
2333
2363
|
|
|
2334
2364
|
let content = await readFile(filePath, 'utf-8');
|
|
@@ -2538,7 +2568,7 @@ async function removeSectionCommand(route, featurePath, options) {
|
|
|
2538
2568
|
state.files[newRelative] = { ...state.files[oldRelative] };
|
|
2539
2569
|
delete state.files[oldRelative];
|
|
2540
2570
|
|
|
2541
|
-
await updateImportsInFile(flatFilePath, loneFilePath, flatFilePath);
|
|
2571
|
+
await updateImportsInFile$1(flatFilePath, loneFilePath, flatFilePath);
|
|
2542
2572
|
|
|
2543
2573
|
// Update hash in state after import updates
|
|
2544
2574
|
const content = await readFile(flatFilePath, 'utf-8');
|
|
@@ -2568,7 +2598,7 @@ async function removeSectionCommand(route, featurePath, options) {
|
|
|
2568
2598
|
}
|
|
2569
2599
|
}
|
|
2570
2600
|
|
|
2571
|
-
async function updateImportsInFile(filePath, oldFilePath, newFilePath) {
|
|
2601
|
+
async function updateImportsInFile$1(filePath, oldFilePath, newFilePath) {
|
|
2572
2602
|
if (!existsSync(filePath)) return;
|
|
2573
2603
|
|
|
2574
2604
|
let content = await readFile(filePath, 'utf-8');
|
|
@@ -2741,9 +2771,14 @@ async function moveSectionCommand(fromRoute, fromFeature, toRoute, toFeature, op
|
|
|
2741
2771
|
const fromFeatureComponentName = getFeatureComponentName(normalizedFromFeature);
|
|
2742
2772
|
const toFeatureComponentName = getFeatureComponentName(targetFeature);
|
|
2743
2773
|
|
|
2744
|
-
//
|
|
2774
|
+
// First, update all relative imports in the file because it moved
|
|
2775
|
+
await updateImportsInFile(toRoutePath, fromRoutePath, toRoutePath);
|
|
2776
|
+
|
|
2777
|
+
let content = await readFile(toRoutePath, 'utf-8');
|
|
2778
|
+
let changed = false;
|
|
2779
|
+
|
|
2780
|
+
// Update component name in JSX tags
|
|
2745
2781
|
if (fromFeatureComponentName !== toFeatureComponentName) {
|
|
2746
|
-
let content = await readFile(toRoutePath, 'utf-8');
|
|
2747
2782
|
content = content.replace(
|
|
2748
2783
|
new RegExp(`<${fromFeatureComponentName}`, 'g'),
|
|
2749
2784
|
`<${toFeatureComponentName}`
|
|
@@ -2752,44 +2787,54 @@ async function moveSectionCommand(fromRoute, fromFeature, toRoute, toFeature, op
|
|
|
2752
2787
|
new RegExp(`</${fromFeatureComponentName}`, 'g'),
|
|
2753
2788
|
`</${toFeatureComponentName}`
|
|
2754
2789
|
);
|
|
2755
|
-
|
|
2790
|
+
changed = true;
|
|
2756
2791
|
}
|
|
2757
2792
|
|
|
2758
2793
|
if (config.importAliases.features) {
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
`import ${toFeatureComponentName} from '${aliasPath}/${toFeatureComponentName}${ext}'`
|
|
2779
|
-
);
|
|
2794
|
+
const oldAliasPath = `${config.importAliases.features}/${normalizedFromFeature}`;
|
|
2795
|
+
const newAliasPath = `${config.importAliases.features}/${targetFeature}`;
|
|
2796
|
+
|
|
2797
|
+
// Flexible regex to match import identifier and path with alias
|
|
2798
|
+
const importRegex = new RegExp(`(import\\s+)(${fromFeatureComponentName})(\\s+from\\s+['"])${oldAliasPath}(/[^'"]+)?(['"])`, 'g');
|
|
2799
|
+
|
|
2800
|
+
if (importRegex.test(content)) {
|
|
2801
|
+
content = content.replace(importRegex, (match, p1, p2, p3, subPath, p5) => {
|
|
2802
|
+
let newSubPath = subPath || '';
|
|
2803
|
+
if (subPath && subPath.includes(fromFeatureComponentName)) {
|
|
2804
|
+
newSubPath = subPath.replace(fromFeatureComponentName, toFeatureComponentName);
|
|
2805
|
+
}
|
|
2806
|
+
return `${p1}${toFeatureComponentName}${p3}${newAliasPath}${newSubPath}${p5}`;
|
|
2807
|
+
});
|
|
2808
|
+
changed = true;
|
|
2809
|
+
} else if (content.includes(oldAliasPath)) {
|
|
2810
|
+
// Fallback for path only replacement
|
|
2811
|
+
content = content.replace(new RegExp(oldAliasPath.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g'), newAliasPath);
|
|
2812
|
+
changed = true;
|
|
2780
2813
|
}
|
|
2781
2814
|
} else {
|
|
2782
|
-
const oldRelativeDir = getRelativeImportPath(
|
|
2815
|
+
const oldRelativeDir = getRelativeImportPath(toRoutePath, fromFeatureDirPath);
|
|
2783
2816
|
const newRelativeDir = getRelativeImportPath(toRoutePath, toFeatureDirPath);
|
|
2784
|
-
const ext = config.naming.featureExtension === '.astro' ? '.astro' : '';
|
|
2785
2817
|
|
|
2786
|
-
|
|
2787
|
-
const
|
|
2818
|
+
// Flexible regex for relative imports
|
|
2819
|
+
const relImportRegex = new RegExp(`(import\\s+)(${fromFeatureComponentName})(\\s+from\\s+['"])${oldRelativeDir}(/[^'"]+)?(['"])`, 'g');
|
|
2788
2820
|
|
|
2789
|
-
if (
|
|
2790
|
-
|
|
2821
|
+
if (relImportRegex.test(content)) {
|
|
2822
|
+
content = content.replace(relImportRegex, (match, p1, p2, p3, subPath, p5) => {
|
|
2823
|
+
let newSubPath = subPath || '';
|
|
2824
|
+
if (subPath && subPath.includes(fromFeatureComponentName)) {
|
|
2825
|
+
newSubPath = subPath.replace(fromFeatureComponentName, toFeatureComponentName);
|
|
2826
|
+
}
|
|
2827
|
+
return `${p1}${toFeatureComponentName}${p3}${newRelativeDir}${newSubPath}${p5}`;
|
|
2828
|
+
});
|
|
2829
|
+
changed = true;
|
|
2791
2830
|
}
|
|
2792
2831
|
}
|
|
2832
|
+
|
|
2833
|
+
if (changed) {
|
|
2834
|
+
await writeFile(toRoutePath, content, 'utf-8');
|
|
2835
|
+
// Update hash in state after changes
|
|
2836
|
+
state.files[normalizedToRouteRelative].hash = calculateHash(content, config.hashing?.normalization);
|
|
2837
|
+
}
|
|
2793
2838
|
}
|
|
2794
2839
|
|
|
2795
2840
|
if (!isRouteOnly && normalizedFromFeature && normalizedToFeature && normalizedFromFeature !== normalizedToFeature) {
|
|
@@ -2860,7 +2905,6 @@ async function scanAndReplaceImports(config, state, fromInfo, toInfo, options) {
|
|
|
2860
2905
|
const { toFeaturePath, toComponentName } = toInfo;
|
|
2861
2906
|
|
|
2862
2907
|
const allFiles = new Set();
|
|
2863
|
-
const { scanDirectory, calculateHash } = await Promise.resolve().then(function () { return filesystem; });
|
|
2864
2908
|
await scanDirectory(process.cwd(), allFiles);
|
|
2865
2909
|
|
|
2866
2910
|
const featuresRoot = resolvePath(config, 'features');
|
|
@@ -3001,7 +3045,6 @@ async function moveDirectory(fromPath, toPath, state, config, options = {}) {
|
|
|
3001
3045
|
if (hasChanged) {
|
|
3002
3046
|
await writeFile(toEntryPath, content, 'utf-8');
|
|
3003
3047
|
// Re-calculate hash after content update
|
|
3004
|
-
const { calculateHash } = await Promise.resolve().then(function () { return filesystem; });
|
|
3005
3048
|
const updatedHash = calculateHash(content, config.hashing?.normalization);
|
|
3006
3049
|
|
|
3007
3050
|
const normalizedToRelative = path.relative(process.cwd(), toEntryPath).replace(/\\/g, '/');
|
|
@@ -3034,6 +3077,39 @@ async function moveDirectory(fromPath, toPath, state, config, options = {}) {
|
|
|
3034
3077
|
}
|
|
3035
3078
|
}
|
|
3036
3079
|
|
|
3080
|
+
async function updateImportsInFile(filePath, oldFilePath, newFilePath) {
|
|
3081
|
+
if (!existsSync(filePath)) return;
|
|
3082
|
+
|
|
3083
|
+
let content = await readFile(filePath, 'utf-8');
|
|
3084
|
+
const oldDir = path.dirname(oldFilePath);
|
|
3085
|
+
const newDir = path.dirname(newFilePath);
|
|
3086
|
+
|
|
3087
|
+
if (oldDir === newDir) return;
|
|
3088
|
+
|
|
3089
|
+
// Find all relative imports
|
|
3090
|
+
const relativeImportRegex = /from\s+['"](\.\.?\/[^'"]+)['"]/g;
|
|
3091
|
+
let match;
|
|
3092
|
+
const replacements = [];
|
|
3093
|
+
|
|
3094
|
+
while ((match = relativeImportRegex.exec(content)) !== null) {
|
|
3095
|
+
const relativePath = match[1];
|
|
3096
|
+
const absoluteTarget = path.resolve(oldDir, relativePath);
|
|
3097
|
+
const newRelativePath = getRelativeImportPath(newFilePath, absoluteTarget);
|
|
3098
|
+
|
|
3099
|
+
replacements.push({
|
|
3100
|
+
full: match[0],
|
|
3101
|
+
oldRel: relativePath,
|
|
3102
|
+
newRel: newRelativePath
|
|
3103
|
+
});
|
|
3104
|
+
}
|
|
3105
|
+
|
|
3106
|
+
for (const repl of replacements) {
|
|
3107
|
+
content = content.replace(repl.full, `from '${repl.newRel}'`);
|
|
3108
|
+
}
|
|
3109
|
+
|
|
3110
|
+
await writeFile(filePath, content, 'utf-8');
|
|
3111
|
+
}
|
|
3112
|
+
|
|
3037
3113
|
async function createComponentCommand(componentName, options) {
|
|
3038
3114
|
try {
|
|
3039
3115
|
const config = await loadConfig();
|
|
@@ -4286,6 +4362,11 @@ program
|
|
|
4286
4362
|
.option('--index', 'Create index.ts')
|
|
4287
4363
|
.option('--no-sub-components-dir', 'Skip creating sub-components directory')
|
|
4288
4364
|
.option('--no-scripts-dir', 'Skip creating scripts directory')
|
|
4365
|
+
.option('--prop <key=value>', 'Layout property', (val, memo) => {
|
|
4366
|
+
const [key, ...rest] = val.split('=');
|
|
4367
|
+
memo[key] = rest.join('=');
|
|
4368
|
+
return memo;
|
|
4369
|
+
}, {})
|
|
4289
4370
|
.option('--dry-run', 'Show what would be created without creating')
|
|
4290
4371
|
.option('--force', 'Overwrite existing files')
|
|
4291
4372
|
.action(addSectionCommand);
|
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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|