MCPcopy Create free account
hub / github.com/mikro-orm/mikro-orm / preparePopulate

Method preparePopulate

packages/core/src/EntityManager.ts:2874–3030  ·  view source on GitHub ↗

@internal

(
    entityName: EntityName<Entity>,
    options: Pick<
      FindOptions<Entity, any, any, any>,
      'populate' | 'strategy' | 'fields' | 'flags' | 'filters' | 'exclude' | 'populateHints'
    >,
    validate = true,
  )

Source from the content-addressed store, hash-verified

2872
2873 /** @internal */
2874 async preparePopulate<Entity extends object>(
2875 entityName: EntityName<Entity>,
2876 options: Pick<
2877 FindOptions<Entity, any, any, any>,
2878 'populate' | 'strategy' | 'fields' | 'flags' | 'filters' | 'exclude' | 'populateHints'
2879 >,
2880 validate = true,
2881 ): Promise<PopulateOptions<Entity>[]> {
2882 if (options.populate === false) {
2883 return [];
2884 }
2885
2886 const meta = this.metadata.find(entityName)!;
2887
2888 // infer populate hints from `fields` when present; merge with explicit `populate` if both are set.
2889 // `populateArray` is only kept when the entries are user-provided strings — when this method runs a
2890 // second time (e.g. from `lockAndPopulate`) the populate is already normalized and merging would be a no-op.
2891 const fields = options.fields ? this.buildFields(options.fields) : undefined;
2892 const populateArray =
2893 Array.isArray(options.populate) && options.populate.every(p => typeof p === 'string')
2894 ? (options.populate as string[])
2895 : undefined;
2896 const hasNestedFields = fields?.some(f => f.includes('.')) ?? false;
2897 const shouldInfer = fields !== undefined && options.populate === undefined;
2898 const shouldMerge =
2899 fields !== undefined && populateArray !== undefined && populateArray.length > 0 && hasNestedFields;
2900
2901 if (shouldInfer || shouldMerge) {
2902 // we need to prune the `populate` hint from to-one relations, as partially loading them does not require their population, we want just the FK
2903 const pruneToOneRelations = (meta: EntityMetadata, fields: string[]): string[] => {
2904 const ret: string[] = [];
2905
2906 for (let field of fields) {
2907 if (field === PopulatePath.ALL || field.startsWith(`${PopulatePath.ALL}.`)) {
2908 ret.push(
2909 ...meta.props
2910 .filter(prop => prop.lazy || [ReferenceKind.SCALAR, ReferenceKind.EMBEDDED].includes(prop.kind))
2911 .map(prop => prop.name),
2912 );
2913 continue;
2914 }
2915
2916 field = field.split(':')[0];
2917
2918 if (
2919 !field.includes('.') &&
2920 ![ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(meta.properties[field].kind)
2921 ) {
2922 ret.push(field);
2923 continue;
2924 }
2925
2926 const parts = field.split('.');
2927 const key = parts.shift()!;
2928
2929 if (parts.length === 0) {
2930 continue;
2931 }

Callers 5

findMethod · 0.80
streamMethod · 0.80
findOneMethod · 0.80
countMethod · 0.80
matchingMethod · 0.80

Calls 13

buildFieldsMethod · 0.95
canPopulateMethod · 0.95
applyPopulateHintsFunction · 0.85
filterMethod · 0.80
normalizePopulateMethod · 0.80
asArrayMethod · 0.80
pushMethod · 0.80
invalidPropertyNameMethod · 0.80
findMethod · 0.65
hasMethod · 0.65

Tested by

no test coverage detected