Skip to content

Commit eb01fe7

Browse files
committed
fix: refactor injection validation and sorting logic for improved maintainability
1 parent 9ecd737 commit eb01fe7

File tree

1 file changed

+68
-20
lines changed

1 file changed

+68
-20
lines changed

adminforth/modules/configValidator.ts

Lines changed: 68 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ export default class ConfigValidator implements IConfigValidator {
3434

3535
customComponentsDir: string | undefined;
3636

37+
private static readonly LOGIN_INJECTION_KEYS = ['underInputs', 'underLoginButton', 'panelHeader'];
38+
private static readonly GLOBAL_INJECTION_KEYS = ['userMenu', 'header', 'sidebar', 'sidebarTop', 'everyPageBottom'];
39+
private static readonly PAGE_INJECTION_KEYS = ['beforeBreadcrumbs', 'beforeActionButtons', 'afterBreadcrumbs', 'bottom', 'threeDotsDropdownItems', 'customActionIcons'];
40+
3741
constructor(private adminforth: IAdminForth, private inputConfig: AdminForthInputConfig) {
3842
this.adminforth = adminforth;
3943
this.inputConfig = inputConfig;
@@ -58,7 +62,6 @@ export default class ConfigValidator implements IConfigValidator {
5862
injections.forEach((target, i) => {
5963
injections[i] = this.validateComponent(target, errors);
6064
});
61-
// sort by injection.meta?.afOrder || 0 desc
6265
return injections;
6366
}
6467

@@ -120,13 +123,12 @@ export default class ConfigValidator implements IConfigValidator {
120123
};
121124

122125
if (this.inputConfig.customization?.loginPageInjections) {
123-
const ALLOWED_LOGIN_INJECTIONS = ['underInputs', 'underLoginButton', 'panelHeader']
124126
Object.keys(this.inputConfig.customization.loginPageInjections).forEach((injection) => {
125-
if (ALLOWED_LOGIN_INJECTIONS.includes(injection)) {
127+
if (ConfigValidator.LOGIN_INJECTION_KEYS.includes(injection)) {
126128
loginPageInjections[injection] = this.validateAndListifyInjectionNew(this.inputConfig.customization.loginPageInjections, injection, errors);
127129
} else {
128-
const similar = suggestIfTypo(ALLOWED_LOGIN_INJECTIONS, injection);
129-
errors.push(`Login page injection key "${injection}" is not allowed. Allowed keys are ${ALLOWED_LOGIN_INJECTIONS.join(', ')}. ${similar ? `Did you mean "${similar}"?` : ''}`);
130+
const similar = suggestIfTypo(ConfigValidator.LOGIN_INJECTION_KEYS, injection);
131+
errors.push(`Login page injection key "${injection}" is not allowed. Allowed keys are ${ConfigValidator.LOGIN_INJECTION_KEYS.join(', ')}. ${similar ? `Did you mean "${similar}"?` : ''}`);
130132
}
131133
});
132134
}
@@ -139,13 +141,12 @@ export default class ConfigValidator implements IConfigValidator {
139141
};
140142

141143
if (this.inputConfig.customization?.globalInjections) {
142-
const ALLOWED_GLOBAL_INJECTIONS = ['userMenu', 'header', 'sidebar', 'sidebarTop', 'everyPageBottom'];
143144
Object.keys(this.inputConfig.customization.globalInjections).forEach((injection) => {
144-
if (ALLOWED_GLOBAL_INJECTIONS.includes(injection)) {
145+
if (ConfigValidator.GLOBAL_INJECTION_KEYS.includes(injection)) {
145146
globalInjections[injection] = this.validateAndListifyInjectionNew(this.inputConfig.customization.globalInjections, injection, errors);
146147
} else {
147-
const similar = suggestIfTypo(ALLOWED_GLOBAL_INJECTIONS, injection);
148-
errors.push(`Global injection key "${injection}" is not allowed. Allowed keys are ${ALLOWED_GLOBAL_INJECTIONS.join(', ')}. ${similar ? `Did you mean "${similar}"?` : ''}`);
148+
const similar = suggestIfTypo(ConfigValidator.GLOBAL_INJECTION_KEYS, injection);
149+
errors.push(`Global injection key "${injection}" is not allowed. Allowed keys are ${ConfigValidator.GLOBAL_INJECTION_KEYS.join(', ')}. ${similar ? `Did you mean "${similar}"?` : ''}`);
149150
}
150151
});
151152
}
@@ -807,7 +808,6 @@ export default class ConfigValidator implements IConfigValidator {
807808
});
808809

809810
// if pageInjection is a string, make array with one element. Also check file exists
810-
const possibleInjections = ['beforeBreadcrumbs', 'beforeActionButtons', 'afterBreadcrumbs', 'bottom', 'threeDotsDropdownItems', 'customActionIcons'];
811811
const possiblePages = ['list', 'show', 'create', 'edit'];
812812

813813
if (options.pageInjections) {
@@ -819,11 +819,11 @@ export default class ConfigValidator implements IConfigValidator {
819819
}
820820

821821
Object.entries(value).map(([injection, target]) => {
822-
if (possibleInjections.includes(injection)) {
823-
this.validateAndListifyInjection(options.pageInjections[key], injection, errors);
822+
if (ConfigValidator.PAGE_INJECTION_KEYS.includes(injection)) {
823+
options.pageInjections[key][injection] = this.validateAndListifyInjectionNew(options.pageInjections[key], injection, errors);
824824
} else {
825-
const similar = suggestIfTypo(possibleInjections, injection);
826-
errors.push(`Resource "${res.resourceId}" has invalid pageInjection key "${injection}", Supported keys are ${possibleInjections.join(', ')} ${similar ? `Did you mean "${similar}"?` : ''}`);
825+
const similar = suggestIfTypo(ConfigValidator.PAGE_INJECTION_KEYS, injection);
826+
errors.push(`Resource "${res.resourceId}" has invalid pageInjection key "${injection}", Supported keys are ${ConfigValidator.PAGE_INJECTION_KEYS.join(', ')} ${similar ? `Did you mean "${similar}"?` : ''}`);
827827
}
828828
});
829829

@@ -898,14 +898,62 @@ export default class ConfigValidator implements IConfigValidator {
898898
}
899899

900900
validateAfterPluginsActivation() {
901-
const ALLOWED_LOGIN_INJECTIONS = ['underInputs', 'underLoginButton', 'panelHeader']
902-
Object.entries(this.adminforth.config.customization).map(([key, value]) => {
903-
Object.entries(value).map(([injection, target]) => {
904-
if (ALLOWED_LOGIN_INJECTIONS.includes(injection)) {
905-
(target as Array<AdminForthComponentDeclarationFull>).sort((a, b) => (b.meta?.afOrder ?? 0) - (a.meta?.afOrder ?? 0));
901+
// Sort all page injections throughout the config by afOrder
902+
this.sortAllPageInjections();
903+
}
904+
905+
private sortAllPageInjections(): void {
906+
const config = this.adminforth.config;
907+
908+
// Sort login page injections
909+
if (config.customization?.loginPageInjections) {
910+
const loginInjections = config.customization.loginPageInjections;
911+
ConfigValidator.LOGIN_INJECTION_KEYS.forEach(key => {
912+
if (loginInjections[key]) {
913+
this.sortInjectionArray(loginInjections[key]);
906914
}
907915
});
908-
})
916+
}
917+
918+
// Sort global injections
919+
if (config.customization?.globalInjections) {
920+
const globalInjections = config.customization.globalInjections;
921+
ConfigValidator.GLOBAL_INJECTION_KEYS.forEach(key => {
922+
if (globalInjections[key]) {
923+
this.sortInjectionArray(globalInjections[key]);
924+
}
925+
});
926+
}
927+
928+
// Sort resource page injections
929+
if (config.resources) {
930+
config.resources.forEach(resource => {
931+
if (resource.options?.pageInjections) {
932+
const pageInjections = resource.options.pageInjections;
933+
934+
// For each page type (list, show, create, edit)
935+
Object.keys(pageInjections).forEach(pageType => {
936+
const pageTypeInjections = pageInjections[pageType];
937+
if (pageTypeInjections) {
938+
// For each injection point within the page
939+
ConfigValidator.PAGE_INJECTION_KEYS.forEach(injectionKey => {
940+
if (pageTypeInjections[injectionKey]) {
941+
this.sortInjectionArray(pageTypeInjections[injectionKey]);
942+
}
943+
});
944+
}
945+
});
946+
}
947+
});
948+
}
949+
}
950+
951+
private sortInjectionArray(injections: any): void {
952+
if (Array.isArray(injections)) {
953+
injections.sort((a: AdminForthComponentDeclarationFull, b: AdminForthComponentDeclarationFull) =>
954+
(b.meta?.afOrder ?? 0) - (a.meta?.afOrder ?? 0)
955+
);
956+
}
909957
}
910958

911959
validateConfig() {

0 commit comments

Comments
 (0)