import { Client } from 'soap' import { Value as StatementValue, ValueKey as StatementValueKey } from './value' import { pql, PQLOptions } from './pql' export type GetByStatementResponseResult> = F extends GetByStatementAsync ? T : never interface GetByStatementAsync { ( getByStatement: GetByStatement, ): Promise< [ result: GetByStatementResponse, rawResponse: any, soapHeader: any, rawRequest: any, ] > } export interface GetByStatement { filterStatement?: FilterStatement } interface FilterStatement { query?: string values?: Array } interface Values { key?: string value?: Value } interface Value {} export interface GetByStatementResponse { rval?: Rval } interface Rval { totalResultSetSize?: number startIndex?: number results?: Array } type ServiceMethod = `get${Capitalize}ByStatementAsync` type GetByStatementMethodNames = keyof { [Key in keyof C as Parameters extends [GetByStatement, ...unknown[]] ? Key extends `get${infer T}ByStatementAsync` ? Uncapitalize : never : never]: unknown } /** * Query a service wth PQL options. * * If a client's method matches that of a usual query statement, * using this function will infer the query object. * * @example * ``` * getByStatement(client, 'lineItems', { * where: { * id: 123 * } * }) * ``` * Is syntactical sugar for: * ``` * client.getLineItemsByStatementAsync({ * filterStatement: { * query: pql({ * where: { * id: 123 * } * }) * } * }) * ``` */ export function getByStatement< C extends Client, S extends GetByStatementMethodNames, V extends StatementValue = StatementValue, Args extends unknown[] = [], >( client: C, service: S, query: ServiceMethod extends keyof C ? PQLOptions< GetByStatementResponseResult]>, StatementValueKey > : never, values?: V[], ...args: Args ): ServiceMethod extends keyof C ? ReturnType]> : never { return client[ `get${(service as string)[0].toUpperCase()}${(service as string).slice(1)}ByStatementAsync` ]( { filterStatement: { query: pql(query), values, }, }, ...args, ) }