{"version":3,"file":"entityFormModel.mjs","names":["EntityAttribute","name","friendlyName","reference","extendedProperties","Record","key","UdpFieldInfo","isPrimaryKey","isIdentity","dataType","properties","mergeEntityAttributes","catalogProperties","udpFieldInfos","length","undefined","attributeMap","Map","map","attribute","toLowerCase","sortedPart","flatMap","field","match","get","udpFieldProperties","configuredNames","Set","unmatchedPart","filter","has"],"sources":["../../../src/domain/entityForm/entityFormModel.ts"],"sourcesContent":["/**\n * The platform's DEFAULT entity form — pure derivations.\n *\n * Two surfaces build the SAME `CrudForm` from the same two server reads: the\n * Maintenance Engine page (its create/edit side sheet) and the inquiry v2\n * action sheet (an Update/Create action with no page configured). The ordering\n * rule that turns catalog attributes + UdpObjectFieldInfo rows into form fields\n * lives here so both read it from one place — and so it is testable without a\n * catalog behind it.\n */\n\n/** One catalog attribute (`catalogObject.properties[]`) — config-shaped. */\nexport interface EntityAttribute {\n  name: string;\n  friendlyName?: string;\n  /** The referenced entity name, for a child-entity (foreign key) attribute. */\n  reference?: string;\n  extendedProperties?: Record<string, unknown>;\n  [key: string]: unknown;\n}\n\n/** One UdpObjectFieldInfo row — the tenant's per-field maintenance config. */\nexport interface UdpFieldInfo {\n  name: string;\n  isPrimaryKey?: boolean;\n  isIdentity?: boolean;\n  dataType?: string;\n  properties?: Record<string, unknown>;\n  [key: string]: unknown;\n}\n\n/**\n * Catalog attributes ordered and enriched by the entity's UdpObjectFieldInfo\n * rows: the field-info order IS the configured form order, and each matched\n * attribute carries its row's `properties` as `udpFieldProperties` (what\n * `useCrudActions` reads to pick an input). Attributes with no field-info row\n * keep their catalog order behind the configured ones.\n *\n * `undefined` when the entity has no field-info rows — there is no configured\n * form for it, which is the caller's cue to say so rather than render a\n * half-guessed one.\n */\nexport const mergeEntityAttributes = (\n  catalogProperties: EntityAttribute[] | null | undefined,\n  udpFieldInfos: UdpFieldInfo[] | null | undefined\n): EntityAttribute[] | undefined => {\n  if (!udpFieldInfos?.length || !catalogProperties) return undefined;\n\n  const attributeMap = new Map(\n    catalogProperties.map((attribute) => [\n      attribute.name.toLowerCase(),\n      attribute\n    ])\n  );\n  const sortedPart = udpFieldInfos.flatMap((field) => {\n    const match = attributeMap.get(field.name.toLowerCase());\n    if (!match) return [];\n    return [\n      {\n        ...match,\n        extendedProperties: {\n          ...match.extendedProperties,\n          udpFieldProperties: field.properties\n        }\n      }\n    ];\n  });\n\n  const configuredNames = new Set(\n    udpFieldInfos.map((field) => field.name.toLowerCase())\n  );\n  const unmatchedPart = catalogProperties.filter(\n    (attribute) => !configuredNames.has(attribute.name.toLowerCase())\n  );\n\n  return [...sortedPart, ...unmatchedPart];\n};\n"],"mappings":";;;;;;;;;;;;AA0CA,MAAaY,yBACXC,mBACAC,kBACkC;AAClC,KAAI,CAACA,eAAeC,UAAU,CAACF,kBAAmB,QAAOG,KAAAA;CAEzD,MAAMC,eAAe,IAAIC,IACvBL,kBAAkBM,KAAKC,cAAc,CACnCA,UAAUnB,KAAKoB,aAAa,EAC5BD,UACD,CACH,CAAC;CACD,MAAME,aAAaR,cAAcS,SAASC,UAAU;EAClD,MAAMC,QAAQR,aAAaS,IAAIF,MAAMvB,KAAKoB,aAAa,CAAC;AACxD,MAAI,CAACI,MAAO,QAAO,EAAE;AACrB,SAAO,CACL;GACE,GAAGA;GACHrB,oBAAoB;IAClB,GAAGqB,MAAMrB;IACTuB,oBAAoBH,MAAMb;IAC5B;GACD,CACF;GACD;CAEF,MAAMiB,kBAAkB,IAAIC,IAC1Bf,cAAcK,KAAKK,UAAUA,MAAMvB,KAAKoB,aAAa,CACvD,CAAC;CACD,MAAMS,gBAAgBjB,kBAAkBkB,QACrCX,cAAc,CAACQ,gBAAgBI,IAAIZ,UAAUnB,KAAKoB,aAAa,CAClE,CAAC;AAED,QAAO,CAAC,GAAGC,YAAY,GAAGQ,cAAc"}