Minor reduce perf optimizations (#170922)

## Summary

Cherry picked from https://github.com/elastic/kibana/pull/168812 the
changes from `core` packages and the `security` and `spaces` plugins

---------

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Pierre Gayvallet 2023-11-10 15:45:51 +01:00 committed by GitHub
parent c43e6997af
commit 2b60d3a6ec
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 83 additions and 83 deletions

View file

@ -98,13 +98,14 @@ const validateAggregationContainer = (
) => { ) => {
return Object.entries(container).reduce<estypes.AggregationsAggregationContainer>( return Object.entries(container).reduce<estypes.AggregationsAggregationContainer>(
(memo, [aggName, aggregation]) => { (memo, [aggName, aggregation]) => {
if (aggregationKeys.includes(aggName)) { if (!aggregationKeys.includes(aggName)) {
return memo; (memo as Record<string, unknown>)[aggName] = validateAggregationType(
aggName,
aggregation,
childContext(context, aggName)
);
} }
return { return memo;
...memo,
[aggName]: validateAggregationType(aggName, aggregation, childContext(context, aggName)),
};
}, },
{} {}
); );

View file

@ -159,10 +159,7 @@ export class ObjectType<P extends Props = any> extends Type<ObjectResultType<P>>
...newProps, ...newProps,
}).reduce((memo, [key, value]) => { }).reduce((memo, [key, value]) => {
if (value !== null && value !== undefined) { if (value !== null && value !== undefined) {
return { (memo as Record<string, unknown>)[key] = value;
...memo,
[key]: value,
};
} }
return memo; return memo;
}, {} as ExtendedProps<P, NP>); }, {} as ExtendedProps<P, NP>);

View file

@ -18,17 +18,12 @@ export const unique = <T>(arr: T[] = []): T[] => [...new Set(arr)];
const merge = (a: any, b: any): { [k: string]: any } => const merge = (a: any, b: any): { [k: string]: any } =>
unique([...Object.keys(a), ...Object.keys(b)]).reduce((acc, key) => { unique([...Object.keys(a), ...Object.keys(b)]).reduce((acc, key) => {
if (isObject(a[key]) && isObject(b[key]) && !Array.isArray(a[key]) && !Array.isArray(b[key])) { if (isObject(a[key]) && isObject(b[key]) && !Array.isArray(a[key]) && !Array.isArray(b[key])) {
return { acc[key] = merge(a[key], b[key]);
...acc, } else {
[key]: merge(a[key], b[key]), acc[key] = b[key] === undefined ? a[key] : b[key];
};
} }
return acc;
return { }, {} as { [k: string]: any });
...acc,
[key]: b[key] === undefined ? a[key] : b[key],
};
}, {});
export const mergeAll = (...sources: any[]) => export const mergeAll = (...sources: any[]) =>
sources.filter(isObject).reduce((acc, source) => merge(acc, source)); sources.filter(isObject).reduce((acc, source) => merge(acc, source));

View file

@ -148,13 +148,10 @@ export async function getAllTranslations(): Promise<{ [key: string]: Translation
const locales = getRegisteredLocales(); const locales = getRegisteredLocales();
const translations = await Promise.all(locales.map(getTranslationsByLocale)); const translations = await Promise.all(locales.map(getTranslationsByLocale));
return locales.reduce( return locales.reduce((acc, locale, index) => {
(acc, locale, index) => ({ acc[locale] = translations[index];
...acc, return acc;
[locale]: translations[index], }, {} as { [key: string]: Translation });
}),
{}
);
} }
/** /**

View file

@ -58,5 +58,8 @@ export async function asyncMapWithLimit<T1, T2>(
return results return results
.sort(([a], [b]) => a - b) .sort(([a], [b]) => a - b)
.reduce((acc: T2[], [, result]) => acc.concat(result), []); .reduce((acc: T2[], [, result]) => {
acc.push(...result);
return acc;
}, []);
} }

View file

@ -178,7 +178,10 @@ export function getDescriptor(node: ts.Node, program: ts.Program): Descriptor |
const constraints = getConstraints(constraint, program); const constraints = getConstraints(constraint, program);
const constraintsArray = Array.isArray(constraints) ? constraints : [constraints]; const constraintsArray = Array.isArray(constraints) ? constraints : [constraints];
if (typeof constraintsArray[0] === 'string') { if (typeof constraintsArray[0] === 'string') {
return constraintsArray.reduce((acc, c) => ({ ...acc, [c]: descriptor }), {}); return constraintsArray.reduce((acc, c) => {
(acc as Record<string, unknown>)[c] = descriptor;
return acc;
}, {});
} }
} }
return { '@@INDEX@@': descriptor }; return { '@@INDEX@@': descriptor };

View file

@ -144,13 +144,11 @@ export function checkPrivilegesFactory(
const indexPrivileges = Object.entries(hasPrivilegesResponse.index ?? {}).reduce< const indexPrivileges = Object.entries(hasPrivilegesResponse.index ?? {}).reduce<
CheckPrivilegesResponse['privileges']['elasticsearch']['index'] CheckPrivilegesResponse['privileges']['elasticsearch']['index']
>((acc, [index, indexResponse]) => { >((acc, [index, indexResponse]) => {
return { acc[index] = Object.entries(indexResponse).map(([privilege, authorized]) => ({
...acc, privilege,
[index]: Object.entries(indexResponse).map(([privilege, authorized]) => ({ authorized,
privilege, }));
authorized, return acc;
})),
};
}, {}); }, {});
// we need to filter out the non requested privileges from the response // we need to filter out the non requested privileges from the response

View file

@ -37,10 +37,8 @@ export function disableUICapabilitiesFactory(
const elasticsearchFeatureMap = elasticsearchFeatures.reduce< const elasticsearchFeatureMap = elasticsearchFeatures.reduce<
Record<string, RecursiveReadonlyArray<FeatureElasticsearchPrivileges>> Record<string, RecursiveReadonlyArray<FeatureElasticsearchPrivileges>>
>((acc, esFeature) => { >((acc, esFeature) => {
return { acc[esFeature.id] = esFeature.privileges;
...acc, return acc;
[esFeature.id]: esFeature.privileges,
};
}, {}); }, {});
const allRequiredClusterPrivileges = Array.from( const allRequiredClusterPrivileges = Array.from(
@ -59,11 +57,9 @@ export function disableUICapabilitiesFactory(
return { return {
...acc, ...acc,
...Object.entries(p.requiredIndexPrivileges!).reduce((acc2, [indexName, privileges]) => { ...Object.entries(p.requiredIndexPrivileges!).reduce((acc2, [indexName, privileges]) => {
return { acc2[indexName] = [...(acc[indexName] ?? []), ...privileges];
...acc2, return acc2;
[indexName]: [...(acc[indexName] ?? []), ...privileges], }, {} as Record<string, string[]>),
};
}, {}),
}; };
}, {}); }, {});
@ -157,14 +153,16 @@ export function disableUICapabilitiesFactory(
} }
const uiActions = Object.entries(uiCapabilities).reduce<string[]>( const uiActions = Object.entries(uiCapabilities).reduce<string[]>(
(acc, [featureId, featureUICapabilities]) => [ (acc, [featureId, featureUICapabilities]) => {
...acc, acc.push(
...flatten( ...flatten(
Object.entries(featureUICapabilities).map(([uiCapability, value]) => { Object.entries(featureUICapabilities).map(([uiCapability, value]) => {
return getActionsForFeatureCapability(featureId, uiCapability, value); return getActionsForFeatureCapability(featureId, uiCapability, value);
}) })
), )
], );
return acc;
},
[] []
); );

View file

@ -18,7 +18,8 @@ export class FeaturePrivilegeManagementBuilder extends BaseFeaturePrivilegeBuild
} }
return Object.entries(managementSections).reduce((acc, [sectionId, items]) => { return Object.entries(managementSections).reduce((acc, [sectionId, items]) => {
return [...acc, ...items.map((item) => this.actions.ui.get('management', sectionId, item))]; acc.push(...items.map((item) => this.actions.ui.get('management', sectionId, item)));
return acc;
}, [] as string[]); }, [] as string[]);
} }
} }

View file

@ -37,8 +37,8 @@ export function privilegesFactory(
(feature) => !feature.excludeFromBasePrivileges (feature) => !feature.excludeFromBasePrivileges
); );
let allActions: string[] = []; const allActionsSet = new Set<string>();
let readActions: string[] = []; const readActionsSet = new Set<string>();
basePrivilegeFeatures.forEach((feature) => { basePrivilegeFeatures.forEach((feature) => {
for (const { privilegeId, privilege } of featuresService.featurePrivilegeIterator(feature, { for (const { privilegeId, privilege } of featuresService.featurePrivilegeIterator(feature, {
@ -47,15 +47,17 @@ export function privilegesFactory(
predicate: (pId, featurePrivilege) => !featurePrivilege.excludeFromBasePrivileges, predicate: (pId, featurePrivilege) => !featurePrivilege.excludeFromBasePrivileges,
})) { })) {
const privilegeActions = featurePrivilegeBuilder.getActions(privilege, feature); const privilegeActions = featurePrivilegeBuilder.getActions(privilege, feature);
allActions = [...allActions, ...privilegeActions]; privilegeActions.forEach((action) => {
if (privilegeId === 'read') { allActionsSet.add(action);
readActions = [...readActions, ...privilegeActions]; if (privilegeId === 'read') {
} readActionsSet.add(action);
}
});
} }
}); });
allActions = uniq(allActions); const allActions = [...allActionsSet];
readActions = uniq(readActions); const readActions = [...readActionsSet];
const featurePrivileges: Record<string, Record<string, string[]>> = {}; const featurePrivileges: Record<string, Record<string, string[]>> = {};
for (const feature of features) { for (const feature of features) {

View file

@ -38,12 +38,10 @@ export function defineGetPrivilegesRoutes({ router, authz }: RouteDefinitionPara
space: Object.keys(privileges.space), space: Object.keys(privileges.space),
features: Object.entries(privileges.features).reduce( features: Object.entries(privileges.features).reduce(
(acc, [featureId, featurePrivileges]) => { (acc, [featureId, featurePrivileges]) => {
return { acc[featureId] = Object.keys(featurePrivileges);
...acc, return acc;
[featureId]: Object.keys(featurePrivileges),
};
}, },
{} {} as Record<string, string[]>
), ),
reserved: Object.keys(privileges.reserved), reserved: Object.keys(privileges.reserved),
}; };

View file

@ -104,7 +104,10 @@ export async function ensureAuthorized<T extends string>(
// Neither fully nor partially authorized. Bail with error. // Neither fully nor partially authorized. Bail with error.
const uniqueUnauthorizedPrivileges = [...missingPrivileges.entries()].reduce( const uniqueUnauthorizedPrivileges = [...missingPrivileges.entries()].reduce(
(acc, [, privilegeSet]) => new Set([...acc, ...privilegeSet]), (acc, [, privilegeSet]) => {
privilegeSet.forEach((entry) => acc.add(entry));
return acc;
},
new Set<string>() new Set<string>()
); );
const targetTypesAndActions = [...uniqueUnauthorizedPrivileges] const targetTypesAndActions = [...uniqueUnauthorizedPrivileges]

View file

@ -81,10 +81,13 @@ export class SecureSpacesClientWrapper implements ISpacesClient {
// Collect all privileges which need to be checked // Collect all privileges which need to be checked
const allPrivileges = Object.entries(PURPOSE_PRIVILEGE_MAP).reduce( const allPrivileges = Object.entries(PURPOSE_PRIVILEGE_MAP).reduce(
(acc, [getSpacesPurpose, privilegeFactory]) => (acc, [getSpacesPurpose, privilegeFactory]) => {
!includeAuthorizedPurposes && getSpacesPurpose !== purpose if (!includeAuthorizedPurposes && getSpacesPurpose !== purpose) {
? acc return acc;
: { ...acc, [getSpacesPurpose]: privilegeFactory(this.authorization) }, }
acc[getSpacesPurpose as GetAllSpacesPurpose] = privilegeFactory(this.authorization);
return acc;
},
{} as Record<GetAllSpacesPurpose, string[]> {} as Record<GetAllSpacesPurpose, string[]>
); );
@ -117,7 +120,8 @@ export class SecureSpacesClientWrapper implements ISpacesClient {
const requiredActions = privilegeFactory(this.authorization); const requiredActions = privilegeFactory(this.authorization);
const hasAllRequired = checkHasAllRequired(space, requiredActions); const hasAllRequired = checkHasAllRequired(space, requiredActions);
hasAnyAuthorization = hasAnyAuthorization || hasAllRequired; hasAnyAuthorization = hasAnyAuthorization || hasAllRequired;
return { ...acc, [purposeKey]: hasAllRequired }; acc[purposeKey as GetAllSpacesPurpose] = hasAllRequired;
return acc;
}, },
{} as Record<GetAllSpacesPurpose, boolean> {} as Record<GetAllSpacesPurpose, boolean>
); );

View file

@ -160,12 +160,7 @@ export function registerSecurityUsageCollector({ usageCollection, config, licens
const loginSelectorEnabled = config.authc.selector.enabled; const loginSelectorEnabled = config.authc.selector.enabled;
const authProviderCount = config.authc.sortedProviders.length; const authProviderCount = config.authc.sortedProviders.length;
const enabledAuthProviders = [ const enabledAuthProviders = [
...new Set( ...new Set(config.authc.sortedProviders.map((provider) => provider.type)),
config.authc.sortedProviders.reduce(
(acc, provider) => [...acc, provider.type],
[] as string[]
)
),
]; ];
const accessAgreementEnabled = const accessAgreementEnabled =
allowAccessAgreement && allowAccessAgreement &&

View file

@ -63,14 +63,19 @@ function toggleDisabledFeatures(
) { ) {
const disabledFeatureKeys = activeSpace.disabledFeatures; const disabledFeatureKeys = activeSpace.disabledFeatures;
const [enabledFeatures, disabledFeatures] = features.reduce( const { enabledFeatures, disabledFeatures } = features.reduce(
(acc, feature) => { (acc, feature) => {
if (disabledFeatureKeys.includes(feature.id)) { if (disabledFeatureKeys.includes(feature.id)) {
return [acc[0], [...acc[1], feature]]; acc.disabledFeatures.push(feature);
} else {
acc.enabledFeatures.push(feature);
} }
return [[...acc[0], feature], acc[1]]; return acc;
}, },
[[], []] as [KibanaFeature[], KibanaFeature[]] { enabledFeatures: [], disabledFeatures: [] } as {
enabledFeatures: KibanaFeature[];
disabledFeatures: KibanaFeature[];
}
); );
const navLinks = capabilities.navLinks; const navLinks = capabilities.navLinks;