{"version":3,"file":"aggregate.cjs","sources":["../../../../../src/core/actions/v3/aggregate.ts"],"sourcesContent":["import type { ActionOptions } from '../abstract-action'\nimport type { TypeCallParams } from '../../../types/http'\nimport type { AjaxResult } from '../../http/ajax-result'\nimport { AbstractAction } from '../abstract-action'\nimport { Result } from '../../result'\nimport { SdkError } from '../../sdk-error'\n\n/**\n * The six aggregate functions the v3 `aggregate` action accepts (reference §7).\n * Anything else is rejected server-side with `UNKNOWNAGGREGATEFUNCTIONEXCEPTION`.\n */\nexport type AggregateFunctionV3 = 'sum' | 'avg' | 'min' | 'max' | 'count' | 'countDistinct'\n\nconst AGGREGATE_FUNCTIONS: readonly AggregateFunctionV3[] = ['sum', 'avg', 'min', 'max', 'count', 'countDistinct']\n\n/**\n * Per-function field selection. Two forms (reference §7):\n *   - list: `['amount', 'qty']` — default alias `<func>_<field>`;\n *   - map:  `{ amount: 'totalAmount' }` — custom alias.\n * Note: the response keys buckets by the **field name**, not the alias.\n */\nexport type AggregateSelectV3 = Partial<Record<AggregateFunctionV3, string[] | Record<string, string>>>\n\n/**\n * Aggregate response buckets: `{ sum: { amount: 12345 }, count: { id: 87 } }`.\n * Keyed by function, then by field name.\n */\nexport type AggregateResultV3 = Partial<Record<AggregateFunctionV3, Record<string, number>>>\n\n/** @experimental options for the v3 `aggregate` action — unverified live (see {@link AggregateV3}). */\nexport type ActionAggregateV3 = ActionOptions & {\n  method: string\n  select: AggregateSelectV3\n  params?: Pick<TypeCallParams, 'filter'>\n  requestId?: string\n}\n\n/**\n * Runs the v3 `aggregate` action for modules that support it (reference §7).\n * `restApi:v3`\n *\n * @experimental NOT verified against a live portal — no module on the SDK's\n * reference test portal currently exposes an `*.aggregate` endpoint. The\n * request/response shapes follow the published v3 reference and may change once\n * verified live; pin to a version if you depend on the exact shape.\n */\nexport class AggregateV3 extends AbstractAction {\n  /**\n   * @param {ActionAggregateV3} options\n   *     - `method: string` - an `*.aggregate` method name.\n   *     - `select: AggregateSelectV3` - per-function field selection (`sum`/`avg`/`min`/`max`/`count`/`countDistinct`).\n   *     - `params?: { filter }` - optional v3 filter (array-of-triples; use `FilterV3` to build it).\n   *     - `requestId?: string` - tracking id.\n   *\n   * @returns {Promise<Result<AggregateResultV3>>} buckets keyed by function then field name.\n   *\n   * @example\n   * const response = await b24.actions.v3.aggregate.make({\n   *   method: 'some.entity.aggregate',\n   *   select: { sum: { amount: 'totalAmount' }, count: ['id'] },\n   *   params: { filter: FilterV3.build(FilterV3.eq('status', 'NEW')) }\n   * })\n   * if (response.isSuccess) {\n   *   const total = response.getData()?.sum?.amount\n   * }\n   */\n  public override async make(options: ActionAggregateV3): Promise<Result<AggregateResultV3>> {\n    const result: Result<AggregateResultV3> = new Result()\n\n    const select = options?.select ?? {}\n    for (const fn of Object.keys(select)) {\n      if (!AGGREGATE_FUNCTIONS.includes(fn as AggregateFunctionV3)) {\n        throw new SdkError({\n          code: 'JSSDK_AGGREGATE_V3_INVALID_FUNCTION',\n          description: `AggregateV3: \"${fn}\" is not an aggregate function — use one of ${AGGREGATE_FUNCTIONS.join(' ')}.`,\n          status: 400\n        })\n      }\n      const fields = (select as Record<string, unknown>)[fn]\n      if (!Array.isArray(fields) && (typeof fields !== 'object' || fields === null)) {\n        throw new SdkError({\n          code: 'JSSDK_AGGREGATE_V3_INVALID_SELECT',\n          description: `AggregateV3: select.${fn} must be a string[] (default alias) or a { field: alias } map.`,\n          status: 400\n        })\n      }\n    }\n\n    // `TypeCallParams.select` is typed `string[]` for the `list` methods, but the\n    // v3 `aggregate` action takes an object select (`{ sum: { field: alias } }`);\n    // the server accepts it, hence the cast.\n    const params: TypeCallParams = { select: select as unknown as TypeCallParams['select'] }\n    if (options?.params?.filter) {\n      params.filter = options.params.filter\n    }\n\n    const response: AjaxResult<unknown> = await this._b24.actions.v3.call.make<unknown>({\n      method: options.method,\n      params,\n      requestId: options.requestId\n    })\n\n    if (!response.isSuccess) {\n      this._logger.error('aggregateMethod', {\n        method: options.method,\n        requestId: options.requestId,\n        messages: response.getErrorMessages()\n      })\n      for (const [index, error] of response.errors) {\n        result.addError(error, index)\n      }\n      return result\n    }\n\n    // The reference (§7) nests one extra level: { result: { result: { <func>: {...} } } }.\n    // `getData()` unwraps the outer `result`, so the buckets are at `payload.result`.\n    // This shape is unverified against a live portal — be defensive: if a portal\n    // returns the buckets at a single level instead, fall back to the payload and\n    // warn rather than silently returning empty data.\n    const payload = response.getData()?.result as any\n    let buckets: AggregateResultV3\n    if (payload && typeof payload === 'object' && 'result' in payload) {\n      buckets = (payload.result ?? {}) as AggregateResultV3\n    } else if (payload && typeof payload === 'object') {\n      this._logger.warning(`aggregate.make: response has no nested 'result.result' envelope (the v3 reference §7 specifies double nesting); falling back to the top-level 'result'. method=${options.method}`)\n      buckets = payload as AggregateResultV3\n    } else {\n      buckets = {}\n    }\n    return result.setData(buckets)\n  }\n}\n"],"names":["AbstractAction","result","Result","SdkError"],"mappings":";;;;;;;;;;;;;;;;AAaA,MAAM,sBAAsD,CAAC,KAAA,EAAO,OAAO,KAAA,EAAO,KAAA,EAAO,SAAS,eAAe,CAAA;AAiC1G,MAAM,oBAAoBA,6BAAA,CAAe;AAAA,EA9ChD;AA8CgD,IAAA,MAAA,CAAA,IAAA,EAAA,aAAA,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoB9C,MAAsB,KAAK,OAAA,EAAgE;AACzF,IAAA,MAAMC,QAAA,GAAoC,IAAIC,aAAA,EAAO;AAErD,IAAA,MAAM,MAAA,GAAS,OAAA,EAAS,MAAA,IAAU,EAAC;AACnC,IAAA,KAAA,MAAW,EAAA,IAAM,MAAA,CAAO,IAAA,CAAK,MAAM,CAAA,EAAG;AACpC,MAAA,IAAI,CAAC,mBAAA,CAAoB,QAAA,CAAS,EAAyB,CAAA,EAAG;AAC5D,QAAA,MAAM,IAAIC,iBAAA,CAAS;AAAA,UACjB,IAAA,EAAM,qCAAA;AAAA,UACN,aAAa,CAAA,cAAA,EAAiB,EAAE,oDAA+C,mBAAA,CAAoB,IAAA,CAAK,GAAG,CAAC,CAAA,CAAA,CAAA;AAAA,UAC5G,MAAA,EAAQ;AAAA,SACT,CAAA;AAAA,MACH;AACA,MAAA,MAAM,MAAA,GAAU,OAAmC,EAAE,CAAA;AACrD,MAAA,IAAI,CAAC,MAAM,OAAA,CAAQ,MAAM,MAAM,OAAO,MAAA,KAAW,QAAA,IAAY,MAAA,KAAW,IAAA,CAAA,EAAO;AAC7E,QAAA,MAAM,IAAIA,iBAAA,CAAS;AAAA,UACjB,IAAA,EAAM,mCAAA;AAAA,UACN,WAAA,EAAa,uBAAuB,EAAE,CAAA,8DAAA,CAAA;AAAA,UACtC,MAAA,EAAQ;AAAA,SACT,CAAA;AAAA,MACH;AAAA,IACF;AAKA,IAAA,MAAM,MAAA,GAAyB,EAAE,MAAA,EAAsD;AACvF,IAAA,IAAI,OAAA,EAAS,QAAQ,MAAA,EAAQ;AAC3B,MAAA,MAAA,CAAO,MAAA,GAAS,QAAQ,MAAA,CAAO,MAAA;AAAA,IACjC;AAEA,IAAA,MAAM,WAAgC,MAAM,IAAA,CAAK,KAAK,OAAA,CAAQ,EAAA,CAAG,KAAK,IAAA,CAAc;AAAA,MAClF,QAAQ,OAAA,CAAQ,MAAA;AAAA,MAChB,MAAA;AAAA,MACA,WAAW,OAAA,CAAQ;AAAA,KACpB,CAAA;AAED,IAAA,IAAI,CAAC,SAAS,SAAA,EAAW;AACvB,MAAA,IAAA,CAAK,OAAA,CAAQ,MAAM,iBAAA,EAAmB;AAAA,QACpC,QAAQ,OAAA,CAAQ,MAAA;AAAA,QAChB,WAAW,OAAA,CAAQ,SAAA;AAAA,QACnB,QAAA,EAAU,SAAS,gBAAA;AAAiB,OACrC,CAAA;AACD,MAAA,KAAA,MAAW,CAAC,KAAA,EAAO,KAAK,CAAA,IAAK,SAAS,MAAA,EAAQ;AAC5C,QAAAF,QAAA,CAAO,QAAA,CAAS,OAAO,KAAK,CAAA;AAAA,MAC9B;AACA,MAAA,OAAOA,QAAA;AAAA,IACT;AAOA,IAAA,MAAM,OAAA,GAAU,QAAA,CAAS,OAAA,EAAQ,EAAG,MAAA;AACpC,IAAA,IAAI,OAAA;AACJ,IAAA,IAAI,OAAA,IAAW,OAAO,OAAA,KAAY,QAAA,IAAY,YAAY,OAAA,EAAS;AACjE,MAAA,OAAA,GAAW,OAAA,CAAQ,UAAU,EAAC;AAAA,IAChC,CAAA,MAAA,IAAW,OAAA,IAAW,OAAO,OAAA,KAAY,QAAA,EAAU;AACjD,MAAA,IAAA,CAAK,OAAA,CAAQ,OAAA,CAAQ,CAAA,kKAAA,EAAkK,OAAA,CAAQ,MAAM,CAAA,CAAE,CAAA;AACvM,MAAA,OAAA,GAAU,OAAA;AAAA,IACZ,CAAA,MAAO;AACL,MAAA,OAAA,GAAU,EAAC;AAAA,IACb;AACA,IAAA,OAAOA,QAAA,CAAO,QAAQ,OAAO,CAAA;AAAA,EAC/B;AACF;;;;"}