{"version":3,"file":"operators.mjs","names":["SearchOperators","OPERATORS_BY_TYPE","Record","guid","string","number","boolean","date","datetime","time","default","SINGLE_VALUE_OPERATORS","Set","MULTI_VALUE_OPERATORS","NO_VALUE_OPERATORS","OPERATOR_TO_BACKEND","equals","EQUALS","not_equals","NOT_EQUALS","contains","LIKE","starts_with","STARTSWITH","greater_than","GREATER_THAN","greater_than_or_equal","GREATER_THAN_OR_EQUAL","less_than","LESS_THAN","less_than_or_equal","LESS_THAN_OR_EQUAL","between","BETWEEN","in","IN","not_in","NOT_IN","is_empty","NULL","is_not_empty","NOT_NULL","OPERATOR_FROM_BACKEND","Object","fromEntries","entries","map","operator","backend","OPERATOR_LABELS","GUID_REGEX","DATE_REGEX","checkValueFormat","type","value","Number","isFinite","trim","test","normalizeSearchFieldType","netType","clean","endsWith","slice","lower","toLowerCase","includes"],"sources":["../../src/searchIntent/operators.ts"],"sourcesContent":["import { SearchOperators } from '@univerus/udp-stencil-component-library';\n\n// Operator availability per normalized type. Mirrors\n// advanced-search-builder/helperFunctions/udpOperatorHelper.ts — keep in sync.\nexport const OPERATORS_BY_TYPE: Record<string, string[]> = {\n  guid: [\n    'equals',\n    'not_equals',\n    'contains',\n    'in',\n    'not_in',\n    'is_empty',\n    'is_not_empty'\n  ],\n  string: [\n    'equals',\n    'not_equals',\n    'contains',\n    'starts_with',\n    'in',\n    'not_in',\n    'is_empty',\n    'is_not_empty'\n  ],\n  number: [\n    'equals',\n    'not_equals',\n    'less_than',\n    'greater_than',\n    'less_than_or_equal',\n    'greater_than_or_equal',\n    'between',\n    'in',\n    'not_in',\n    'is_empty',\n    'is_not_empty'\n  ],\n  boolean: ['equals', 'not_equals', 'is_empty', 'is_not_empty'],\n  date: [\n    'equals',\n    'not_equals',\n    'less_than',\n    'greater_than',\n    'less_than_or_equal',\n    'greater_than_or_equal',\n    'between',\n    'is_empty',\n    'is_not_empty'\n  ],\n  datetime: [\n    'equals',\n    'not_equals',\n    'less_than',\n    'greater_than',\n    'less_than_or_equal',\n    'greater_than_or_equal',\n    'between',\n    'is_empty',\n    'is_not_empty'\n  ],\n  time: [\n    'equals',\n    'not_equals',\n    'less_than',\n    'greater_than',\n    'less_than_or_equal',\n    'greater_than_or_equal',\n    'between',\n    'is_empty',\n    'is_not_empty'\n  ],\n  default: ['equals', 'not_equals']\n};\n\nexport const SINGLE_VALUE_OPERATORS = new Set([\n  'equals',\n  'not_equals',\n  'contains',\n  'starts_with',\n  'greater_than',\n  'greater_than_or_equal',\n  'less_than',\n  'less_than_or_equal'\n]);\nexport const MULTI_VALUE_OPERATORS = new Set(['between', 'in', 'not_in']);\nexport const NO_VALUE_OPERATORS = new Set(['is_empty', 'is_not_empty']);\n\n// Semantic operator → backend SearchHelper constant. Values are sent raw:\n// the backend applies substring semantics to LIKE itself (matching the grid's\n// buildSearchObject behavior), so no % wrapping here.\nexport const OPERATOR_TO_BACKEND: Record<string, string> = {\n  equals: SearchOperators.EQUALS,\n  not_equals: SearchOperators.NOT_EQUALS,\n  contains: SearchOperators.LIKE,\n  starts_with: SearchOperators.STARTSWITH,\n  greater_than: SearchOperators.GREATER_THAN,\n  greater_than_or_equal: SearchOperators.GREATER_THAN_OR_EQUAL,\n  less_than: SearchOperators.LESS_THAN,\n  less_than_or_equal: SearchOperators.LESS_THAN_OR_EQUAL,\n  between: SearchOperators.BETWEEN,\n  in: SearchOperators.IN,\n  not_in: SearchOperators.NOT_IN,\n  is_empty: SearchOperators.NULL,\n  is_not_empty: SearchOperators.NOT_NULL\n};\n\n/**\n * Backend SearchHelper constant → semantic operator: the inverse of\n * OPERATOR_TO_BACKEND, for reading an existing Search back into the vocabulary\n * the model speaks (see describeCurrentSearchState). Backend operators with no\n * intent equivalent (NOTLIKE, ENDSWITH) are absent — callers fall back to the\n * raw constant rather than inventing one.\n */\nexport const OPERATOR_FROM_BACKEND: Record<string, string> = Object.fromEntries(\n  Object.entries(OPERATOR_TO_BACKEND).map(([operator, backend]) => [\n    backend,\n    operator\n  ])\n);\n\n/** Human-readable operator labels for proposal diff cards. */\nexport const OPERATOR_LABELS: Record<string, string> = {\n  equals: '=',\n  not_equals: '≠',\n  contains: 'contains',\n  starts_with: 'begins with',\n  greater_than: '>',\n  greater_than_or_equal: '≥',\n  less_than: '<',\n  less_than_or_equal: '≤',\n  between: 'between',\n  in: 'in',\n  not_in: 'not in',\n  is_empty: 'is empty',\n  is_not_empty: 'is not empty'\n};\n\nconst GUID_REGEX =\n  /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;\nconst DATE_REGEX = /^\\d{4}-\\d{2}-\\d{2}/;\n\n/** Returns an error fragment when a value doesn't fit the field type, else null. */\nexport const checkValueFormat = (\n  type: string,\n  value: string\n): string | null => {\n  switch (type) {\n    case 'boolean':\n      return value === 'true' || value === 'false'\n        ? null\n        : `expected \"true\" or \"false\", got \"${value}\"`;\n    case 'number':\n      return Number.isFinite(Number(value)) && value.trim() !== ''\n        ? null\n        : `\"${value}\" is not a number`;\n    case 'date':\n    case 'datetime':\n      return DATE_REGEX.test(value)\n        ? null\n        : `\"${value}\" is not an ISO date (YYYY-MM-DD)`;\n    case 'guid':\n      return GUID_REGEX.test(value) ? null : `\"${value}\" is not a GUID`;\n    default:\n      return null;\n  }\n};\n\n/**\n * Normalizes a catalog/.NET type name to the vocabulary OPERATORS_BY_TYPE and\n * checkValueFormat use (same normalization catalogTree.ts applies).\n */\nexport const normalizeSearchFieldType = (\n  netType: string | null | undefined\n): string => {\n  if (!netType) return 'default';\n  const clean = netType.endsWith('?') ? netType.slice(0, -1) : netType;\n  const lower = clean.toLowerCase();\n  if (lower === 'guid' || lower === 'string uuid') return 'guid';\n  if (lower === 'string') return 'string';\n  if (\n    lower === 'long' ||\n    lower === 'int' ||\n    lower === 'short' ||\n    lower.includes('decimal') ||\n    lower === 'double' ||\n    lower === 'float'\n  )\n    return 'number';\n  if (lower === 'bool') return 'boolean';\n  if (lower === 'date') return 'date';\n  if (lower.includes('datetime')) return 'datetime';\n  if (lower.includes('time')) return 'time';\n  return 'default';\n};\n"],"mappings":"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"}