File size: 3,536 Bytes
d9494a5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import {
  checkIfFieldIsImageIdentifier,
  checkIfFieldIsLabelIdentifier,
} from 'twenty-shared/metadata';
import {
  FieldMetadataType,
  RelationType,
  type RestrictedFieldsPermissions,
  compositeTypeDefinitions,
} from 'twenty-shared/types';

import { computeMorphOrRelationFieldJoinColumnName } from 'src/engine/metadata-modules/field-metadata/utils/compute-morph-or-relation-field-join-column-name.util';
import { isCompositeFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util';
import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type';
import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util';
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
import { isFlatFieldMetadataOfType } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-flat-field-metadata-of-type.util';
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';

type SelectableFieldsStructured = Record<
  string,
  boolean | Record<string, boolean>
>;

export const getAllSelectableFields = ({
  restrictedFields,
  flatObjectMetadata,
  flatFieldMetadataMaps,
  onlyUseLabelIdentifierFieldsInRelations = false,
}: {
  restrictedFields: RestrictedFieldsPermissions;
  flatObjectMetadata: FlatObjectMetadata;
  flatFieldMetadataMaps: FlatEntityMaps<FlatFieldMetadata>;
  onlyUseLabelIdentifierFieldsInRelations?: boolean;
}): SelectableFieldsStructured => {
  const result: SelectableFieldsStructured = {};

  for (const fieldId of flatObjectMetadata.fieldIds) {
    const flatField = findFlatEntityByIdInFlatEntityMapsOrThrow({
      flatEntityMaps: flatFieldMetadataMaps,
      flatEntityId: fieldId,
    });

    if (restrictedFields[flatField.id]?.canRead === false) continue;

    if (onlyUseLabelIdentifierFieldsInRelations) {
      const fieldIsLabelIdentifier = checkIfFieldIsLabelIdentifier(
        flatField,
        flatObjectMetadata,
      );
      const fieldIsImageIdentifier = checkIfFieldIsImageIdentifier(
        flatField,
        flatObjectMetadata,
      );
      const fieldIsIdField = flatField.name === 'id';

      if (
        !fieldIsLabelIdentifier &&
        !fieldIsImageIdentifier &&
        !fieldIsIdField
      ) {
        continue;
      }
    }

    if (isCompositeFieldMetadataType(flatField.type)) {
      const compositeType = compositeTypeDefinitions.get(flatField.type);

      if (!compositeType) {
        throw new Error(
          `Composite type definition not found for type: ${flatField.type}`,
        );
      }

      const compositeFields: Record<string, boolean> = {};

      for (const property of compositeType.properties) {
        compositeFields[property.name] = true;
      }

      result[flatField.name] = compositeFields;
    } else if (
      (isFlatFieldMetadataOfType(flatField, FieldMetadataType.RELATION) ||
        isFlatFieldMetadataOfType(
          flatField,
          FieldMetadataType.MORPH_RELATION,
        )) &&
      flatField.settings.relationType === RelationType.MANY_TO_ONE
    ) {
      const joinColumnName = computeMorphOrRelationFieldJoinColumnName({
        name: flatField.name,
      });

      result[joinColumnName] = true;
    } else {
      result[flatField.name] = true;
    }
  }

  return result;
};