{"version":3,"file":"extractors.cjs","sources":["../../../src/query/extractors.ts"],"sourcesContent":["import { evaluateFunction, isFunctionCall } from \"./functions.js\"\nimport type { AllowedFunctionName, ConditionOperand } from \"./schema.js\"\n\n/**\n * Extracts a value from a nested row structure\n * @param namespacedRow The nested row structure\n * @param columnRef The column reference (may include table.column format)\n * @param mainTableAlias The main table alias to check first for columns without table reference\n * @param joinedTableAlias The joined table alias to check second for columns without table reference\n * @returns The extracted value or undefined if not found\n */\nexport function extractValueFromNamespacedRow(\n  namespacedRow: Record<string, unknown>,\n  columnRef: string,\n  mainTableAlias?: string,\n  joinedTableAlias?: string\n): unknown {\n  // Check if it's a table.column reference\n  if (columnRef.includes(`.`)) {\n    const [tableAlias, colName] = columnRef.split(`.`) as [string, string]\n\n    // Get the table data\n    const tableData = namespacedRow[tableAlias] as\n      | Record<string, unknown>\n      | null\n      | undefined\n\n    if (!tableData) {\n      return null\n    }\n\n    // Return the column value from that table\n    const value = tableData[colName]\n    return value\n  } else {\n    // If no table is specified, first try to find in the main table if provided\n    if (mainTableAlias && namespacedRow[mainTableAlias]) {\n      const mainTableData = namespacedRow[mainTableAlias] as Record<\n        string,\n        unknown\n      >\n      if (typeof mainTableData === `object` && columnRef in mainTableData) {\n        return mainTableData[columnRef]\n      }\n    }\n\n    // Then try the joined table if provided\n    if (joinedTableAlias && namespacedRow[joinedTableAlias]) {\n      const joinedTableData = namespacedRow[joinedTableAlias] as Record<\n        string,\n        unknown\n      >\n      if (typeof joinedTableData === `object` && columnRef in joinedTableData) {\n        return joinedTableData[columnRef]\n      }\n    }\n\n    // If not found in main or joined table, try to find the column in any table\n    for (const [_tableAlias, tableData] of Object.entries(namespacedRow)) {\n      if (\n        tableData &&\n        typeof tableData === `object` &&\n        columnRef in (tableData as Record<string, unknown>)\n      ) {\n        return (tableData as Record<string, unknown>)[columnRef]\n      }\n    }\n    return undefined\n  }\n}\n\n/**\n * Evaluates an operand against a nested row structure\n */\nexport function evaluateOperandOnNamespacedRow(\n  namespacedRow: Record<string, unknown>,\n  operand: ConditionOperand,\n  mainTableAlias?: string,\n  joinedTableAlias?: string\n): unknown {\n  // Handle column references\n  if (typeof operand === `string` && operand.startsWith(`@`)) {\n    const columnRef = operand.substring(1)\n    return extractValueFromNamespacedRow(\n      namespacedRow,\n      columnRef,\n      mainTableAlias,\n      joinedTableAlias\n    )\n  }\n\n  // Handle explicit column references\n  if (operand && typeof operand === `object` && `col` in operand) {\n    const colRef = (operand as { col: unknown }).col\n\n    if (typeof colRef === `string`) {\n      // First try to extract from nested row structure\n      const nestedValue = extractValueFromNamespacedRow(\n        namespacedRow,\n        colRef,\n        mainTableAlias,\n        joinedTableAlias\n      )\n\n      // If not found in nested structure, check if it's a direct property of the row\n      // This is important for HAVING clauses that reference aggregated values\n      if (nestedValue === undefined && colRef in namespacedRow) {\n        return namespacedRow[colRef]\n      }\n\n      return nestedValue\n    }\n\n    return undefined\n  }\n\n  // Handle function calls\n  if (operand && typeof operand === `object` && isFunctionCall(operand)) {\n    // Get the function name (the only key in the object)\n    const functionName = Object.keys(operand)[0] as AllowedFunctionName\n    // Get the arguments using type assertion with specific function name\n    const args = (operand as any)[functionName]\n\n    // If the arguments are a reference or another expression, evaluate them first\n    const evaluatedArgs = Array.isArray(args)\n      ? args.map((arg) =>\n          evaluateOperandOnNamespacedRow(\n            namespacedRow,\n            arg as ConditionOperand,\n            mainTableAlias,\n            joinedTableAlias\n          )\n        )\n      : evaluateOperandOnNamespacedRow(\n          namespacedRow,\n          args as ConditionOperand,\n          mainTableAlias,\n          joinedTableAlias\n        )\n\n    // Call the function with the evaluated arguments\n    return evaluateFunction(\n      functionName,\n      evaluatedArgs as ConditionOperand | Array<ConditionOperand>\n    )\n  }\n\n  // Handle explicit literals\n  if (operand && typeof operand === `object` && `value` in operand) {\n    return (operand as { value: unknown }).value\n  }\n\n  // Handle literal values\n  return operand\n}\n\n/**\n * Extracts a join key value from a row based on the operand\n * @param row The data row (not nested)\n * @param operand The operand to extract the key from\n * @param defaultTableAlias The default table alias\n * @returns The extracted key value\n */\nexport function extractJoinKey<T extends Record<string, unknown>>(\n  row: T,\n  operand: ConditionOperand,\n  defaultTableAlias?: string\n): unknown {\n  let keyValue: unknown\n\n  // Handle column references (e.g., \"@orders.id\" or \"@id\")\n  if (typeof operand === `string` && operand.startsWith(`@`)) {\n    const columnRef = operand.substring(1)\n\n    // If it contains a dot, extract the table and column\n    if (columnRef.includes(`.`)) {\n      const [tableAlias, colName] = columnRef.split(`.`) as [string, string]\n      // If this is referencing the current table, extract from row directly\n      if (tableAlias === defaultTableAlias) {\n        keyValue = row[colName]\n      } else {\n        // This might be a column from another table, return undefined\n        keyValue = undefined\n      }\n    } else {\n      // No table specified, look directly in the row\n      keyValue = row[columnRef]\n    }\n  } else if (operand && typeof operand === `object` && `col` in operand) {\n    // Handle explicit column references like { col: \"orders.id\" } or { col: \"id\" }\n    const colRef = (operand as { col: unknown }).col\n\n    if (typeof colRef === `string`) {\n      if (colRef.includes(`.`)) {\n        const [tableAlias, colName] = colRef.split(`.`) as [string, string]\n        // If this is referencing the current table, extract from row directly\n        if (tableAlias === defaultTableAlias) {\n          keyValue = row[colName]\n        } else {\n          // This might be a column from another table, return undefined\n          keyValue = undefined\n        }\n      } else {\n        // No table specified, look directly in the row\n        keyValue = row[colRef]\n      }\n    }\n  } else {\n    // Handle literals or other types\n    keyValue = operand\n  }\n\n  return keyValue\n}\n"],"names":["isFunctionCall","evaluateFunction"],"mappings":";;;AAWO,SAAS,8BACd,eACA,WACA,gBACA,kBACS;AAEL,MAAA,UAAU,SAAS,GAAG,GAAG;AAC3B,UAAM,CAAC,YAAY,OAAO,IAAI,UAAU,MAAM,GAAG;AAG3C,UAAA,YAAY,cAAc,UAAU;AAK1C,QAAI,CAAC,WAAW;AACP,aAAA;AAAA,IAAA;AAIH,UAAA,QAAQ,UAAU,OAAO;AACxB,WAAA;AAAA,EAAA,OACF;AAED,QAAA,kBAAkB,cAAc,cAAc,GAAG;AAC7C,YAAA,gBAAgB,cAAc,cAAc;AAIlD,UAAI,OAAO,kBAAkB,YAAY,aAAa,eAAe;AACnE,eAAO,cAAc,SAAS;AAAA,MAAA;AAAA,IAChC;AAIE,QAAA,oBAAoB,cAAc,gBAAgB,GAAG;AACjD,YAAA,kBAAkB,cAAc,gBAAgB;AAItD,UAAI,OAAO,oBAAoB,YAAY,aAAa,iBAAiB;AACvE,eAAO,gBAAgB,SAAS;AAAA,MAAA;AAAA,IAClC;AAIF,eAAW,CAAC,aAAa,SAAS,KAAK,OAAO,QAAQ,aAAa,GAAG;AACpE,UACE,aACA,OAAO,cAAc,YACrB,aAAc,WACd;AACA,eAAQ,UAAsC,SAAS;AAAA,MAAA;AAAA,IACzD;AAEK,WAAA;AAAA,EAAA;AAEX;AAKO,SAAS,+BACd,eACA,SACA,gBACA,kBACS;AAET,MAAI,OAAO,YAAY,YAAY,QAAQ,WAAW,GAAG,GAAG;AACpD,UAAA,YAAY,QAAQ,UAAU,CAAC;AAC9B,WAAA;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EAAA;AAIF,MAAI,WAAW,OAAO,YAAY,YAAY,SAAS,SAAS;AAC9D,UAAM,SAAU,QAA6B;AAEzC,QAAA,OAAO,WAAW,UAAU;AAE9B,YAAM,cAAc;AAAA,QAClB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAII,UAAA,gBAAgB,UAAa,UAAU,eAAe;AACxD,eAAO,cAAc,MAAM;AAAA,MAAA;AAGtB,aAAA;AAAA,IAAA;AAGF,WAAA;AAAA,EAAA;AAIT,MAAI,WAAW,OAAO,YAAY,YAAYA,UAAAA,eAAe,OAAO,GAAG;AAErE,UAAM,eAAe,OAAO,KAAK,OAAO,EAAE,CAAC;AAErC,UAAA,OAAQ,QAAgB,YAAY;AAG1C,UAAM,gBAAgB,MAAM,QAAQ,IAAI,IACpC,KAAK;AAAA,MAAI,CAAC,QACR;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAAA,IACF,IAEF;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAGG,WAAAC,UAAA;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAAA,EAAA;AAIF,MAAI,WAAW,OAAO,YAAY,YAAY,WAAW,SAAS;AAChE,WAAQ,QAA+B;AAAA,EAAA;AAIlC,SAAA;AACT;AASgB,SAAA,eACd,KACA,SACA,mBACS;AACL,MAAA;AAGJ,MAAI,OAAO,YAAY,YAAY,QAAQ,WAAW,GAAG,GAAG;AACpD,UAAA,YAAY,QAAQ,UAAU,CAAC;AAGjC,QAAA,UAAU,SAAS,GAAG,GAAG;AAC3B,YAAM,CAAC,YAAY,OAAO,IAAI,UAAU,MAAM,GAAG;AAEjD,UAAI,eAAe,mBAAmB;AACpC,mBAAW,IAAI,OAAO;AAAA,MAAA,OACjB;AAEM,mBAAA;AAAA,MAAA;AAAA,IACb,OACK;AAEL,iBAAW,IAAI,SAAS;AAAA,IAAA;AAAA,EAC1B,WACS,WAAW,OAAO,YAAY,YAAY,SAAS,SAAS;AAErE,UAAM,SAAU,QAA6B;AAEzC,QAAA,OAAO,WAAW,UAAU;AAC1B,UAAA,OAAO,SAAS,GAAG,GAAG;AACxB,cAAM,CAAC,YAAY,OAAO,IAAI,OAAO,MAAM,GAAG;AAE9C,YAAI,eAAe,mBAAmB;AACpC,qBAAW,IAAI,OAAO;AAAA,QAAA,OACjB;AAEM,qBAAA;AAAA,QAAA;AAAA,MACb,OACK;AAEL,mBAAW,IAAI,MAAM;AAAA,MAAA;AAAA,IACvB;AAAA,EACF,OACK;AAEM,eAAA;AAAA,EAAA;AAGN,SAAA;AACT;;;;"}