import { Query, QueryResponse } from './query'; /** * Service for executing queries using the query objects API. * * The {@link QueryService} provides direct access to the Lime CRM query engine, * allowing you to execute complex queries with filtering, sorting, pagination, * and aggregation. This is the most powerful way to query objects when you need * advanced filtering or aggregation capabilities. * * **When to use QueryService vs LimeObjectRepository:** * - Use {@link QueryService} for complex queries with aggregations, custom response formats, * or when you need full control over the query structure * - Use {@link LimeObjectRepository.loadObjects} for simpler object loading with filters, * as it provides automatic state management and a simpler API * * @example Get active deals * ```ts * import { Operator, PlatformServiceName } from '@limetech/lime-web-components'; * * const queryService = platform.get(PlatformServiceName.Query); * * const response = await queryService.execute({ * limetype: 'deal', * filter: { * key: 'status', * op: Operator.EQUALS, * exp: 'active', * }, * responseFormat: { * object: { name: null, value: null }, * }, * }); * * console.log(`Found ${response.objects.length} active deals`); * ``` * * @example Complex query with pagination and aggregates * ```ts * import { * AggregateOperator, * Operator, * PlatformServiceName, * } from '@limetech/lime-web-components'; * * const queryService = platform.get(PlatformServiceName.Query); * * const response = await queryService.execute({ * limetype: 'deal', * limit: 50, * offset: 0, * filter: { * op: Operator.AND, * exp: [ * { * key: 'status', * op: Operator.EQUALS, * exp: 'active', * }, * { * key: 'value', * op: Operator.GREATER_OR_EQUAL, * exp: 100_000, * }, * ], * }, * orderBy: [{ name: 'value', direction: 'DESC' }], * responseFormat: { * object: { name: null, value: null }, * aggregates: { * totals: { * total_value: { op: AggregateOperator.Sum, key: 'value' }, * deal_count: { op: AggregateOperator.Count }, * }, * }, * }, * }); * * const [totals] = response.aggregates.totals; * console.log(`Total: ${totals?.total_value}`); * console.log(`Count: ${totals?.deal_count}`); * ``` * * @example Query with nested AND/OR logic * ```ts * import { Operator, PlatformServiceName } from '@limetech/lime-web-components'; * * const queryService = platform.get(PlatformServiceName.Query); * * const response = await queryService.execute({ * limetype: 'ticket', * filter: { * op: Operator.AND, * exp: [ * { * op: Operator.OR, * exp: [ * { key: 'status', op: Operator.EQUALS, exp: 'open' }, * { key: 'status', op: Operator.EQUALS, exp: 'in_progress' }, * ], * }, * { * key: 'priority', * op: Operator.IN, * exp: ['high', 'urgent'], * }, * { * op: Operator.NOT, * exp: { key: 'is_archived', op: Operator.EQUALS, exp: true }, * }, * ], * }, * responseFormat: { * object: { subject: null, priority: null }, * }, * }); * ``` * * @public * @group Query * @see {@link Query} for query configuration * @see {@link QueryResponse} for response format * @see {@link Expression} for building filter expressions * @see {@link LimeObjectRepository.loadObjects} for simpler object loading */ export interface QueryService { /** * Execute a query and return matching objects. * * Sends a query to the Lime CRM backend and returns the matching objects * along with any requested aggregate calculations. The query can include * complex filter expressions, sorting, pagination, and aggregations. * * The response type is inferred from the query's `responseFormat`. Define * the query inline or with `satisfies Query` to keep the literal shape that * drives the inference. * * @param query - Query configuration defining what to retrieve * @returns Promise resolving to the query results * * @example List companies in a city * ```ts * import { Operator, PlatformServiceName } from '@limetech/lime-web-components'; * * const queryService = platform.get(PlatformServiceName.Query); * * const response = await queryService.execute({ * limetype: 'company', * limit: 100, * filter: { * key: 'city', * op: Operator.EQUALS, * exp: 'Stockholm', * }, * orderBy: [{ name: 'name', direction: 'ASC' }], * responseFormat: { * object: { name: null }, * }, * }); * * for (const company of response.objects) { * console.log(company.name); * } * ``` * * @see {@link Query} for query structure * @see {@link QueryResponse} for response structure */ execute(query: Q): Promise>; }