{"version":3,"file":"call-tail.cjs","sources":["../../../../../src/core/actions/v3/call-tail.ts"],"sourcesContent":["import type { ActionOptions } from '../abstract-action'\nimport type { TypeCallParams } from '../../../types/http'\nimport { AbstractAction } from '../abstract-action'\nimport { Result } from '../../result'\nimport { SdkError } from '../../sdk-error'\nimport { keysetPaginate, KeysetPaginationError } from './_keyset-paginate'\n\nexport type ActionCallTailV3 = ActionOptions & {\n  method: string\n  params?: Omit<TypeCallParams, 'pagination' | 'order' | 'cursor'>\n  cursorField?: string\n  order?: 'ASC' | 'DESC' | 'asc' | 'desc' | string\n  customKeyForResult?: string\n  requestId?: string\n  limit?: number\n  initialValue?: number | string\n}\n\n/**\n * Fast data retrieval via the native `tail` (keyset cursor) action, without\n * counting the total number of records. `restApi:v3`\n *\n * The eager counterpart of `fetchTail`: it walks the same native\n * `cursor: { field, value, order, limit }` pagination and returns every record\n * as a single array. See the v3 reference §6.2. The cursor field MUST NOT appear\n * in `filter`.\n */\nexport class CallTailV3 extends AbstractAction {\n  /**\n   * Returns every record of a `tail` method as one array.\n   *\n   * @template T - The type of the elements of the returned array (default is `unknown`).\n   *\n   * @param {ActionCallTailV3} options - parameters for executing the request.\n   *     - `method: string` - A REST API `tail` method name (for example: `main.eventlog.tail`).\n   *     - `params?: Omit<TypeCallParams, 'pagination' | 'order' | 'cursor'>` - Request parameters\n   *         (`filter`, `select`). `pagination`, `order` and `cursor` are managed by this helper.\n   *         The cursor field must NOT be used in `filter`.\n   *     - `cursorField?: string` - The DTO field that drives the cursor. Default is `id`.\n   *     - `order?: 'ASC' | 'DESC'` - Cursor direction. Default is `ASC`. For `DESC` you MUST pass\n   *         `initialValue` (the server pages by `field < value`, so the default `0` returns nothing).\n   *     - `customKeyForResult?: string` - The key the response groups rows under. Default is `items`.\n   *     - `requestId?: string` - Unique request identifier for tracking.\n   *     - `limit?: number` - How many records to retrieve at a time. Default is `50`. Maximum is `1000`.\n   *     - `initialValue?: number | string` - Cursor start value for the first page. Default is `0`\n   *         (valid for ascending numeric fields); required for `DESC` and for non-numeric fields.\n   *\n   * @returns {Promise<Result<T[]>>} A promise that resolves to the result of an REST API call.\n   *\n   * @example\n   * const response = await b24.actions.v3.callTail.make<{ id: string }>({\n   *   method: 'main.eventlog.tail',\n   *   params: { select: ['id', 'auditType'] },\n   *   cursorField: 'id',\n   *   customKeyForResult: 'items'\n   * })\n   * if (!response.isSuccess) {\n   *   throw new Error(`Problem: ${response.getErrorMessages().join('; ')}`)\n   * }\n   * console.log(`Result: ${response.getData()?.length}`)\n   */\n  public override async make<T = unknown>(options: ActionCallTailV3): Promise<Result<T[]>> {\n    const batchSize = options?.limit ?? 50\n    const result: Result<T[]> = new Result()\n\n    const cursorField = options?.cursorField ?? 'id'\n    const order = options?.order ?? 'ASC'\n    const customKeyForResult = options?.customKeyForResult ?? 'items'\n    const params = options?.params ?? {}\n\n    // DESC keyset needs an explicit start: the server pages by `field < value`,\n    // so the default first-page value 0 would match nothing for a non-negative\n    // field. Require `initialValue` (the type maximum / newest value) for DESC.\n    if (/desc/i.test(order) && options?.initialValue === undefined) {\n      throw new SdkError({\n        code: 'JSSDK_CORE_B24_CALL_TAIL_DESC_REQUIRES_INITIAL_VALUE',\n        description: 'callTail.make: order \"DESC\" requires an explicit `initialValue` (the server pages by `field < value`, so the default 0 returns nothing). Pass `initialValue` set to the type maximum / newest value.',\n        status: 500\n      })\n    }\n\n    // Cursor field must not also live in `filter` (server rejects with\n    // INVALIDFILTEREXCEPTION). Detection covers only the short-form triples.\n    if (Array.isArray(params['filter']) && params['filter'].some((c: any) => Array.isArray(c) && c[0] === cursorField)) {\n      this._logger.warning(`callTail.make: the cursor field \"${cursorField}\" must not appear in \\`filter\\` — the server orders and pages by it and will reject a filter on the same field (INVALIDFILTEREXCEPTION). Remove it from \\`filter\\`.`)\n    }\n\n    // Cursor field must be readable to advance. Append it to an explicit\n    // `select`; warn for a non-default cursorField when `select` is omitted.\n    let select = params['select'] as string[] | undefined\n    if (Array.isArray(select)) {\n      if (!select.includes(cursorField)) {\n        select = [...select, cursorField]\n      }\n    } else if (cursorField !== 'id') {\n      this._logger.warning(`callTail.make: no \\`select\\` provided with a non-default cursorField \"${cursorField}\" — make sure it is in the server's default field set, otherwise pass \\`select\\` including \"${cursorField}\" so the cursor can advance.`)\n    }\n\n    const { select: _ignoredSelect, ...restParams } = params as TypeCallParams\n\n    const allItems: T[] = []\n    try {\n      for await (const page of keysetPaginate<T>(this._b24, this._logger, {\n        method: options.method,\n        requestId: options.requestId,\n        customKeyForResult,\n        initialCursor: options?.initialValue ?? 0,\n        // Native keyset: drive the server's `cursor: { field, value, order, limit }`.\n        buildParams: cursor => ({\n          ...restParams,\n          ...(select ? { select } : {}),\n          cursor: { field: cursorField, value: cursor, order, limit: batchSize }\n        }),\n        // Advance by the raw cursor-field value from the last item; a missing\n        // value (cursorField not selected / wrong name) stops the walk.\n        readNextCursor: lastItem => lastItem[cursorField] ?? null,\n        noCursorWarning: `callTail.make: pagination stops here — no value could be read from the returned items via cursorField \"${cursorField}\". Make sure cursorField matches a field present in the response (and in \\`select\\`).`,\n        errorLabel: 'callTailMethod'\n      })) {\n        for (const item of page) {\n          allItems.push(item)\n        }\n      }\n    } catch (error) {\n      if (error instanceof KeysetPaginationError) {\n        for (const [index, err] of error.errors) {\n          result.addError(err, index)\n        }\n      } else {\n        throw error\n      }\n    }\n\n    return result.setData(allItems)\n  }\n}\n"],"names":["AbstractAction","result","Result","SdkError","keysetPaginate","KeysetPaginationError"],"mappings":"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"}