{"version":3,"sources":["../src/index.ts","../src/use-cube-record-query.ts"],"sourcesContent":["export type {\n  CubeRecordAttribute,\n  CubeRecordDefinition,\n  CubeRecordMap,\n  CubeRecordName,\n  CubeRecordQueryDimension,\n  CubeRecordQueryMeasure,\n  CubeRecordQueryMeasureType,\n  CubeRecordQueryRow,\n  CubeRecordQueryRowEnhanced,\n  CubeRecordQueryTimeDimension,\n  CubeRecordTimeDimension,\n  GroupByKey,\n  NumberFields,\n  PickNumberFields,\n  PickStringFields,\n  StringFields,\n} from './types';\nexport type {\n  CubeRecordOrder,\n  CubeRecordQueryFilter,\n  CubeRecordQueryParams,\n  CubeRecordQueryResult,\n  CubeRecordTimeDimensionParam,\n  UseCubeRecordQueryProps,\n  UseCubeRecordOptions,\n} from './use-cube-record-query';\nexport { useCubeRecordQuery } from './use-cube-record-query';\n","import type {\n  BinaryOperator,\n  Query as CoreCubeQuery,\n  ResultSet,\n  TimeDimension,\n  UnaryOperator,\n} from '@cubejs-client/core';\nimport {\n  type UseCubeQueryOptions as UseCoreCubeQueryOptions,\n  useCubeQuery as useCoreCubeQuery,\n} from '@cubejs-client/react';\nimport type {\n  CubeRecordAttribute,\n  CubeRecordName,\n  CubeRecordQueryDimension,\n  CubeRecordQueryMeasure,\n  CubeRecordQueryRow,\n  CubeRecordQueryTimeDimension,\n} from './types';\n\n/**\n * Remap keys by adding the model prefix to non-joined attributes\n */\n// TODO: Delete this when we handle non stripping in the `CubeRecordQueryRow` type.\ntype RemapKeysWithModel<N extends CubeRecordName, T> = {\n  [K in keyof T as K extends string\n    ? K extends `${string}.${string}`\n      ? K\n      : `${N}.${K}`\n    : K]: T[K];\n};\n\n/**\n * Filter definition for cube record queries\n */\nexport type CubeRecordQueryFilter<N extends CubeRecordName> =\n  | {\n      member: CubeRecordQueryMeasure<N> | CubeRecordQueryDimension<N>;\n      operator: BinaryOperator;\n      values: string[];\n    }\n  | {\n      member: CubeRecordQueryMeasure<N> | CubeRecordQueryDimension<N>;\n      operator: UnaryOperator;\n      values?: never;\n    };\n\n/**\n * Order type that accepts any valid attribute (measure or dimension) from the cube\n */\nexport type CubeRecordOrder<N extends CubeRecordName> = Partial<\n  Record<CubeRecordAttribute<N>, 'asc' | 'desc'>\n>;\n\n/**\n * Type-safe time dimension that only accepts dimensions with time type\n */\nexport type CubeRecordTimeDimensionParam<N extends CubeRecordName> = Omit<\n  TimeDimension,\n  'dimension'\n> & {\n  dimension: CubeRecordQueryTimeDimension<N>;\n};\n\n/**\n * Query parameters for the useCubeRecordQuery hook\n */\nexport interface CubeRecordQueryParams<N extends CubeRecordName> {\n  measures?: CubeRecordQueryMeasure<N>[];\n  dimensions?: CubeRecordQueryDimension<N>[];\n  filters?: CubeRecordQueryFilter<N>[];\n  segments?: string[];\n  timeDimensions?: CubeRecordTimeDimensionParam<N>[];\n  limit?: number;\n  offset?: number;\n  order?: CubeRecordOrder<N>;\n  timezone?: string;\n  renewQuery?: boolean;\n  ungrouped?: boolean;\n  total?: boolean;\n}\n\n/**\n * Result of the useCubeRecordQuery hook\n */\nexport interface CubeRecordQueryResult<\n  N extends CubeRecordName,\n  M extends CubeRecordQueryMeasure<N>[] = [],\n  D extends CubeRecordQueryDimension<N>[] = [],\n  Strip extends boolean = true,\n> {\n  isLoading: boolean;\n  error?: Error;\n  resultSet?: ResultSet;\n  refetch: () => Promise<void>;\n  // TODO: Use a single type that handles both stripped and non-stripped cases.\n  data: (Strip extends true\n    ? CubeRecordQueryRow<N, M, D>\n    : RemapKeysWithModel<N, CubeRecordQueryRow<N, M, D>>\n  )[];\n  totalResultCount: number | null;\n}\n\n/**\n * Formats filters for Cube.js query\n */\nconst formatFilters = <N extends CubeRecordName>(\n  filters: CubeRecordQueryFilter<N>[],\n  cubeRecordName: string\n) => {\n  return filters.map((filter) => {\n    const member = filter.member.includes('.')\n      ? filter.member\n      : `${cubeRecordName}.${filter.member}`;\n\n    if ('values' in filter && filter.values) {\n      return {\n        member,\n        operator: filter.operator,\n        values: filter.values,\n      };\n    }\n\n    return {\n      member,\n      operator: filter.operator,\n    };\n  });\n};\n\n/**\n * Formats result set data by removing cube name prefixes from keys\n */\nconst formatResultSet = <_N extends CubeRecordName>(\n  resultSet: ResultSet | null | undefined,\n  cubeRecordName: string,\n  strip: boolean\n): Record<string, unknown>[] => {\n  if (!resultSet) {\n    return [];\n  }\n\n  const data = resultSet.tablePivot();\n\n  if (!strip) {\n    // Keep as-is\n    return data as unknown as Record<string, unknown>[];\n  }\n\n  return data.map((row) => {\n    const formattedRow: Record<string, unknown> = {};\n\n    for (const key in row) {\n      if (Object.hasOwn(row, key)) {\n        // Remove cube name prefix (e.g., \"users.id\" -> \"id\")\n        const cleanKey = key.startsWith(`${cubeRecordName}.`)\n          ? key.substring(cubeRecordName.length + 1)\n          : key;\n        formattedRow[cleanKey] = row[key];\n      }\n    }\n\n    return formattedRow;\n  });\n};\n\nexport type UseCubeRecordFormattingOptions = {\n  stripModelPrefix?: boolean;\n};\n\nexport type UseCubeRecordOptions = UseCoreCubeQueryOptions & UseCubeRecordFormattingOptions;\n\nexport type UseCubeRecordQueryProps<\n  N extends CubeRecordName,\n  M extends CubeRecordQueryMeasure<N>[] = [],\n  D extends CubeRecordQueryDimension<N>[] = [],\n> = {\n  model: N;\n  query: CubeRecordQueryParams<N> & {\n    measures?: M;\n    dimensions?: D;\n  };\n  options?: UseCubeRecordOptions;\n};\n\n/**\n * A strongly-typed wrapper around Cube.js useCubeQuery hook for CubeRecords\n *\n * @param cubeRecordName - The name of the cube record\n * @param query - Query parameters including measures, dimensions, filters, etc.\n * @returns Strongly typed query result with data, loading state, and error handling\n */\n// Overloads for better type narrowing based on options.stripModelPrefix\nexport function useCubeRecordQuery<\n  N extends CubeRecordName,\n  M extends CubeRecordQueryMeasure<N>[] = [],\n  D extends CubeRecordQueryDimension<N>[] = [],\n>(props: UseCubeRecordQueryProps<N, M, D> & {\n  options?: UseCubeRecordOptions & { stripModelPrefix?: true | undefined };\n}): CubeRecordQueryResult<N, M, D, true>;\n\nexport function useCubeRecordQuery<\n  N extends CubeRecordName,\n  M extends CubeRecordQueryMeasure<N>[] = [],\n  D extends CubeRecordQueryDimension<N>[] = [],\n>(props: UseCubeRecordQueryProps<N, M, D> & {\n  options: UseCubeRecordOptions & { stripModelPrefix: false };\n}): CubeRecordQueryResult<N, M, D, false>;\n\nexport function useCubeRecordQuery<\n  N extends CubeRecordName,\n  M extends CubeRecordQueryMeasure<N>[] = [],\n  D extends CubeRecordQueryDimension<N>[] = [],\n>({\n  model: cubeRecordName,\n  query,\n  options,\n}: UseCubeRecordQueryProps<N, M, D> & { options?: UseCubeRecordOptions }): CubeRecordQueryResult<N, M, D, boolean> {\n  // Build the Cube.js query\n  const cubeQuery: CoreCubeQuery = {\n    measures: query.measures?.map((measure) =>\n      measure.includes('.') ? measure : `${cubeRecordName}.${measure}`\n    ),\n    dimensions: query.dimensions?.map((dimension) =>\n      dimension.includes('.') ? dimension : `${cubeRecordName}.${dimension}`\n    ),\n    filters: query.filters\n      ? formatFilters(query.filters, cubeRecordName)\n      : undefined,\n    segments: query.segments,\n    timeDimensions: query.timeDimensions?.map((td) => ({\n      ...td,\n      dimension: td.dimension.includes('.')\n        ? td.dimension\n        : `${cubeRecordName}.${td.dimension}`,\n    })),\n    limit: query.limit,\n    offset: query.offset,\n    order: query.order\n      ? Object.entries(query.order).reduce<Record<string, 'asc' | 'desc'>>(\n          (acc, [key, direction]) => {\n            const member = key.includes('.') ? key : `${cubeRecordName}.${key}`;\n            acc[member] = direction as 'asc' | 'desc';\n            return acc;\n          },\n          {}\n        )\n      : undefined,\n    timezone: query.timezone,\n    renewQuery: query.renewQuery,\n    ungrouped: query.ungrouped,\n    total: query.total,\n  };\n\n  const hasStripFlag =\n    options != null && Object.hasOwn(options as object, 'stripModelPrefix');\n  const { stripModelPrefix = true, ...coreOptions } = options ?? {};\n  const forwardedOptions = hasStripFlag ? coreOptions : options;\n\n  // Use the core Cube.js query hook\n  const { resultSet, isLoading, error, refetch } = useCoreCubeQuery(\n    cubeQuery,\n    forwardedOptions\n  );\n\n  // Format the result data\n  const formattedData = formatResultSet(resultSet, cubeRecordName, stripModelPrefix);\n  const totalResultCount = resultSet?.totalRows() ?? null;\n\n  // Cast to strongly typed result based on strip flag (overloads drive the API type)\n  const data = formattedData as unknown as (\n    | CubeRecordQueryRow<N, M, D>[]\n    | RemapKeysWithModel<N, CubeRecordQueryRow<N, M, D>>[]\n  );\n\n  return {\n    isLoading,\n    error: error as Error | undefined,\n    resultSet: resultSet as ResultSet | undefined,\n    refetch,\n    data: data,\n    totalResultCount,\n  };\n}\n"],"mappings":"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","names":["useCoreCubeQuery"]}