{"version":3,"file":"entityFormInputs.mjs","names":["ConfigService","CardinalityTypeEnums","UdpEnums","executeQueryAdHoc","executeQueryAdHocUntyped","EntityAttribute","UdpFieldInfo","getSanitizedName","getSanitizedNameUntyped","SYSTEM_ENTITY_PROPERTIES","toLowerFirstChar","toLowerFirstCharUntyped","getSearchObject","apiMutate","apiMutateUntyped","UDP_LOOKUP_ENTITY_ATTRIBUTES_TO_HIDE","request","data","apiMethodId","Promise","pageList","baseURL","url","config","method","body","status","name","value","ForeignKeyDatum","fieldName","entityName","Array","id","ForeignKeyResult","foreignKeyData","entitiesMissingGetAll","fetchUdpFieldInfos","udpFieldSearchApiId","requestObj","searchField","searchOperator","searchValue","response","crudFormAttributes","entityAttributes","hidden","toLowerCase","includes","Udp_Lookup","filter","attribute","ForeignKeyMethod","entityAttribute","entity","unityBaseGetAllMethod","fetchForeignKeyMethods","catalogId","attributes","methods","extended","extendedProperties","childEntity","childEntityAssoc","Cardinality","Keys","UdpType","childAssoc","keyNames","Object","keys","length","Many_To_Many","One_To_Many","key","split","push","test","keyAttribute","find","candidate","integrationV1ApiUrl","reference","UNITY_PRODUCT_ID","fetchAssociationLabel","fieldInfos","fieldInfo","properties","maintainenceConfig","associationLabel","getDataByKey","row","Record","match","rowKey","fetchForeignKeyData","map","requests","all","payload","isArray","rows","some","existing","idName"],"sources":["../../src/maintenanceEngine/entityFormInputs.ts"],"sourcesContent":["/**\n * The platform's DEFAULT entity form — the server reads behind it.\n *\n * `CrudForm` needs three inputs, and every surface that mounts it assembles\n * them the same way: the entity's UdpObjectFieldInfo rows, the catalog\n * attributes ordered by them (`mergeEntityAttributes`, pure — domain/entityForm)\n * and the option lists behind its foreign-key fields. These were inlined in\n * `UdpMaintenanceEnginePage`; they live here so the inquiry v2 action sheet\n * mounts the SAME form from the SAME reads instead of a second copy of them.\n *\n * Effectful on purpose — the pure derivation is in `domain/entityForm`.\n */\nimport { ConfigService } from '../configService';\nimport { CardinalityTypeEnums, UdpEnums } from '../enums/unitySystemEnums';\nimport { executeQueryAdHoc as executeQueryAdHocUntyped } from '../udp/utilities/methodUtils';\nimport type {\n  EntityAttribute,\n  UdpFieldInfo\n} from '../domain/entityForm/entityFormModel';\nimport {\n  getSanitizedName as getSanitizedNameUntyped,\n  SYSTEM_ENTITY_PROPERTIES\n} from '../utilities/entities/entityUtilities';\nimport { toLowerFirstChar as toLowerFirstCharUntyped } from '../utilities/input/StringUtilities';\nimport { getSearchObject } from '../utilities/search/SearchUtilities';\nimport { apiMutate as apiMutateUntyped } from '../utilities/useAxiosMutate';\nimport { UDP_LOOKUP_ENTITY_ATTRIBUTES_TO_HIDE } from './entityAttributeActions';\n\n/* Typed boundaries over the untyped JS helpers (the queries.ts idiom). */\nconst executeQueryAdHoc = executeQueryAdHocUntyped as unknown as (\n  request: { data: unknown },\n  apiMethodId: string\n) => Promise<{ data?: { pageList?: UdpFieldInfo[] } }>;\nconst apiMutate = apiMutateUntyped as unknown as (\n  baseURL: string,\n  url: string,\n  config: { method: string },\n  body: unknown\n) => Promise<{ status?: number; data?: unknown }>;\nconst getSanitizedName = getSanitizedNameUntyped as (name: string) => string;\nconst toLowerFirstChar = toLowerFirstCharUntyped as (value: string) => string;\n\n/** One foreign-key field's option list, as `CrudForm` consumes it. */\nexport interface ForeignKeyDatum {\n  fieldName: string;\n  entityName: string;\n  name: string;\n  data: Array<{ id: unknown; name: unknown }>;\n}\n\nexport interface ForeignKeyResult {\n  foreignKeyData: ForeignKeyDatum[];\n  /**\n   * Referenced entities whose Get-All method is not promoted — their field has\n   * no options to offer. Surfaced as a warning by the maintenance page and\n   * logged by the inquiry sheet; never silently dropped.\n   */\n  entitiesMissingGetAll: string[];\n}\n\n/**\n * The entity's UdpObjectFieldInfo rows (`ObjectInfo.SanitizedName = <entity>`).\n * `udpFieldSearchApiId` is UdpObjectFieldInfo's own promoted search method —\n * without it the tenant has no field config at all, and the answer is empty.\n */\nexport const fetchUdpFieldInfos = async (\n  udpFieldSearchApiId: string | null | undefined,\n  entityName: string | null | undefined\n): Promise<UdpFieldInfo[]> => {\n  if (!udpFieldSearchApiId || !entityName) return [];\n  const requestObj = getSearchObject(\n    [\n      {\n        searchField: 'ObjectInfo.SanitizedName',\n        searchOperator: '=',\n        searchValue: getSanitizedName(entityName)\n      }\n    ] as never,\n    1,\n    50,\n    true\n  );\n  const response = await executeQueryAdHoc(\n    { data: requestObj },\n    udpFieldSearchApiId\n  );\n  return response?.data?.pageList ?? [];\n};\n\n/**\n * The attributes a `CrudForm` actually renders: identity bookkeeping the user\n * never edits is removed (LAA UNT-3026), and a UdpLookup hides its own storage\n * columns on top of that.\n */\nexport const crudFormAttributes = (\n  entityAttributes: EntityAttribute[] | null | undefined,\n  entityName: string | null | undefined\n): EntityAttribute[] | undefined => {\n  const hidden = entityName\n    ?.toLowerCase()\n    .includes(UdpEnums.Udp_Lookup.toLowerCase())\n    ? UDP_LOOKUP_ENTITY_ATTRIBUTES_TO_HIDE\n    : SYSTEM_ENTITY_PROPERTIES;\n  return entityAttributes?.filter(\n    (attribute) => !hidden.includes(attribute.name)\n  );\n};\n\n/** A child-entity attribute paired with the promoted methods behind it. */\ninterface ForeignKeyMethod {\n  entityAttribute: EntityAttribute;\n  entity: {\n    entityName: string;\n    unityBaseGetAllMethod?: { apiMethodId?: string };\n  };\n}\n\n/**\n * The child-entity attributes that need an option list, with the promoted\n * methods of the entity each one points at.\n */\nconst fetchForeignKeyMethods = async (\n  catalogId: string,\n  attributes: EntityAttribute[]\n): Promise<ForeignKeyMethod[]> => {\n  const methods: ForeignKeyMethod[] = [];\n  for (const attribute of attributes) {\n    const extended = attribute.extendedProperties as\n      | {\n          childEntity?: unknown;\n          childEntityAssoc?: {\n            Cardinality?: CardinalityTypeEnums;\n            Keys?: string[];\n            UdpType?: unknown;\n          };\n        }\n      | undefined;\n    if (!extended?.childEntity) continue;\n\n    // The association's key fields, in the row's own casing.\n    const childAssoc = extended.childEntityAssoc;\n    const keyNames: string[] = [];\n    if (\n      childAssoc &&\n      Object.keys(childAssoc).length > 0 &&\n      (childAssoc.Cardinality === CardinalityTypeEnums.Many_To_Many ||\n        childAssoc.Cardinality === CardinalityTypeEnums.One_To_Many) &&\n      !childAssoc.UdpType\n    ) {\n      for (const key of childAssoc.Keys ?? []) {\n        const name = key.split(',')[0];\n        if (!name) continue;\n        keyNames.push(\n          /^[A-Z]*$/.test(name) ? name.toLowerCase() : toLowerFirstChar(name)\n        );\n      }\n    }\n\n    const keyAttribute = attributes.find((candidate) =>\n      keyNames.includes(candidate.name)\n    );\n    if (!keyAttribute) continue;\n\n    const response = await apiMutate(\n      ConfigService.integrationV1ApiUrl,\n      `apicatalog/${catalogId}/promotedMethodEntities/${attribute.reference}/product/${ConfigService.config.UNITY_PRODUCT_ID}`,\n      { method: 'get' },\n      {}\n    );\n    if (response?.data) {\n      methods.push({\n        entityAttribute: keyAttribute,\n        entity: response.data as ForeignKeyMethod['entity']\n      });\n    }\n  }\n  return methods;\n};\n\n/** The field whose value labels a referenced record in a picker. */\nconst fetchAssociationLabel = async (\n  udpFieldSearchApiId: string | null | undefined,\n  entityName: string\n): Promise<string | undefined> => {\n  const fieldInfos = await fetchUdpFieldInfos(udpFieldSearchApiId, entityName);\n  return fieldInfos.find((fieldInfo) => {\n    const config = fieldInfo.properties as\n      | { maintainenceConfig?: { associationLabel?: string } }\n      | undefined;\n    return config?.maintainenceConfig?.associationLabel === 'true';\n  })?.name;\n};\n\n/** Wire rows mix casings; find a value by an exact key or a contained one. */\nconst getDataByKey = (\n  row: Record<string, unknown> | null | undefined,\n  key: string\n): unknown => {\n  if (!row) return null;\n  const value = row[key] ?? null;\n  if (value) return value;\n  const match = Object.keys(row).find((rowKey) =>\n    rowKey.toLowerCase().includes(key)\n  );\n  return match ? row[match] : null;\n};\n\n/**\n * Every foreign-key field's option list: one Get-All per referenced entity,\n * mapped to `{ id, name }` through the entity's association label (falling back\n * to the id, so a picker never renders a blank row).\n */\nexport const fetchForeignKeyData = async (\n  catalogId: string | null | undefined,\n  attributes: EntityAttribute[] | null | undefined,\n  udpFieldSearchApiId: string | null | undefined\n): Promise<ForeignKeyResult> => {\n  if (!catalogId || !attributes?.length) {\n    return { foreignKeyData: [], entitiesMissingGetAll: [] };\n  }\n  const methods = await fetchForeignKeyMethods(catalogId, attributes);\n  const entitiesMissingGetAll = methods\n    .filter((method) => !method.entity?.unityBaseGetAllMethod)\n    .map((method) => method.entity.entityName);\n\n  const requests = await Promise.all(\n    methods\n      .filter((method) => method.entity?.unityBaseGetAllMethod)\n      .map(async (method) => ({\n        fieldName: method.entityAttribute.name,\n        entityName: method.entity.entityName,\n        associationLabel: await fetchAssociationLabel(\n          udpFieldSearchApiId,\n          method.entity.entityName\n        ),\n        response: await apiMutate(\n          ConfigService.integrationV1ApiUrl,\n          `apimethod/executeQueryWithParameters/${method.entity.unityBaseGetAllMethod?.apiMethodId}`,\n          { method: 'post' },\n          { data: {} }\n        )\n      }))\n  );\n\n  const foreignKeyData: ForeignKeyDatum[] = [];\n  for (const request of requests) {\n    const payload =\n      request.response?.status === 200 ? request.response.data : null;\n    if (!Array.isArray(payload)) continue;\n    const rows = payload as Array<Record<string, unknown>>;\n    if (\n      foreignKeyData.some(\n        (existing) =>\n          existing.entityName === request.entityName &&\n          existing.fieldName === request.fieldName\n      )\n    ) {\n      continue;\n    }\n    foreignKeyData.push({\n      fieldName: request.fieldName,\n      entityName: request.entityName,\n      name: request.fieldName,\n      data: rows.map((row) => {\n        const idName = row[request.fieldName] ? request.fieldName : 'id';\n        const id = getDataByKey(row, idName);\n        const name = getDataByKey(\n          row,\n          request.associationLabel\n            ? toLowerFirstChar(request.associationLabel)\n            : 'name'\n        );\n        return { id, name: name ?? id };\n      })\n    });\n  }\n\n  return { foreignKeyData, entitiesMissingGetAll };\n};\n"],"mappings":"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"}