Skip to content

Commit 37504b7

Browse files
committed
feat: enhance component injection logic and add label sanitization for component names
1 parent 27c2ed2 commit 37504b7

File tree

4 files changed

+62
-28
lines changed

4 files changed

+62
-28
lines changed

adminforth/commands/createCustomComponent/configUpdater.js

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ export async function injectGlobalComponent(indexFilePath, injectionType, compon
294294
});
295295

296296
let updated = false;
297-
297+
console.log(JSON.stringify(injectionType));
298298
recast.visit(ast, {
299299
visitNewExpression(path) {
300300
if (
@@ -332,27 +332,41 @@ export async function injectGlobalComponent(indexFilePath, injectionType, compon
332332

333333
const injectionsValue = globalInjections.value;
334334
if (!n.ObjectExpression.check(injectionsValue)) return false;
335-
335+
console.log(JSON.stringify(injectionType));
336336
let injectionProp = injectionsValue.properties.find(
337337
p => n.ObjectProperty.check(p) && n.Identifier.check(p.key) && p.key.name === injectionType
338338
);
339-
340339
if (injectionProp) {
341-
const injectionArray = injectionProp.value.elements;
342-
injectionArray.push(b.stringLiteral(componentPath));
343-
console.log(chalk.dim(`Added '${componentPath}' to '${injectionType}'`));
344-
} else {
340+
const currentValue = injectionProp.value;
341+
342+
if (n.ArrayExpression.check(currentValue)) {
343+
currentValue.elements.push(b.stringLiteral(componentPath));
344+
console.log(chalk.dim(`Added '${componentPath}' to existing array in '${injectionType}'`));
345+
} else if (n.StringLiteral.check(currentValue)) {
346+
// Преобразовать строку в массив
347+
injectionProp.value = b.arrayExpression([
348+
b.stringLiteral(currentValue.value),
349+
b.stringLiteral(componentPath)
350+
]);
351+
console.log(chalk.dim(`Converted '${injectionType}' from string to array and added '${componentPath}'`));
352+
} else {
353+
throw new Error(`Unsupported value type for '${injectionType}'. Must be string or array.`);
354+
}
355+
} else {
345356
injectionsValue.properties.push(
346-
b.objectProperty(b.identifier(injectionType), b.arrayExpression([b.stringLiteral(componentPath)]))
357+
b.objectProperty(
358+
b.identifier(injectionType),
359+
b.arrayExpression([b.stringLiteral(componentPath)])
360+
)
347361
);
348-
console.log(chalk.dim(`Added '${injectionType}': [${componentPath}]`));
362+
console.log(chalk.dim(`Added new array for '${injectionType}' with '${componentPath}'`));
363+
}
364+
365+
updated = true;
366+
this.abort();
349367
}
350-
351-
updated = true;
352-
this.abort();
353-
}
354-
return false;
355-
}
368+
return false;
369+
}
356370
});
357371

358372
if (!updated) {

adminforth/commands/createCustomComponent/main.js

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@ import { loadAdminForthConfig } from './configLoader.js'; // Helper to load conf
55
import { generateComponentFile, generateLoginOrGlobalComponentFile, generateCrudInjectionComponent } from './fileGenerator.js'; // Helper to create the .vue file
66
import { updateResourceConfig, injectLoginComponent, injectGlobalComponent, updateCrudInjectionConfig } from './configUpdater.js'; // Helper to modify resource .ts file
77

8+
function sanitizeLabel(input){
9+
return input
10+
.replace(/[^a-zA-Z0-9\s]/g, '')
11+
.split(' ')
12+
.map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()) // Переводим первую букву в верхний регистр
13+
.join('');
14+
}
15+
816
export default async function createComponent(args) {
917
console.log('This command will help you to generate boilerplate for component.\n');
1018

@@ -88,8 +96,8 @@ async function handleFieldComponentCreation(config, resources) {
8896
console.log(chalk.dim(`One-line alternative: |adminforth component fields.${fieldType}.${resourceId}.${columnName}|`));
8997

9098

91-
const safeResourceLabel = selectedResource.label.replace(/[^a-zA-Z0-9]/g, '');
92-
const safeColumnLabel = selectedColumn.label.replace(/[^a-zA-Z0-9]/g, '');
99+
const safeResourceLabel = sanitizeLabel(selectedResource.label)
100+
const safeColumnLabel = sanitizeLabel(selectedColumn.label)
93101
const componentFileName = `${safeResourceLabel}${safeColumnLabel}${fieldType.charAt(0).toUpperCase() + fieldType.slice(1)}.vue`; // e.g., UserEmailShow.vue
94102
const componentPathForConfig = `@@/${componentFileName}`; // Path relative to custom dir for config
95103

@@ -106,7 +114,10 @@ async function handleFieldComponentCreation(config, resources) {
106114

107115
await updateResourceConfig(selectedResource.resourceId, columnName, fieldType, componentPathForConfig);
108116
console.log(chalk.green(`\n✅ Successfully created component ${componentPathForConfig} and updated configuration.`));
109-
console.log(`\nYou can now open the component in your IDE: ${absoluteComponentPath}`);
117+
console.log(
118+
chalk.bold.greenBright('You can now open the component in your IDE:'),
119+
chalk.underline.cyanBright(absoluteComponentPath)
120+
);
110121
}
111122
process.exit(0);
112123
}catch (error) {
@@ -168,7 +179,7 @@ async function handleCrudPageInjectionCreation(config, resources) {
168179
],
169180
});
170181

171-
const safeResourceLabel = selectedResource.label.replace(/[^a-zA-Z0-9]/g, '');
182+
const safeResourceLabel = sanitizeLabel(selectedResource.label)
172183
const componentFileName = `${safeResourceLabel}${crudType.charAt(0).toUpperCase() + crudType.slice(1)}${injectionPosition.charAt(0).toUpperCase() + injectionPosition.slice(1)}.vue`;
173184
const componentPathForConfig = `@@/${componentFileName}`;
174185

@@ -192,7 +203,10 @@ async function handleCrudPageInjectionCreation(config, resources) {
192203
);
193204

194205
console.log(chalk.green(`\n✅ Successfully created component ${componentPathForConfig} and updated configuration.`));
195-
console.log(`\nYou can now open the component in your IDE: ${absoluteComponentPath}`);
206+
console.log(
207+
chalk.bold.greenBright('You can now open the component in your IDE:'),
208+
chalk.underline.cyanBright(absoluteComponentPath)
209+
);
196210
}
197211
process.exit(0);
198212
} catch (error) {
@@ -224,7 +238,7 @@ async function handleLoginPageInjectionCreation(config) {
224238

225239

226240
try {
227-
const safeName = reason.replace(/[^a-zA-Z0-9]/g, '');
241+
const safeName = sanitizeLabel(reason)
228242
const componentFileName = `CustomLogin${safeName}.vue`;
229243

230244
const context = { reason };
@@ -240,8 +254,11 @@ async function handleLoginPageInjectionCreation(config) {
240254
console.log(chalk.dim(`Injecting component: ${configFilePath}, ${componentFileName}`));
241255
await injectLoginComponent(configFilePath, `@@/${componentFileName}`);
242256

243-
console.log(chalk.green(`\n✅ Successfully created component ${componentPathForConfig} and updated configuration.`));
244-
console.log(`\nYou can now open the component in your IDE: ${absoluteComponentPath}`);
257+
console.log(chalk.green(`\n✅ Successfully created component ${componentFileName} and updated configuration.`));
258+
console.log(
259+
chalk.bold.greenBright('You can now open the component in your IDE:'),
260+
chalk.underline.cyanBright(absoluteComponentPath)
261+
);
245262
}
246263
process.exit(0);
247264
}catch (error) {
@@ -277,7 +294,7 @@ async function handleGlobalInjectionCreation(config) {
277294
console.log(chalk.grey(`Selected ❯ 🌍 Global page injections ❯ ${injectionType}${reason}`));
278295

279296
try {
280-
const safeName = reason.replace(/[^a-zA-Z0-9]/g, '');
297+
const safeName = sanitizeLabel(reason)
281298
const componentFileName = `CustomGlobal${safeName}.vue`;
282299

283300
const context = { reason };
@@ -298,7 +315,10 @@ async function handleGlobalInjectionCreation(config) {
298315
await injectGlobalComponent(configFilePath, injectionType, `@@/${componentFileName}`);
299316

300317
console.log(chalk.green(`\n✅ Successfully created component ${componentFileName} and updated configuration.`));
301-
console.log(`\nYou can now open the component in your IDE: ${absoluteComponentPath}`);
318+
console.log(
319+
chalk.bold.greenBright('You can now open the component in your IDE:'),
320+
chalk.underline.cyanBright(absoluteComponentPath)
321+
);
302322
}
303323
process.exit(0);
304324
} catch (error) {
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<template>
2-
<div class="flex items-center p-4 md:p-5 border-t border-gray-200 rounded-b dark:border-gray-600">
2+
<div class="flex items-center justify-center text-gray-900 dark:text-gray-400 p-4 md:p-5 border-t border-gray-200 rounded-b dark:border-gray-600">
33
{{reason}}
44
</div>
55
</template>
@@ -8,4 +8,4 @@
88
defineProps({
99
reason: String
1010
});
11-
</script>
11+
</script>

adminforth/commands/createCustomComponent/templates/global/sidebar.vue.hbs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<template>
2-
<div class="text-center text-gray-500 text-sm mt-4">
2+
<div class="display-flex justify-center text-lightSidebarIcons text-center dark:text-darkSidebarIcons">
33
{{reason}}
44
</div>
55
</template>

0 commit comments

Comments
 (0)