{"version":3,"file":"compile.mjs","names":["LogicalSearchOperator","SearchGroupingType","CatalogProperty","FilterElement","FilterGroup","Search","OPERATOR_TO_BACKEND","AiCondition","AiFilterSpec","CompiledSearchChanges","QueryIntent","toLogicalOperator","op","Or","And","toFilterElement","cond","groupId","searchField","field","searchOperator","operator","searchValue","values","join","value","compileFilters","spec","Pick","ROOT_GROUP_ID","filterGroups","parentGroupId","logicalSearchOperator","filterElements","conditions","map","c","nextGroupId","group","groups","push","compileIntent","intent","currentSearchBody","currentColumns","searchBody","filters","undefined","sorts","orderElements","s","sortColumn","sortDirection","direction","grouping","groupProperty","groupBy","groupOperationList","aggregates","a","operation","property","groupingType","length","Aggregate","Distinct","None","pageSize","grouped","Set","filter","o","has","eagerLoad","columns","showOnly","show","hide","showSet","hideSet","showOnlySet","col","currentVisible","extendedProperties","defaultVisible","nextVisible","name"],"sources":["../../src/searchIntent/compile.ts"],"sourcesContent":["import {\n  LogicalSearchOperator,\n  SearchGroupingType\n} from '@univerus/udp-stencil-component-library';\nimport type {\n  CatalogProperty,\n  FilterElement,\n  FilterGroup,\n  Search\n} from '@univerus/udp-stencil-component-library';\nimport { OPERATOR_TO_BACKEND } from './operators';\nimport type {\n  AiCondition,\n  AiFilterSpec,\n  CompiledSearchChanges,\n  QueryIntent\n} from './types';\n\nconst toLogicalOperator = (op: 'and' | 'or'): number =>\n  op === 'or' ? LogicalSearchOperator.Or : LogicalSearchOperator.And;\n\nconst toFilterElement = (\n  cond: AiCondition,\n  groupId: number\n): FilterElement => ({\n  searchField: cond.field,\n  searchOperator: OPERATOR_TO_BACKEND[cond.operator],\n  // Multi-value operators are comma-joined (\"v1,v2\"), matching both the manual\n  // builder's storage format and the grid's search composition.\n  searchValue: cond.values ? cond.values.join(',') : (cond.value ?? ''),\n  groupId\n});\n\n/**\n * Compiles the filter spec into filterElements + filterGroups with\n * deterministically assigned group ids: root group is 1, subgroups 2..n.\n * This is the shape getNormalizedData in the advanced search builder expects.\n */\nconst compileFilters = (\n  spec: AiFilterSpec\n): Pick<\n  Search,\n  'filterElements' | 'filterGroups' | 'logicalSearchOperator'\n> => {\n  const ROOT_GROUP_ID = 1;\n  const filterGroups: FilterGroup[] = [\n    {\n      groupId: ROOT_GROUP_ID,\n      parentGroupId: null,\n      logicalSearchOperator: toLogicalOperator(spec.op)\n    }\n  ];\n  const filterElements: FilterElement[] = (spec.conditions ?? []).map((c) =>\n    toFilterElement(c, ROOT_GROUP_ID)\n  );\n\n  let nextGroupId = ROOT_GROUP_ID + 1;\n  for (const group of spec.groups ?? []) {\n    const groupId = nextGroupId++;\n    filterGroups.push({\n      groupId,\n      parentGroupId: ROOT_GROUP_ID,\n      logicalSearchOperator: toLogicalOperator(group.op)\n    });\n    filterElements.push(\n      ...group.conditions.map((c) => toFilterElement(c, groupId))\n    );\n  }\n\n  return {\n    filterElements,\n    filterGroups,\n    logicalSearchOperator: toLogicalOperator(spec.op)\n  };\n};\n\n/**\n * Applies a validated intent to the current state, producing the next\n * searchBody + columns. Pure: never mutates inputs. Sections that are\n * null/omitted in the intent pass through unchanged.\n */\nexport const compileIntent = (\n  intent: QueryIntent,\n  currentSearchBody: Search,\n  currentColumns: CatalogProperty[]\n): CompiledSearchChanges => {\n  let searchBody: Search = { ...currentSearchBody };\n\n  if (intent.filters !== undefined && intent.filters !== null) {\n    searchBody = { ...searchBody, ...compileFilters(intent.filters) };\n  }\n\n  if (intent.sorts !== undefined && intent.sorts !== null) {\n    searchBody = {\n      ...searchBody,\n      orderElements: intent.sorts.map((s) => ({\n        sortColumn: s.field,\n        sortDirection: s.direction\n      }))\n    };\n  }\n\n  if (intent.grouping !== undefined && intent.grouping !== null) {\n    const groupProperty = [...(intent.grouping.groupBy ?? [])];\n    const groupOperationList = (intent.grouping.aggregates ?? []).map((a) => ({\n      operation: a.operation,\n      property: a.field\n    }));\n    // Aggregate when both groupBy and aggregates present, Distinct when only\n    // groupBy — the same derivation Data Builder's manual grouping UI applies.\n    const groupingType =\n      groupProperty.length > 0\n        ? groupOperationList.length > 0\n          ? SearchGroupingType.Aggregate\n          : SearchGroupingType.Distinct\n        : SearchGroupingType.None;\n    searchBody = {\n      ...searchBody,\n      groupProperty,\n      groupOperationList,\n      groupingType\n    };\n  }\n\n  if (intent.pageSize !== undefined && intent.pageSize !== null) {\n    searchBody = { ...searchBody, pageSize: intent.pageSize };\n  }\n\n  // Grouping-active invariants, mirroring the backend's own conventions\n  // (verified against the starter-project SearchUtil/DAO):\n  // - a grouped SELECT can only be ordered by grouped columns; the DB rejects\n  //   anything else (\"ORDER BY items must appear in the select list\"), and an\n  //   order on a grouped column is required for stable pagination\n  // - the AGGREGATE pk-list subquery only selects the pk expression when\n  //   EagerLoad is true (the backend service sets EagerLoad=true itself when\n  //   it builds aggregate searches)\n  const groupProperty = searchBody.groupProperty ?? [];\n  if (groupProperty.length > 0) {\n    const grouped = new Set(groupProperty);\n    let orderElements = (searchBody.orderElements ?? []).filter((o) =>\n      grouped.has(o.sortColumn)\n    );\n    if (orderElements.length === 0) {\n      orderElements = [{ sortColumn: groupProperty[0], sortDirection: 'ASC' }];\n    }\n    searchBody = { ...searchBody, orderElements };\n    if ((searchBody.groupOperationList ?? []).length > 0) {\n      searchBody = { ...searchBody, eagerLoad: true };\n    }\n  }\n\n  let columns = currentColumns;\n  if (intent.columns) {\n    const { showOnly, show, hide } = intent.columns;\n    const showSet = new Set(show ?? []);\n    const hideSet = new Set(hide ?? []);\n    const showOnlySet = showOnly ? new Set(showOnly) : null;\n\n    columns = currentColumns.map((col) => {\n      const currentVisible = col.extendedProperties?.defaultVisible !== false;\n      const nextVisible = showOnlySet\n        ? showOnlySet.has(col.name)\n        : showSet.has(col.name)\n          ? true\n          : hideSet.has(col.name)\n            ? false\n            : currentVisible;\n      if (nextVisible === currentVisible) return col;\n      return {\n        ...col,\n        extendedProperties: {\n          ...col.extendedProperties,\n          defaultVisible: nextVisible\n        }\n      };\n    });\n  }\n\n  return { searchBody, columns };\n};\n"],"mappings":"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"}