@iyulab/flex-table 0.58.0 → 0.60.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,44 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.60.0] - 2026-10-07
4
+
5
+ ### Added
6
+
7
+ - **`fetchAll(options?)` on both data sources and both hooks** — the whole result of the current sort, search and
8
+ fixed filter, for exporting what a list shows. A server-paged table holds one page, so its export was one page: a
9
+ 1,240-row register came out as 20 rows with nothing saying so. The OData source asks without `$top`/`$skip` and
10
+ follows `@odata.nextLink` to the end (the same origin and repeat checks as a page read). `maxRows` (default
11
+ `100000`, `DEFAULT_MAX_ROWS`) rejects with `RowLimitError` instead of cutting — on the first response when the server
12
+ counts (`@odata.count`). `signal` and `onProgress(loaded, total)` too. It leaves the source state alone and needs no
13
+ subscriber. The array source returns the searched and sorted rows under the same contract.
14
+ - **The table exports rows it is given**: `exportToString` / `exportToBlob` / `exportToFile` take `{ rows }` — those
15
+ rows with the table's visible columns and formats (`exportToFile` gained an `options` argument). With the above:
16
+ `table.exportToFile('xlsx', 'x.xlsx', { rows: await source.fetchAll() })`.
17
+ - `exportDataBlob` (compressed XLSX) and `downloadBlob` are exported from the root entry, for an export without a table.
18
+ - `SourceRequestError` (its `failure` is the `SourceError`) and `RowLimitError` are exported from `./odata` and
19
+ `./react` (`RowLimitError` also from `./array`), and `SourceError` / `SourceErrorDetail` types from `./odata`.
20
+ - `buildODataQuery` builds the whole-result query when `pageSize` is left out (`page` and `pageSize` are optional).
21
+
22
+ ## [0.59.0] - 2026-10-07
23
+
24
+ ### Changed (breaking)
25
+
26
+ - **A plain click on a body cell fires `row-activate`** (`via: 'click'`), as Enter on a non-editable cell does
27
+ (`via: 'keyboard'`) and as `u-rich-table` does. A read-only list had no pointer way to open a row, so it opened rows on
28
+ `cell-select` — which is focus and also fires when Tab arrives on the grid: one Tab into the table opened the first
29
+ row. A Shift / Ctrl / Cmd click (extends the selection), the click that ends a drag, and a click on a control the
30
+ cell renders (a link, a button, a field) do not activate. A listener that only wants Enter checks
31
+ `e.detail.via === 'keyboard'`.
32
+ - `cell-select` carries the row's `id` — `row` is the visible position, which is not the row in `data` once a client
33
+ sort or filter is on.
34
+ - Requires `@iyulab/components` 2.15.0 (the shared «pressed a control» test, `isFromControl`).
35
+
36
+ ### Migration
37
+
38
+ - Open rows on `row-activate`, not `cell-select`.
39
+ - If you listened to `row-activate` for Enter only (a picker that confirms on Enter), add
40
+ `if (e.detail.via !== 'keyboard') return;`.
41
+
3
42
  ## [0.58.0] - 2026-10-07
4
43
 
5
44
  ### Added
package/README.md CHANGED
@@ -288,9 +288,29 @@ Default is `false`, matching `clear-undo-on-data-change`.
288
288
 
289
289
  | Method | Returns | Description |
290
290
  |--------|---------|-------------|
291
- | `exportToString(format, options?)` | `string \| Uint8Array` | Export to `'csv'` / `'tsv'` / `'json'` (a string) or `'xlsx'` (bytes, uncompressed). Pass `{ selectionOnly: true }` for selection range |
291
+ | `exportToString(format, options?)` | `string \| Uint8Array` | Export to `'csv'` / `'tsv'` / `'json'` (a string) or `'xlsx'` (bytes, uncompressed). Pass `{ selectionOnly: true }` for selection range, or `{ rows }` to export rows the table does not hold (see below) |
292
292
  | `exportToBlob(format, options?)` | `Promise<Blob>` | The same export as a `Blob` of the format's MIME type — `'xlsx'` is DEFLATE-compressed |
293
- | `exportToFile(format, filename?)` | `Promise<void>` | Export and trigger browser file download (`'xlsx'` compressed) |
293
+ | `exportToFile(format, filename?, options?)` | `Promise<void>` | Export and trigger browser file download (`'xlsx'` compressed) |
294
+
295
+ The table exports the rows it holds — the filtered rows in sort order, or the selection. **A server-paged table
296
+ (`data-mode="server"`) holds one page**, so its export is one page. To export what the list shows — the whole result
297
+ of the current sort, search and filter — read it from the source and hand it to the table, which keeps its own
298
+ columns and formats:
299
+
300
+ ```ts
301
+ import { RowLimitError } from '@iyulab/flex-table/odata';
302
+
303
+ try {
304
+ const rows = await orders.fetchAll({ maxRows: 50_000 }); // follows @odata.nextLink to the end
305
+ await table.exportToFile('xlsx', 'orders.xlsx', { rows });
306
+ } catch (e) {
307
+ if (e instanceof RowLimitError) showMessage(e.failure.message); // more rows than maxRows — nothing is cut silently
308
+ else throw e;
309
+ }
310
+ ```
311
+
312
+ Without a table, `exportDataBlob(rows, columns, format)` and `downloadBlob(blob, filename)` (root entry) do the same
313
+ — `exportData` stays synchronous and writes XLSX uncompressed.
294
314
 
295
315
  ## Events
296
316
 
@@ -303,7 +323,7 @@ type-checks without a cast. The React wrapper's `on*` props carry the same types
303
323
 
304
324
  | Event | Detail | Description |
305
325
  |-------|--------|-------------|
306
- | `cell-select` | `{ row, col }` or `null` | Cell focus changed (`null` when no cell is active) |
326
+ | `cell-select` | `{ row, col, id }` or `null` | Cell focus changed (`null` when no cell is active). `row`/`col` are visible positions, `id` the row's id. Fires when keyboard focus arrives on the grid too — it is focus, not a choice: open rows on `row-activate` |
307
327
  | `cell-edit-start` | `{ row, col, key, value }` | Cell editing started |
308
328
  | `cell-edit-commit` | `{ row, col, key, oldValue, newValue }` | Cell value committed |
309
329
  | `cell-edit-cancel` | `{ row, col }` | Cell edit cancelled (Escape, or its row left `data`). `row` is the data index (`-1` once the row is gone) |
@@ -315,7 +335,7 @@ type-checks without a cast. The React wrapper's `on*` props carry the same types
315
335
  |-------|--------|-------------|
316
336
  | `row-add` | `{ row, index }` | Row added |
317
337
  | `row-delete` | `{ indices, rows }` | Rows deleted |
318
- | `row-activate` | `{ row, id, index, col, key }` | Enter pressed on a non-editable cell — the grid's own contract for "activate this row" (e.g. navigate to a detail view), guaranteed even though the internal Enter handler prevents the keystroke from reliably reaching a listener the host attaches to the same element |
338
+ | `row-activate` | `{ row, id, via, index, col, key }` | "Open this row" (e.g. navigate to a detail view): a plain click on a body cell (`via: 'click'`), or Enter on a non-editable cell (`via: 'keyboard'`). Not a Shift / Ctrl / Cmd click (those extend the selection), the click that ends a drag, or a click on a control the cell renders (a link, a button). The grid's own contract — its Enter handler keeps the keystroke from reliably reaching a listener the host attaches to the same element |
319
339
  | `batch-update` | `{ changes: [{ row, key, oldValue, newValue }] }` | Batch update applied |
320
340
  | `row-reorder` | `{ from, to }` | Row dragged to a new place (data indices) |
321
341
  | `data-import` | `{ count }` | Rows imported from a file |
@@ -834,6 +854,7 @@ The hook returns:
834
854
  | `sortCriteria` / `onSortChange` | Bind `onSortChange` to the table's `sort-change` event |
835
855
  | `search` / `setSearch` | Current search term and its setter (resets to page 0) |
836
856
  | `refresh` | Re-run the current request |
857
+ | `fetchAll` | The whole result of the current conditions — the source's `fetchAll` (below), for exporting what the list shows |
837
858
 
838
859
  #### Search semantics
839
860
 
@@ -888,6 +909,7 @@ off(); // the last unsu
888
909
  | `setSort(criteria)` / `setSearch(term)` | Change the sort or search and go back to page 0 |
889
910
  | `refresh()` | Re-read with the same conditions (nothing while `enabled: false`) |
890
911
  | `update(url, options)` | New options. Only a changed request re-reads; a changed `fixedFilter` value goes back to page 0; a changed `pageSize` value takes effect (page 0), the same value again keeps the size `setPageSize` set; `initial*` are read at creation only |
912
+ | `fetchAll(options?)` | `Promise<T[]>` — **the whole result of the current sort, search and fixed filter**: no `$top`/`$skip`, following `@odata.nextLink` to the end. For an export of what the list shows. Leaves the state alone and needs no subscriber. Options: `maxRows` (default `100000` — past it, it rejects with `RowLimitError` instead of cutting; when the server counts, on the first response), `signal`, `onProgress(loaded, total)`. A failed request rejects with `SourceRequestError` (`failure` is the `SourceError`) |
891
913
 
892
914
  Changes made in the same tick become one request with the final conditions, so `setSearch` followed by `setPage` does not send the intermediate one.
893
915
 
@@ -954,8 +976,8 @@ count after search (not a server-reported total), and `loading`/`error` are alwa
954
976
  "refresh" button wired unconditionally against either hook doesn't need a branch.
955
977
 
956
978
  Without React, `createArraySource(rows, options)` (`@iyulab/flex-table/array`) is the same source with the same
957
- members as `createODataSource` — `getState()`, `subscribe()`, `setPage`, `setPageSize`, `setSort`, `setSearch`, `refresh` (no-op) —
958
- plus `update(rows, options)` when the rows change. `ArraySourceController` binds it to a Lit element (from rows, or an existing source):
979
+ members as `createODataSource` — `getState()`, `subscribe()`, `setPage`, `setPageSize`, `setSort`, `setSearch`, `refresh` (no-op),
980
+ `fetchAll` (the whole searched and sorted result, same options and `RowLimitError`) — plus `update(rows, options)` when the rows change. `ArraySourceController` binds it to a Lit element (from rows, or an existing source):
959
981
 
960
982
  ```ts
961
983
  import { LitElement } from 'lit';
@@ -2,3 +2,6 @@ export { computeArrayView } from './view.js';
2
2
  export type { ComputeArrayViewOptions } from './view.js';
3
3
  export { createArraySource, ArraySourceController } from './source.js';
4
4
  export type { ArraySource, ArraySourceOptions } from './source.js';
5
+ export { DEFAULT_MAX_ROWS } from '../core/fetch-all.js';
6
+ export type { FetchAllOptions } from '../core/fetch-all.js';
7
+ export { RowLimitError } from '../core/source-error.js';
@@ -1,65 +1,73 @@
1
- import { i as e } from "../query-Dw4iO0ir.js";
2
- import { t } from "../view-DiLr-TdY.js";
1
+ import { n as e, t, u as n } from "../fetch-all-J37bOtgc.js";
2
+ import { n as r, t as i } from "../view-BtoXdUGF.js";
3
3
  //#region src/array/source.ts
4
- function n(n, r = {}) {
5
- let i = n, a = r, o = e({
6
- defaultOrderBy: r.defaultOrderBy,
7
- initialPage: r.initialPage ?? 0,
8
- initialSearch: r.initialSearch ?? "",
9
- initialSort: r.initialSort
10
- }), s = o.page, c = o.sortCriteria, l = o.search, u = r.pageSize ?? 20, d = p(), f = /* @__PURE__ */ new Set();
11
- function p() {
12
- let e = t(i, {
13
- search: l,
14
- sortCriteria: c,
15
- page: s,
16
- pageSize: u,
17
- columns: a.columns,
18
- searchFields: a.searchFields
19
- }), n = e.totalCount === 0 ? 0 : Math.ceil(e.totalCount / u) - 1;
20
- return s > n && (s = n), {
4
+ function a(e, t = {}) {
5
+ let a = e, o = t, s = n({
6
+ defaultOrderBy: t.defaultOrderBy,
7
+ initialPage: t.initialPage ?? 0,
8
+ initialSearch: t.initialSearch ?? "",
9
+ initialSort: t.initialSort
10
+ }), c = s.page, l = s.sortCriteria, u = s.search, d = t.pageSize ?? 20, f = m(), p = /* @__PURE__ */ new Set();
11
+ function m() {
12
+ let e = i(a, {
13
+ search: u,
14
+ sortCriteria: l,
15
+ page: c,
16
+ pageSize: d,
17
+ columns: o.columns,
18
+ searchFields: o.searchFields
19
+ }), t = e.totalCount === 0 ? 0 : Math.ceil(e.totalCount / d) - 1;
20
+ return c > t && (c = t), {
21
21
  data: e.data,
22
22
  totalCount: e.totalCount,
23
23
  loading: !1,
24
24
  error: null,
25
- page: s,
26
- pageSize: u,
27
- sortCriteria: c,
28
- search: l
25
+ page: c,
26
+ pageSize: d,
27
+ sortCriteria: l,
28
+ search: u
29
29
  };
30
30
  }
31
- function m() {
32
- d = p();
33
- for (let e of [...f]) e();
31
+ function h() {
32
+ f = m();
33
+ for (let e of [...p]) e();
34
34
  }
35
35
  return {
36
- getState: () => d,
36
+ getState: () => f,
37
37
  subscribe(e) {
38
- return f.add(e), () => {
39
- f.delete(e);
38
+ return p.add(e), () => {
39
+ p.delete(e);
40
40
  };
41
41
  },
42
42
  setPage(e) {
43
- s = e, m();
43
+ c = e, h();
44
44
  },
45
45
  setPageSize(e) {
46
- e !== u && (u = e, s = 0, m());
46
+ e !== d && (d = e, c = 0, h());
47
47
  },
48
48
  setSort(e) {
49
- c = e, s = 0, m();
49
+ l = e, c = 0, h();
50
50
  },
51
51
  setSearch(e) {
52
- l = e, s = 0, m();
52
+ u = e, c = 0, h();
53
53
  },
54
54
  refresh() {},
55
+ fetchAll(e) {
56
+ return r(a, {
57
+ search: u,
58
+ sortCriteria: l,
59
+ columns: o.columns,
60
+ searchFields: o.searchFields
61
+ }, e);
62
+ },
55
63
  update(e, t = {}) {
56
- t.pageSize !== void 0 && t.pageSize !== a.pageSize && t.pageSize !== u && (u = t.pageSize, s = 0), i = e, a = t, m();
64
+ t.pageSize !== void 0 && t.pageSize !== o.pageSize && t.pageSize !== d && (d = t.pageSize, c = 0), a = e, o = t, h();
57
65
  }
58
66
  };
59
67
  }
60
- var r = class {
61
- constructor(e, t, r = {}) {
62
- this.host = e, this.source = Array.isArray(t) ? n(t, r) : t, e.addController(this);
68
+ var o = class {
69
+ constructor(e, t, n = {}) {
70
+ this.host = e, this.source = Array.isArray(t) ? a(t, n) : t, e.addController(this);
63
71
  }
64
72
  get state() {
65
73
  return this.source.getState();
@@ -72,4 +80,4 @@ var r = class {
72
80
  }
73
81
  };
74
82
  //#endregion
75
- export { r as ArraySourceController, t as computeArrayView, n as createArraySource };
83
+ export { o as ArraySourceController, t as DEFAULT_MAX_ROWS, e as RowLimitError, i as computeArrayView, a as createArraySource };
@@ -3,6 +3,7 @@ import type { SortCriteria } from '../core/sorting.js';
3
3
  import type { DataRow } from '../models/types.js';
4
4
  import type { ODataSourceState } from '../odata/source.js';
5
5
  import type { UseArraySourceOptions } from './types.js';
6
+ import type { FetchAllOptions } from '../core/fetch-all.js';
6
7
  /** 메모리 소스의 설정 — `useArraySource` 의 옵션과 같다(`initial*` 은 만들 때만 읽는다). */
7
8
  export type ArraySourceOptions<T> = UseArraySourceOptions<T>;
8
9
  /** 메모리 소스 — `createODataSource` 와 같은 상태·조작 모양이라 같은 표 배선이 두 소스에서 돈다. */
@@ -23,6 +24,8 @@ export interface ArraySource<T> {
23
24
  refresh(): void;
24
25
  /** 행이나 설정이 바뀌었다 — 다시 계산한다. 결과가 줄어 지금 페이지가 없어지면 마지막 페이지로 내려온다. */
25
26
  update(data: T[], options?: ArraySourceOptions<T>): void;
27
+ /** 지금 검색·정렬의 결과 전체(페이지 없이) — `createODataSource` 의 `fetchAll` 과 같은 계약(상한 · 취소 · 진행). */
28
+ fetchAll(options?: FetchAllOptions): Promise<T[]>;
26
29
  }
27
30
  /**
28
31
  * 이미 메모리에 있는 행의 데이터 소스 — 검색·정렬·페이지 나누기를 로컬에서 한다(`computeArrayView`). React 없이 쓴다;
@@ -1,5 +1,6 @@
1
1
  import type { SortCriteria } from '../core/sorting.js';
2
2
  import type { SourceError } from '../core/source-error.js';
3
+ import type { FetchAllOptions } from '../core/fetch-all.js';
3
4
  export interface UseArraySourceOptions<T> {
4
5
  /** 페이지당 행 수. `useODataSource`와 동일 기본값. */
5
6
  pageSize?: number;
@@ -51,4 +52,6 @@ export interface UseArraySourceResult<T> {
51
52
  /** no-op — 로컬 배열에는 다시 불러올 원격 상태가 없다. 소비자가 `useODataSource`와
52
53
  * 같은 자리에 무조건 배선한 refresh 버튼이 있어도 안전하게 아무 일도 하지 않는다. */
53
54
  refresh: () => void;
55
+ /** 지금 검색·정렬의 결과 전체(페이지 없이) — `useODataSource` 의 `fetchAll` 과 같은 계약. 내보내기에 쓴다. */
56
+ fetchAll: (options?: FetchAllOptions) => Promise<T[]>;
54
57
  }
@@ -1,5 +1,6 @@
1
1
  import type { SortCriteria } from '../core/sorting.js';
2
2
  import type { ColumnDefinition, DataRow } from '../models/types.js';
3
+ import { type FetchAllOptions } from '../core/fetch-all.js';
3
4
  export interface ComputeArrayViewOptions<T> {
4
5
  search: string;
5
6
  sortCriteria: SortCriteria[];
@@ -22,3 +23,8 @@ export declare function computeArrayView<T extends DataRow>(data: T[], { search,
22
23
  data: T[];
23
24
  totalCount: number;
24
25
  };
26
+ /**
27
+ * 페이지 없이 — 검색·정렬만 적용한 결과 전체. 메모리 소스의 `fetchAll`(소스·훅 둘 다)이 이것을 부른다. OData 소스와
28
+ * 같은 계약이다: 상한을 넘으면 `RowLimitError`, 거둔 신호면 `AbortError`, 진행 콜백은 한 번(전부 한 «페이지»).
29
+ */
30
+ export declare function readAllArrayRows<T extends DataRow>(data: T[], view: Omit<ComputeArrayViewOptions<T>, 'page' | 'pageSize'>, { maxRows, signal, onProgress }?: FetchAllOptions): Promise<T[]>;
@@ -0,0 +1,14 @@
1
+ /** `fetchAll` 의 옵션 — 두 소스가 같은 모양이다. */
2
+ export interface FetchAllOptions {
3
+ /**
4
+ * 읽을 수 있는 행의 상한. 기본값 `100000`(`DEFAULT_MAX_ROWS`). 결과가 이보다 크면 **잘라서 주지 않고**
5
+ * `RowLimitError` 로 거절한다 — OData 소스는 서버가 센 개수(`@odata.count`)로 첫 응답에서 알면 더 읽지 않는다.
6
+ */
7
+ maxRows?: number;
8
+ /** 취소. 거두면 `AbortError` 로 거절한다. */
9
+ signal?: AbortSignal;
10
+ /** 페이지를 하나 받을 때마다 — 받은 행 수와 전체(서버가 세지 않았으면 `undefined`). */
11
+ onProgress?: (loaded: number, total: number | undefined) => void;
12
+ }
13
+ /** «전부 읽기» 의 기본 상한 — 브라우저 메모리와 서버 부하를 지키는 선. 넘으면 조용히 자르지 않고 거절한다. */
14
+ export declare const DEFAULT_MAX_ROWS = 100000;
@@ -31,11 +31,23 @@ export interface SourceError {
31
31
  }
32
32
  /** 실패 응답을 `SourceError` 로 읽는다. 본문을 읽을 수 없어도 상태와 기본 문장은 남긴다. */
33
33
  export declare function readFailedResponse(res: Response): Promise<SourceError>;
34
- /** 실패 응답을 실어 나르는 내부 예외 — `catch` 가 상태를 잃지 않고 `SourceError` 를 꺼낸다. */
34
+ /**
35
+ * 소스 요청의 실패 — `failure` 가 `SourceError`(상태 · 거절 코드 · 상세)다. `fetchAll` 은 이것으로 거절한다(상한을 넘으면
36
+ * 하위 `RowLimitError`). 화면에는 `failure.message`. 상태로 드러나는 실패(`error`)는 이 `failure` 그대로다.
37
+ */
35
38
  export declare class SourceRequestError extends Error {
36
39
  readonly failure: SourceError;
37
40
  constructor(failure: SourceError);
38
41
  }
42
+ /**
43
+ * 조회 결과가 «전부 읽기» 의 상한(`maxRows`)을 넘었다 — 잘라서 주지 않고 거절한 것이다. 화면에는 `failure.message` 를
44
+ * 그린다(로케일 `tooManyRows`). `total` 은 서버가 센 행 수(`@odata.count`)이고, 서버가 세지 않았으면 없다.
45
+ */
46
+ export declare class RowLimitError extends SourceRequestError {
47
+ readonly total: number | undefined;
48
+ readonly maxRows: number;
49
+ constructor(maxRows: number, total?: number);
50
+ }
39
51
  /** 전송이 응답 없이 던진 실패(네트워크 · 오프라인)를 `SourceError` 로 — 브라우저마다 다른 예외 문구 대신 로케일 문장. */
40
52
  export declare function networkFailure(cause: unknown): SourceRequestError;
41
53
  /** 잡힌 예외를 `SourceError` 로 — 응답이 있던 실패는 그 구조 그대로, 나머지는 메시지만. */
package/dist/events.d.ts CHANGED
@@ -84,11 +84,16 @@ export interface FlexTableEventMap {
84
84
  from: number;
85
85
  to: number;
86
86
  }>;
87
- /** Enter on a non-editable cell — "activate this row". `index` is the data index, `col` the visible column index. */
88
- /** `id` — the row's id (`getRowId`); `index` — its position in `data`; `key` — the active column's key. */
87
+ /**
88
+ * "Open this row": a plain click on a body cell, or Enter on a non-editable cell. `via` tells them apart.
89
+ * Not a click that selects a range (Shift / Ctrl / Cmd), ends a drag, or presses a control the cell renders.
90
+ * `id` — the row's id (`getRowId`); `index` — its position in `data`; `col` — the visible column index;
91
+ * `key` — that column's key.
92
+ */
89
93
  'row-activate': CustomEvent<{
90
94
  row: DataRow;
91
95
  id: string;
96
+ via: 'click' | 'keyboard';
92
97
  index: number;
93
98
  col: number;
94
99
  key: string | undefined;
@@ -97,8 +102,13 @@ export interface FlexTableEventMap {
97
102
  'batch-update': CustomEvent<{
98
103
  changes: CellChange[];
99
104
  }>;
100
- /** The active cell moved; `null` when there is none. */
101
- 'cell-select': CustomEvent<CellPosition | null>;
105
+ /**
106
+ * The active cell moved — by pointer, keyboard, or focus arriving on the grid; `null` when there is none.
107
+ * `row`/`col` are visible positions, `id` the row's id. This is focus, not a choice: open a row on `row-activate`.
108
+ */
109
+ 'cell-select': CustomEvent<(CellPosition & {
110
+ id: string;
111
+ }) | null>;
102
112
  /** `row` is the data index, `col` the visible column index. */
103
113
  'cell-edit-start': CustomEvent<{
104
114
  row: number;
@@ -0,0 +1,86 @@
1
+ import { n as e } from "./locale-D9g0ksXq.js";
2
+ import t from "odata-query";
3
+ //#region src/odata/query.ts
4
+ function n(e) {
5
+ let t = e.split(/\s+/).map((e) => e.replace(/"/g, "")).filter((e) => e.length > 0);
6
+ if (t.length !== 0) return t.map((e) => `"${e}"`).join(" AND ");
7
+ }
8
+ function r(e) {
9
+ let { defaultOrderBy: t, initialPage: n = 0, initialSearch: r = "", initialSort: a } = e;
10
+ return {
11
+ page: n,
12
+ search: r,
13
+ sortCriteria: a ?? (t ? i(t) : [])
14
+ };
15
+ }
16
+ function i(e) {
17
+ return e.split(",").map((e) => {
18
+ let t = e.trim().split(/\s+/);
19
+ return {
20
+ key: t[0],
21
+ direction: t[1]?.toLowerCase() === "desc" ? "desc" : "asc"
22
+ };
23
+ });
24
+ }
25
+ function a(e) {
26
+ let { page: r = 0, pageSize: i, sortCriteria: a = [], defaultOrderBy: o, search: s, fixedFilter: c } = e, l = a.length > 0 ? a.map((e) => `${e.key} ${e.direction}`).join(", ") : o, u = i === void 0 ? { count: !0 } : {
27
+ top: i,
28
+ skip: r * i,
29
+ count: !0
30
+ };
31
+ if (l && (u.orderBy = l), c && (u.filter = c), s) {
32
+ let e = n(s);
33
+ e && (u.search = e);
34
+ }
35
+ return t(u);
36
+ }
37
+ //#endregion
38
+ //#region src/core/source-error.ts
39
+ async function o(t) {
40
+ let n = await t.text().catch(() => ""), r = {
41
+ message: e("requestFailed", { status: t.status }),
42
+ status: t.status
43
+ };
44
+ if (!n) return r;
45
+ let i = n;
46
+ try {
47
+ i = JSON.parse(n);
48
+ } catch {}
49
+ if (r.body = i, !i || typeof i != "object") return r;
50
+ let a = i, o = a.error && typeof a.error == "object" ? a.error : a;
51
+ typeof o.message == "string" && o.message ? r.message = o.message : typeof a.message == "string" && a.message && (r.message = a.message), typeof o.code == "string" && o.code && (r.code = o.code);
52
+ let c = s(o.details);
53
+ return c && (r.details = c), r;
54
+ }
55
+ function s(e) {
56
+ if (!Array.isArray(e)) return;
57
+ let t = e.filter((e) => {
58
+ if (!e || typeof e != "object") return !1;
59
+ let t = e;
60
+ return typeof t.code == "string" && typeof t.message == "string";
61
+ });
62
+ return t.length > 0 ? t : void 0;
63
+ }
64
+ var c = class extends Error {
65
+ constructor(e) {
66
+ super(e.message), this.name = "SourceRequestError", this.failure = e;
67
+ }
68
+ }, l = class extends c {
69
+ constructor(t, n) {
70
+ super({ message: e("tooManyRows", { maxRows: t }) }), this.name = "RowLimitError", this.total = n, this.maxRows = t;
71
+ }
72
+ };
73
+ function u(t) {
74
+ return new c({
75
+ message: e("networkFailed"),
76
+ cause: t
77
+ });
78
+ }
79
+ function d(e) {
80
+ return e instanceof c ? e.failure : e instanceof Error ? { message: e.message } : { message: String(e) };
81
+ }
82
+ //#endregion
83
+ //#region src/core/fetch-all.ts
84
+ var f = 1e5;
85
+ //#endregion
86
+ export { o as a, n as c, u as i, i as l, l as n, d as o, c as r, a as s, f as t, r as u };