@querykitjs/web 2.0.0 → 3.0.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/README.en.md CHANGED
@@ -6,9 +6,11 @@
6
6
 
7
7
  # @querykitjs/web
8
8
 
9
+ [![npm](https://img.shields.io/npm/v/@querykitjs/web.svg)](https://www.npmjs.com/package/@querykitjs/web) [![license](https://img.shields.io/npm/l/@querykitjs/web.svg)](./LICENSE)
10
+
9
11
  > Typed **query-building** for frontends: build filter/sort/pagination payloads, map response meta, sync URL state. It **does not send requests** — you pass the payload to your own `fetch`/`axios`. Zero-dependency.
10
12
 
11
- React dashboards hand-write the same boilerplate on every list page: build `IFilter[]` from `searchParams`, drop empty filters, `sortType` ↔ `{name,direction}`, "reset page on any change", snake→camel meta. `@querykitjs/web` removes all of it. The payload matches what the querykit backend (`@querykitjs/drizzle-pg`, a mongoose adapter, …) accepts.
13
+ React dashboards hand-write the same boilerplate on every list page: build `IFilter[]` from `searchParams`, drop empty filters, `sortType` ↔ `[{key,direction}]` (multi-field), "reset page on any change", snake→camel meta. `@querykitjs/web` removes all of it. The payload matches what the querykit backend (`@querykitjs/drizzle-pg`, a mongoose adapter, …) accepts.
12
14
 
13
15
  ```ts
14
16
  // src/lib/query.ts — configure once
@@ -16,7 +18,7 @@ import { createRegistry } from "@querykitjs/web";
16
18
 
17
19
  export const qk = createRegistry({
18
20
  adapter: "drizzle-pg", // tailors `with` intellisense to the backend
19
- defaults: { perPage: 20, sort: "-createdAt" },
21
+ defaults: { perPage: 20, sort: ["-createdAt"] },
20
22
  });
21
23
  ```
22
24
 
@@ -79,21 +81,21 @@ export const qk = createRegistry({
79
81
  defaults: {
80
82
  perPage: 20, // list (offset) page size
81
83
  limit: 20, // infinite + cursor page size
82
- sort: "-createdAt", // list + infinite ordering (leading "-" = desc)
84
+ sort: ["-createdAt"], // list + infinite ordering (leading "-" = desc)
83
85
  cursor: { order: "asc" }, // cursor-only key traversal order
84
86
  },
85
87
  pruneEmpty: true, // drop empty filter values (""/null/undefined/[]); keep 0/false
86
88
  });
87
89
  ```
88
90
 
89
- | Config | Meaning |
90
- | ----------------------- | ----------------------------------------------------------------------------- |
91
- | `adapter` | Target backend — tailors `with` typing (intellisense only). |
92
- | `defaults.perPage` | Default `perPage` for `list`. |
93
- | `defaults.limit` | Default `limit` for `infinite` and `cursor`. |
94
- | `defaults.sort` | Default sort for `list`/`infinite` (`"-field"` string or `{name,direction}`). |
95
- | `defaults.cursor.order` | Default cursor traversal order (`"asc"`/`"desc"`). |
96
- | `pruneEmpty` | Auto-drop empty filter conditions built from form inputs (default `true`). |
91
+ | Config | Meaning |
92
+ | ----------------------- | ----------------------------------------------------------------------------------- |
93
+ | `adapter` | Target backend — tailors `with` typing (intellisense only). |
94
+ | `defaults.perPage` | Default `perPage` for `list`. |
95
+ | `defaults.limit` | Default `limit` for `infinite` and `cursor`. |
96
+ | `defaults.sort` | Default sort for `list`/`infinite` — `[{key,direction}]` or `["-field"]` shorthand. |
97
+ | `defaults.cursor.order` | Default cursor traversal order (`"asc"`/`"desc"`). |
98
+ | `pruneEmpty` | Auto-drop empty filter conditions built from form inputs (default `true`). |
97
99
 
98
100
  Every default is overridable per call.
99
101
 
@@ -157,6 +159,30 @@ users.search("ali", ["buyerName", "email"]);
157
159
 
158
160
  An untyped `f` is also exported: `import { f } from "@querykitjs/web"` (no field-type checks, quick use).
159
161
 
162
+ ## Sort — always `[{ key, direction }]` (multi-field)
163
+
164
+ Sort is **always an array** of `{ key, direction }` items — one shape across the whole querykit stack (frontend + every backend adapter).
165
+
166
+ ```ts
167
+ // canonical
168
+ users.list({ sort: [{ key: "createdAt", direction: "desc" }] });
169
+
170
+ // multi-field — ORDER BY name ASC, createdAt DESC
171
+ users.list({ sort: [{ key: "name" }, { key: "createdAt", direction: "desc" }] });
172
+
173
+ // shorthand — the builder maps `"-field"` / `"field"` strings for you
174
+ users.list({ sort: ["-createdAt", "name"] }); // → [{ key:"createdAt", direction:"desc" }, { key:"name", direction:"asc" }]
175
+ ```
176
+
177
+ **URL round-trip.** `setSort` encodes to a single comma-separated `sortType` param; reading it back decodes to the array — so multi-sort survives the URL:
178
+
179
+ ```ts
180
+ setSort(searchParams, ["-createdAt", "id"]); // ?sortType=-createdAt,id
181
+ decodeSort("-createdAt,id"); // → [{ key:"createdAt", direction:"desc" }, { key:"id", direction:"asc" }]
182
+ ```
183
+
184
+ The **backend only ever receives** the canonical `[{ key, direction }]` — the `"-field"` shorthand is resolved on the frontend, never sent over the wire.
185
+
160
186
  ## Builders — inputs and **what they return**
161
187
 
162
188
  These are **pure, synchronous** functions. They return a **payload object** (not a Promise, not data). You send it yourself.
@@ -164,7 +190,7 @@ These are **pure, synchronous** functions. They return a **payload object** (not
164
190
  ```ts
165
191
  // list — offset (page)
166
192
  users.list({ filter?, sort?, columns?, with?, withDeleted?, page?, perPage? });
167
- // → { filter, sort:{name,direction}, columns, with, page, perPage, withDeleted? }
193
+ // → { filter, sort: [{ key, direction }], columns, with, page, perPage, withDeleted? }
168
194
 
169
195
  // infinite — limit/offset
170
196
  users.infinite({ filter?, sort?, columns?, with?, withDeleted?, limit?, offset? });
@@ -338,7 +364,7 @@ const users = qk.resource<IUser>("users");
338
364
  function useUsers(filters: { status?: string; search?: string }, page: number) {
339
365
  const body = users.list({
340
366
  filter: [users.f.eq("status", filters.status), users.f.contains("name", filters.search)],
341
- sort: "-createdAt",
367
+ sort: ["-createdAt"],
342
368
  page,
343
369
  });
344
370
  return useQuery({
@@ -407,7 +433,7 @@ import { buildListParams, buildInfiniteParams, buildCursorParams, f } from "@que
407
433
 
408
434
  const body = buildListParams({
409
435
  filter: f.and(f.contains("name", search), f.eq("status", status)),
410
- sort: "-createdAt",
436
+ sort: ["-createdAt"],
411
437
  page,
412
438
  perPage: 20,
413
439
  with: { supervisor: true },
@@ -457,7 +483,7 @@ const { data, meta } = users.parseList(await res.json());
457
483
  | `searchParamsToPayload(schema, sp)` | searchParams → full payload |
458
484
  | `readListParams(schema, sp)` | searchParams → `ListParams` |
459
485
  | `setParam/setPage/setSize/setSort/resetParams` | write URL (immutable, page-reset) |
460
- | `encodeSort/decodeSort` | `{name,direction}` ↔ `"-createdAt"` |
486
+ | `encodeSort/decodeSort` | `[{key,direction}]` ↔ `"-createdAt,id"` (multi-field) |
461
487
  | `useListParams(resource, {schema})` (`/react`) | URL-sync hook (react-router-dom) |
462
488
  | `useListParamsBase(resource, {schema, searchParams, setSearchParams})` (`/react`) | router-agnostic hook |
463
489
 
package/README.md CHANGED
@@ -6,9 +6,11 @@
6
6
 
7
7
  # @querykitjs/web
8
8
 
9
+ [![npm](https://img.shields.io/npm/v/@querykitjs/web.svg)](https://www.npmjs.com/package/@querykitjs/web) [![license](https://img.shields.io/npm/l/@querykitjs/web.svg)](./LICENSE)
10
+
9
11
  > Frontend uchun **tipli query-building**: filter/sort/pagination payloadini quradi, javob meta'sini map qiladi, URL-state sync beradi. **So'rov yubormaydi** — chiqqan payload'ni o'z `fetch`/`axios`ingizga uzatasiz. Zero-dependency.
10
12
 
11
- React dashboardlar har list sahifasida bir xil boilerplate'ni qo'lda yozadi: `searchParams`'dan `IFilter[]` qurish, bo'sh filterlarni tashlash, `sortType` ↔ `{name,direction}`, "har o'zgarishda page-reset", meta snake→camel. `@querykitjs/web` shularni bartaraf qiladi. Payload querykit backend (`@querykitjs/drizzle-pg`, mongoose adapter, ...) qabul qiladigan formatда.
13
+ React dashboardlar har list sahifasida bir xil boilerplate'ni qo'lda yozadi: `searchParams`'dan `IFilter[]` qurish, bo'sh filterlarni tashlash, `sortType` ↔ `[{key,direction}]` (ko'p-maydon), "har o'zgarishda page-reset", meta snake→camel. `@querykitjs/web` shularni bartaraf qiladi. Payload querykit backend (`@querykitjs/drizzle-pg`, mongoose adapter, ...) qabul qiladigan formatда.
12
14
 
13
15
  ```ts
14
16
  // src/lib/query.ts — bir marta sozlang
@@ -16,7 +18,7 @@ import { createRegistry } from "@querykitjs/web";
16
18
 
17
19
  export const qk = createRegistry({
18
20
  adapter: "drizzle-pg", // `with` intellisense'ini backend'ga moslaydi
19
- defaults: { perPage: 20, sort: "-createdAt" },
21
+ defaults: { perPage: 20, sort: ["-createdAt"] },
20
22
  });
21
23
  ```
22
24
 
@@ -79,7 +81,7 @@ export const qk = createRegistry({
79
81
  defaults: {
80
82
  perPage: 20, // list (offset) sahifa hajmi
81
83
  limit: 20, // infinite + cursor hajmi
82
- sort: "-createdAt", // list + infinite tartibi (boshidagi "-" = desc)
84
+ sort: ["-createdAt"], // list + infinite tartibi (boshidagi "-" = desc)
83
85
  cursor: { order: "asc" }, // faqat cursor: kalit bo'ylab yurish tartibi
84
86
  },
85
87
  pruneEmpty: true, // bo'sh filterlarni tashlash (""/null/undefined/[]); 0/false qoladi
@@ -91,7 +93,7 @@ export const qk = createRegistry({
91
93
  | `adapter` | Backend turi — `with` tipini moslaydi (faqat intellisense). |
92
94
  | `defaults.perPage` | `list` uchun default `perPage`. |
93
95
  | `defaults.limit` | `infinite` va `cursor` uchun default `limit`. |
94
- | `defaults.sort` | `list`/`infinite` default sort (`"-field"` string yoki `{name,direction}`). |
96
+ | `defaults.sort` | `list`/`infinite` default sort — `[{key,direction}]` yoki `["-field"]` shorthand. |
95
97
  | `defaults.cursor.order` | Default cursor tartibi (`"asc"`/`"desc"`). |
96
98
  | `pruneEmpty` | Form input'lardan qurilgan bo'sh filterlarni avtomatik tashlash (default `true`). |
97
99
 
@@ -157,6 +159,30 @@ users.search("ali", ["buyerName", "email"]);
157
159
 
158
160
  Tipsiz `f` ham bor: `import { f } from "@querykitjs/web"` (maydon-tip tekshiruvisiz, tez ishlatish).
159
161
 
162
+ ## Sort — hamisha `[{ key, direction }]` (ko'p-maydon)
163
+
164
+ Sort **hamisha** `{ key, direction }` elementlar massivi — butun querykit stеки bo'ylab (frontend + har bir backend adapter) bir xil shakl.
165
+
166
+ ```ts
167
+ // canonical
168
+ users.list({ sort: [{ key: "createdAt", direction: "desc" }] });
169
+
170
+ // ko'p-maydon — ORDER BY name ASC, createdAt DESC
171
+ users.list({ sort: [{ key: "name" }, { key: "createdAt", direction: "desc" }] });
172
+
173
+ // shorthand — builder `"-field"` / `"field"` string'larни o'zi maplaydi
174
+ users.list({ sort: ["-createdAt", "name"] }); // → [{ key:"createdAt", direction:"desc" }, { key:"name", direction:"asc" }]
175
+ ```
176
+
177
+ **URL round-trip.** `setSort` bitta vergul bilan ajratilgan `sortType` param'ga kodlaydi; o'qiganда yana massivga dekodlanadi — ko'p-sort URL'да saqlanadi:
178
+
179
+ ```ts
180
+ setSort(searchParams, ["-createdAt", "id"]); // ?sortType=-createdAt,id
181
+ decodeSort("-createdAt,id"); // → [{ key:"createdAt", direction:"desc" }, { key:"id", direction:"asc" }]
182
+ ```
183
+
184
+ **Backend faqat** canonical `[{ key, direction }]`ни oladi — `"-field"` shorthand frontend'да resolve qilinadi, wire'га hech qачон yuborilmaydi.
185
+
160
186
  ## Builder'lar — kirish va **nima qaytaradi**
161
187
 
162
188
  Bular **sof, sinxron** funksiyalar. **Payload obyekt** qaytaradi (Promise emas, data emas). O'zingiz yuborasiz.
@@ -164,7 +190,7 @@ Bular **sof, sinxron** funksiyalar. **Payload obyekt** qaytaradi (Promise emas,
164
190
  ```ts
165
191
  // list — offset (page)
166
192
  users.list({ filter?, sort?, columns?, with?, withDeleted?, page?, perPage? });
167
- // → { filter, sort:{name,direction}, columns, with, page, perPage, withDeleted? }
193
+ // → { filter, sort: [{ key, direction }], columns, with, page, perPage, withDeleted? }
168
194
 
169
195
  // infinite — limit/offset
170
196
  users.infinite({ filter?, sort?, columns?, with?, withDeleted?, limit?, offset? });
@@ -338,7 +364,7 @@ const users = qk.resource<IUser>("users");
338
364
  function useUsers(filters: { status?: string; search?: string }, page: number) {
339
365
  const body = users.list({
340
366
  filter: [users.f.eq("status", filters.status), users.f.contains("name", filters.search)],
341
- sort: "-createdAt",
367
+ sort: ["-createdAt"],
342
368
  page,
343
369
  });
344
370
  return useQuery({
@@ -407,7 +433,7 @@ import { buildListParams, buildInfiniteParams, buildCursorParams, f } from "@que
407
433
 
408
434
  const body = buildListParams({
409
435
  filter: f.and(f.contains("name", search), f.eq("status", status)),
410
- sort: "-createdAt",
436
+ sort: ["-createdAt"],
411
437
  page,
412
438
  perPage: 20,
413
439
  with: { supervisor: true },
@@ -457,7 +483,7 @@ const { data, meta } = users.parseList(await res.json());
457
483
  | `searchParamsToPayload(schema, sp)` | searchParams → to'liq payload |
458
484
  | `readListParams(schema, sp)` | searchParams → `ListParams` |
459
485
  | `setParam/setPage/setSize/setSort/resetParams` | URL yozish (immutable, page-reset) |
460
- | `encodeSort/decodeSort` | `{name,direction}` ↔ `"-createdAt"` |
486
+ | `encodeSort/decodeSort` | `[{key,direction}]` ↔ `"-createdAt,id"` (multi-field) |
461
487
  | `useListParams(resource, {schema})` (`/react`) | URL-sync hook (react-router-dom) |
462
488
  | `useListParamsBase(resource, {schema, searchParams, setSearchParams})` (`/react`) | router-agnostik hook |
463
489
 
package/dist/index.cjs CHANGED
@@ -19,7 +19,7 @@ var DEFAULTS = {
19
19
  cursorField: "cursor",
20
20
  defaultPerPage: core.DEFAULT_PER_PAGE,
21
21
  defaultLimit: core.DEFAULT_LIMIT,
22
- defaultSort: { name: "createdAt", direction: "desc" },
22
+ defaultSort: [{ key: "createdAt", direction: "desc" }],
23
23
  pruneEmpty: true
24
24
  };
25
25
  function isEmptyValue(value) {
@@ -27,13 +27,18 @@ function isEmptyValue(value) {
27
27
  if (Array.isArray(value) && value.length === 0) return true;
28
28
  return false;
29
29
  }
30
- function normalizeSort(input, fallback) {
31
- if (input === void 0 || input === "") return fallback;
32
- if (typeof input === "string") {
33
- const desc = input.startsWith("-");
34
- return { name: desc ? input.slice(1) : input, direction: desc ? "desc" : "asc" };
30
+ function toSortItem(item) {
31
+ if (typeof item === "string") {
32
+ const desc = item.startsWith("-");
33
+ const key = (desc ? item.slice(1) : item).trim();
34
+ return key ? { key, direction: desc ? "desc" : "asc" } : void 0;
35
35
  }
36
- return { name: input.name ?? fallback.name, direction: input.direction ?? fallback.direction };
36
+ return item && item.key ? { key: item.key, direction: item.direction ?? "asc" } : void 0;
37
+ }
38
+ function normalizeSort(input, fallback) {
39
+ if (!input || input.length === 0) return fallback;
40
+ const items = input.map(toSortItem).filter((i) => i !== void 0);
41
+ return items.length ? items : fallback;
37
42
  }
38
43
  function normalizeCondition(condition, prune) {
39
44
  const operation = condition.operation ?? "=";
@@ -172,12 +177,14 @@ var URL_DEFAULTS = {
172
177
  };
173
178
  function decodeSort(value) {
174
179
  if (!value) return void 0;
175
- const desc = value.startsWith("-");
176
- return { name: desc ? value.slice(1) : value, direction: desc ? "desc" : "asc" };
180
+ const items = value.split(",").map((s) => s.trim()).filter(Boolean).map((tok) => {
181
+ const desc = tok.startsWith("-");
182
+ return { key: desc ? tok.slice(1) : tok, direction: desc ? "desc" : "asc" };
183
+ }).filter((i) => i.key);
184
+ return items.length ? items : void 0;
177
185
  }
178
186
  function encodeSort(sort) {
179
- if (!sort.name) return "";
180
- return (sort.direction === "desc" ? "-" : "") + sort.name;
187
+ return sort.map((i) => typeof i === "string" ? i.trim() : i && i.key ? (i.direction === "desc" ? "-" : "") + i.key : "").filter(Boolean).join(",");
181
188
  }
182
189
  function schemaToFilter(schema, searchParams) {
183
190
  const conditions = [];
@@ -224,7 +231,7 @@ function readListParams(schema, searchParams, url = {}) {
224
231
  const size = searchParams.get(cfg.sizeParam);
225
232
  return {
226
233
  filter: schemaToFilter(schema, searchParams),
227
- sort: searchParams.get(cfg.sortParam) ?? void 0,
234
+ sort: decodeSort(searchParams.get(cfg.sortParam)),
228
235
  page: Number(searchParams.get(cfg.pageParam)) || 1,
229
236
  perPage: size ? Number(size) : void 0
230
237
  };
@@ -260,7 +267,7 @@ function setSort(searchParams, sort, url = {}) {
260
267
  const cfg = { ...URL_DEFAULTS, ...url };
261
268
  const next = clone(searchParams);
262
269
  next.delete(cfg.pageParam);
263
- const encoded = typeof sort === "string" ? sort : encodeSort(sort);
270
+ const encoded = encodeSort(sort);
264
271
  if (encoded) next.set(cfg.sortParam, encoded);
265
272
  else next.delete(cfg.sortParam);
266
273
  return next;
@@ -277,12 +284,12 @@ function resetParams(searchParams, keep = []) {
277
284
  // src/registry.ts
278
285
  function createRegistry(config) {
279
286
  const defaults = config.defaults ?? {};
280
- const sort = typeof defaults.sort === "string" ? decodeSort(defaults.sort) : defaults.sort;
287
+ const sort = normalizeSort(defaults.sort, []);
281
288
  const cursorOrder = defaults.cursor?.order ?? "asc";
282
289
  const qcfg = {};
283
290
  if (defaults.perPage !== void 0) qcfg.defaultPerPage = defaults.perPage;
284
291
  if (defaults.limit !== void 0) qcfg.defaultLimit = defaults.limit;
285
- if (sort?.name) qcfg.defaultSort = sort;
292
+ if (sort.length) qcfg.defaultSort = sort;
286
293
  if (config.pruneEmpty !== void 0) qcfg.pruneEmpty = config.pruneEmpty;
287
294
  const q = createQuery(qcfg);
288
295
  const parseList = (raw) => ({ data: raw?.data ?? [], meta: mapMeta(raw?.meta) });
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/filters.ts","../src/query.ts","../src/meta.ts","../src/schema.ts","../src/url.ts","../src/registry.ts"],"names":["coreCreateFilters","DEFAULT_PER_PAGE","DEFAULT_LIMIT","f"],"mappings":"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","file":"index.cjs","sourcesContent":["import { createFilters as coreCreateFilters, f } from \"@querykitjs/core\";\n\nimport type { AndGroup, FieldCondition, FieldKey, FilterNode, FilterScalar, FilterValue, NotGroup, OrGroup } from \"./types\";\n\n/** Keys of `T` whose value is assignable to `V`. */\ntype ValueKeys<T, V> = { [K in keyof T]-?: NonNullable<T[K]> extends V ? Extract<K, string> : never }[keyof T];\n/** String-valued field keys (for `contains`/`startsWith`/`like`/…). */\ntype StringKeys<T> = ValueKeys<T, string>;\n/** Comparable field keys — string/number/bigint/Date (for `gt`/`between`/…). */\ntype ComparableKeys<T> = ValueKeys<T, string | number | bigint | Date>;\n\ntype Node<T> = FilterNode<T>;\n\n/**\n * Field-type-aware filter builder: string-match operators are offered only for\n * string fields, comparison only for comparable fields, so nonsensical filters\n * (e.g. `contains` on a number) are compile errors. Runtime is\n * `@querykitjs/core`'s builder unchanged.\n */\nexport interface TypedFilters<T> {\n eq<K extends FieldKey<T>>(key: K, value: FilterValue): FieldCondition<T>;\n ne<K extends FieldKey<T>>(key: K, value: FilterValue): FieldCondition<T>;\n\n gt<K extends ComparableKeys<T>>(key: K, value: FilterValue): FieldCondition<T>;\n gte<K extends ComparableKeys<T>>(key: K, value: FilterValue): FieldCondition<T>;\n lt<K extends ComparableKeys<T>>(key: K, value: FilterValue): FieldCondition<T>;\n lte<K extends ComparableKeys<T>>(key: K, value: FilterValue): FieldCondition<T>;\n between<K extends ComparableKeys<T>>(key: K, min: FilterScalar | Date, max: FilterScalar | Date): FieldCondition<T>;\n range<K extends ComparableKeys<T>>(key: K, from: FilterScalar | Date, to: FilterScalar | Date): FieldCondition<T>[];\n\n contains<K extends StringKeys<T>>(key: K, value: string): FieldCondition<T>;\n startsWith<K extends StringKeys<T>>(key: K, value: string): FieldCondition<T>;\n endsWith<K extends StringKeys<T>>(key: K, value: string): FieldCondition<T>;\n like<K extends StringKeys<T>>(key: K, value: string): FieldCondition<T>;\n ilike<K extends StringKeys<T>>(key: K, value: string): FieldCondition<T>;\n notLike<K extends StringKeys<T>>(key: K, value: string): FieldCondition<T>;\n\n in<K extends FieldKey<T>>(key: K, value: Array<string | number>): FieldCondition<T>;\n notIn<K extends FieldKey<T>>(key: K, value: Array<string | number>): FieldCondition<T>;\n\n isNull<K extends FieldKey<T>>(key: K): FieldCondition<T>;\n isNotNull<K extends FieldKey<T>>(key: K): FieldCondition<T>;\n\n and(...nodes: Node<T>[]): AndGroup<T>;\n or(...nodes: Node<T>[]): OrGroup<T>;\n not(node: Node<T>): NotGroup<T>;\n}\n\n/**\n * Typed, ergonomic filter builder for an entity — field-name autocomplete plus\n * field-type-aware operators (see {@link TypedFilters}).\n *\n * @typeParam T - the list entity type (`Buyer`, `Product`, …).\n * @example\n * ```ts\n * const f = createFilters<Buyer>();\n * const filter = f.and(f.contains(\"buyerName\", s), f.gte(\"age\", 18));\n * // f.contains(\"age\", …) → compile error (age is a number)\n * ```\n */\nexport function createFilters<T = Record<string, unknown>>(): TypedFilters<T> {\n return coreCreateFilters<FieldKey<T>>() as unknown as TypedFilters<T>;\n}\n\n/** Untyped (entity-agnostic) filter builder — quick use, no field-type checks. */\nexport { f };\n","import { DEFAULT_LIMIT, DEFAULT_PER_PAGE } from \"@querykitjs/core\";\n\nimport type {\n CursorParams,\n CursorPayload,\n FieldCondition,\n Filter,\n FilterNode,\n FilterValue,\n InfiniteParams,\n InfinitePayload,\n ListParams,\n ListPayload,\n Params,\n QueryPayload,\n Sort,\n SortInput,\n} from \"./types\";\n\n/** {@link createQuery} sozlamalari — wire field nomlari va default qiymatlar. */\nexport interface QueryConfig {\n filterField?: string;\n sortField?: string;\n columnsField?: string;\n withField?: string;\n withDeletedField?: string;\n pageField?: string;\n perPageField?: string;\n limitField?: string;\n offsetField?: string;\n cursorField?: string;\n defaultPerPage?: number;\n defaultLimit?: number;\n defaultSort?: Sort;\n /** Bo'sh qiymatli filterlarni tashlash (default `true`). */\n pruneEmpty?: boolean;\n}\n\nconst DEFAULTS: Required<QueryConfig> = {\n filterField: \"filter\",\n sortField: \"sort\",\n columnsField: \"columns\",\n withField: \"with\",\n withDeletedField: \"withDeleted\",\n pageField: \"page\",\n perPageField: \"perPage\",\n limitField: \"limit\",\n offsetField: \"offset\",\n cursorField: \"cursor\",\n defaultPerPage: DEFAULT_PER_PAGE,\n defaultLimit: DEFAULT_LIMIT,\n defaultSort: { name: \"createdAt\", direction: \"desc\" },\n pruneEmpty: true,\n};\n\n/** Bo'sh (yuborilmaydigan) qiymatmi: undefined/null/\"\"/[] . `false`/`0` — bo'sh emas. */\nfunction isEmptyValue(value: FilterValue | undefined): boolean {\n if (value === undefined || value === null || value === \"\") return true;\n if (Array.isArray(value) && value.length === 0) return true;\n return false;\n}\n\n/** `\"-createdAt\"` yoki `{ name, direction }` → `{ name, direction }`. */\nexport function normalizeSort(input: SortInput | undefined, fallback: Sort): Sort {\n if (input === undefined || input === \"\") return fallback;\n if (typeof input === \"string\") {\n const desc = input.startsWith(\"-\");\n return { name: desc ? input.slice(1) : input, direction: desc ? \"desc\" : \"asc\" };\n }\n return { name: input.name ?? fallback.name, direction: input.direction ?? fallback.direction };\n}\n\nfunction normalizeCondition(condition: FieldCondition, prune: boolean): FieldCondition | undefined {\n const operation = condition.operation ?? \"=\";\n const noValue = operation === \"isNull\" || operation === \"isNotNull\";\n const value = condition.value as FilterValue;\n\n if (!noValue && prune && isEmptyValue(value)) return undefined;\n\n const out: FieldCondition = { key: condition.key, operation };\n if (!noValue) out.value = value;\n return out;\n}\n\nfunction normalizeNode(node: FilterNode, prune: boolean): FilterNode | undefined {\n if (\"and\" in node) {\n const kids = node.and.map(n => normalizeNode(n, prune)).filter((n): n is FilterNode => !!n);\n return kids.length ? { and: kids } : undefined;\n }\n if (\"or\" in node) {\n const kids = node.or.map(n => normalizeNode(n, prune)).filter((n): n is FilterNode => !!n);\n return kids.length ? { or: kids } : undefined;\n }\n if (\"not\" in node) {\n const inner = normalizeNode(node.not, prune);\n return inner ? { not: inner } : undefined;\n }\n return normalizeCondition(node, prune);\n}\n\n/** Filterni normalizatsiya qiladi: bo'sh shartlarni prune. Massiv → flat massiv. */\nexport function normalizeFilter(filter: Filter | undefined, prune: boolean): FieldCondition[] | FilterNode {\n if (!filter) return [];\n if (Array.isArray(filter)) {\n return filter.map(c => normalizeCondition(c, prune)).filter((c): c is FieldCondition => !!c);\n }\n return normalizeNode(filter, prune) ?? [];\n}\n\n/** Umumiy qism: filter/columns/with (+ withDeleted). Sort qo'shilmaydi. */\nfunction buildBase(input: Params, cfg: Required<QueryConfig>): Record<string, unknown> {\n const base: Record<string, unknown> = {\n [cfg.filterField]: normalizeFilter(input.filter, cfg.pruneEmpty),\n [cfg.columnsField]: input.columns ?? {},\n [cfg.withField]: input.with ?? {},\n };\n if (input.withDeleted !== undefined) base[cfg.withDeletedField] = input.withDeleted;\n return base;\n}\n\nfunction clampInt(value: number | undefined, fallback: number): number {\n return value === undefined || value < 1 || Number.isNaN(value) ? fallback : Math.trunc(value);\n}\n\nfunction build(input: Params, cfg: Required<QueryConfig>): Record<string, unknown> {\n return { ...buildBase(input, cfg), [cfg.sortField]: normalizeSort(input.sort, cfg.defaultSort) };\n}\n\nfunction buildList(input: ListParams, cfg: Required<QueryConfig>): Record<string, unknown> {\n return {\n ...build(input, cfg),\n [cfg.pageField]: clampInt(input.page, 1), // page >= 1 (kasr/0/manfiy → 1)\n [cfg.perPageField]: clampInt(input.perPage, cfg.defaultPerPage),\n };\n}\n\nfunction buildInfinite(input: InfiniteParams, cfg: Required<QueryConfig>): Record<string, unknown> {\n return {\n ...build(input, cfg),\n [cfg.limitField]: clampInt(input.limit, cfg.defaultLimit),\n [cfg.offsetField]: input.offset && input.offset > 0 ? Math.trunc(input.offset) : 0,\n };\n}\n\nfunction buildCursor(input: CursorParams, cfg: Required<QueryConfig>): Record<string, unknown> {\n const payload: Record<string, unknown> = {\n ...buildBase(input, cfg),\n [cfg.limitField]: clampInt(input.limit, cfg.defaultLimit),\n [cfg.cursorField]: input.cursor ?? null,\n order: input.order ?? \"asc\",\n direction: input.direction ?? \"forward\",\n };\n if (input.cursorKey !== undefined) payload.cursorKey = input.cursorKey;\n return payload;\n}\n\n/**\n * Config bilan bog'langan query quruvchilarni qaytaradi. Boshqa backend field\n * nomlari (masalan `perPage`, `withPopulates`) uchun.\n *\n * @example\n * ```ts\n * const q = createQuery({ withField: \"withPopulates\", defaultPerPage: 20 });\n * const params = q.list({ filter, page, perPage });\n * ```\n */\nexport function createQuery(config: QueryConfig = {}) {\n const cfg = { ...DEFAULTS, ...config };\n return {\n params: (input: Params = {}) => build(input, cfg),\n list: (input: ListParams = {}) => buildList(input, cfg),\n infinite: (input: InfiniteParams = {}) => buildInfinite(input, cfg),\n cursor: (input: CursorParams = {}) => buildCursor(input, cfg),\n };\n}\n\n/**\n * Params'ni normalizatsiya qiladi (paginatsiyasiz): filter prune, sort decode,\n * `with`/`columns` pass-through. Default querykit wire-format.\n *\n * @example\n * ```ts\n * const payload = buildParams({\n * filter: [{ key: \"name\", operation: \"%_%\", value: s }],\n * sort: \"-createdAt\",\n * with: { supervisor: true },\n * });\n * ```\n */\nexport function buildParams(input: Params = {}): QueryPayload {\n return build(input, DEFAULTS) as unknown as QueryPayload;\n}\n\n/**\n * {@link buildParams} + `page`/`perPage` (default `perPage = 20`, `@querykitjs/core`).\n *\n * @example\n * ```ts\n * const payload = buildListParams({ filter, sort: \"-createdAt\", page: 2, perPage: 20 });\n * // -> { filter, sort:{name,direction}, columns, with, page, perPage }\n * ```\n */\nexport function buildListParams(input: ListParams = {}): ListPayload {\n return buildList(input, DEFAULTS) as unknown as ListPayload;\n}\n\n/**\n * Infinite-scroll payload — {@link buildParams} + `limit`/`offset` (default\n * `limit = 20`).\n *\n * @example\n * ```ts\n * const payload = buildInfiniteParams({ filter, limit: 20, offset: 40 });\n * // -> { filter, sort, columns, with, limit, offset }\n * ```\n */\nexport function buildInfiniteParams(input: InfiniteParams = {}): InfinitePayload {\n return buildInfinite(input, DEFAULTS) as unknown as InfinitePayload;\n}\n\n/**\n * Cursor (keyset) payload — `sort` o'rniga `order`/`direction`. `cursor`\n * oldingi javob meta'sidagi `next_cursor`/`prev_cursor` tokeni.\n *\n * @example\n * ```ts\n * const payload = buildCursorParams({ filter, limit: 20, cursor, order: \"asc\" });\n * // -> { filter, columns, with, limit, cursor, order, direction }\n * ```\n */\nexport function buildCursorParams(input: CursorParams = {}): CursorPayload {\n return buildCursor(input, DEFAULTS) as unknown as CursorPayload;\n}\n","import type { CursorMeta, InfiniteMeta, Meta, RawCursorMeta, RawInfiniteMeta, RawMeta } from \"./types\";\n\n/**\n * **Offset** (list) meta'sini snake_case → camelCase map qiladi.\n *\n * @example\n * ```ts\n * const { data, meta } = (await http.post(\"/buyers/list\", params)).data;\n * setMeta(mapMeta(meta)); // { totalPages, totalCount, currentPage, perPage, hasNext, hasPrev }\n * ```\n */\nexport function mapMeta(raw?: RawMeta | null): Meta {\n return {\n totalPages: raw?.total_pages ?? 0,\n totalCount: raw?.total_items ?? 0,\n currentPage: raw?.current_page ?? 0,\n perPage: raw?.per_page ?? 0,\n hasNext: raw?.has_next ?? false,\n hasPrev: raw?.has_prev ?? false,\n };\n}\n\n/**\n * **Infinite-scroll** meta'sini map qiladi.\n *\n * @example\n * ```ts\n * const m = mapInfiniteMeta(res.meta); // { limit, offset, count, hasMore, nextOffset }\n * if (m.hasMore) load(m.nextOffset);\n * ```\n */\nexport function mapInfiniteMeta(raw?: RawInfiniteMeta | null): InfiniteMeta {\n return {\n limit: raw?.limit ?? 0,\n offset: raw?.offset ?? 0,\n count: raw?.count ?? 0,\n hasMore: raw?.has_more ?? false,\n nextOffset: raw?.next_offset ?? null,\n };\n}\n\n/**\n * **Cursor** (keyset) meta'sini map qiladi.\n *\n * @example\n * ```ts\n * const m = mapCursorMeta(res.meta); // { limit, hasNext, hasPrev, nextCursor, prevCursor }\n * ```\n */\nexport function mapCursorMeta(raw?: RawCursorMeta | null): CursorMeta {\n return {\n limit: raw?.limit ?? 0,\n hasNext: raw?.has_next ?? false,\n hasPrev: raw?.has_prev ?? false,\n nextCursor: raw?.next_cursor ?? null,\n prevCursor: raw?.prev_cursor ?? null,\n };\n}\n","import type { FilterOperator, FilterValue } from \"./types\";\n\n/** Forbids the listed keys (`?: never`) so modes can't be mixed. */\ntype Without<K extends string> = { [P in K]?: never };\n\n/** Filter-key override, shared by the single-key modes. */\ninterface KeyBase {\n /** Backend field key (defaults to the schema param name). */\n key?: string;\n}\n\n/**\n * **Simple** mode — one URL param → one condition. `operation` defaults to `\"=\"`;\n * `trim`/`default`/`split` shape the value.\n */\nexport interface SimpleField extends KeyBase {\n /** Filter operation (default `\"=\"`). */\n operation?: FilterOperator;\n /** Trim the string value. */\n trim?: boolean;\n /** Value used when the URL param is absent. */\n default?: FilterValue;\n /**\n * For array operations (`in`/`notIn`): split a comma-string into an array.\n * `true` → delimiter `\",\"`; or a custom delimiter. Guarded: absent/empty →\n * pruned; parts trimmed, empties dropped.\n */\n split?: boolean | string;\n}\n\n/** **Range** mode — `[fromParam, toParam]` → two inclusive conditions (`>=`, `<=`). */\nexport interface RangeField extends KeyBase {\n range: [string, string];\n}\n\n/** **Between** mode — `[fromParam, toParam]` → one `between` condition (2-tuple). */\nexport interface BetweenField extends KeyBase {\n between: [string, string];\n}\n\n/** **Search** mode — one URL param → OR of `contains` across these field keys. */\nexport interface SearchField {\n search: string[];\n trim?: boolean;\n default?: FilterValue;\n}\n\n/**\n * One list field's URL→filter mapping. Exactly **one mode** per descriptor —\n * Simple / Range / Between / Search — enforced at compile time (mixing e.g.\n * `range` + `search`, or `range` + `between`, is a type error).\n */\nexport type FieldDescriptor =\n | (SimpleField & Without<\"range\" | \"between\" | \"search\">)\n | (RangeField & Without<\"operation\" | \"trim\" | \"default\" | \"split\" | \"between\" | \"search\">)\n | (BetweenField & Without<\"operation\" | \"trim\" | \"default\" | \"split\" | \"range\" | \"search\">)\n | (SearchField & Without<\"key\" | \"operation\" | \"split\" | \"range\" | \"between\">);\n\n/** URL param → {@link FieldDescriptor} map. */\nexport type ListSchema = Record<string, FieldDescriptor>;\n\n/**\n * Declares a list filter schema (identity helper — preserves the literal type).\n * Maps URL params to `{key, operation, value}` conditions so pages never build\n * `IFilter[]` by hand.\n *\n * @example\n * ```ts\n * const buyersSchema = defineListSchema({\n * id: { operation: \"=\" },\n * status: { operation: \"=\", default: \"active\" },\n * ids: { operation: \"in\", split: true },\n * q: { search: [\"name\", \"email\"] },\n * createdAt: { range: [\"fromDate\", \"toDate\"] },\n * });\n * ```\n */\nexport function defineListSchema<S extends ListSchema>(schema: S): S {\n return schema;\n}\n","import { buildListParams } from \"./query\";\nimport type { FieldDescriptor, ListSchema } from \"./schema\";\nimport type { FieldCondition, Filter, FilterNode, FilterValue, ListParams, ListPayload, Sort, SortInput } from \"./types\";\n\n/** URL param nomlari (sahifa/o'lcham/sort) — sozlanadigan. */\nexport interface UrlConfig {\n pageParam?: string;\n sizeParam?: string;\n sortParam?: string;\n}\n\nconst URL_DEFAULTS: Required<UrlConfig> = {\n pageParam: \"page\",\n sizeParam: \"size\",\n sortParam: \"sortType\",\n};\n\n/** `\"-createdAt\"` → `{ name, direction }` (bo'sh bo'lsa `undefined`). */\nexport function decodeSort(value: string | null | undefined): Sort | undefined {\n if (!value) return undefined;\n const desc = value.startsWith(\"-\");\n return { name: desc ? value.slice(1) : value, direction: desc ? \"desc\" : \"asc\" };\n}\n\n/** `{ name, direction }` → `\"-createdAt\"` / `\"createdAt\"` (nomsiz bo'lsa `\"\"`). */\nexport function encodeSort(sort: Sort): string {\n if (!sort.name) return \"\";\n return (sort.direction === \"desc\" ? \"-\" : \"\") + sort.name;\n}\n\n/**\n * Schema + searchParams → filter. Applies `range`/`between`/`search`/`split`/\n * `default`/`trim`; empty/absent params are dropped. Returns a flat\n * `FieldCondition[]` (implicit AND), or a tree when a `search` OR-group is\n * present (`{ and: [orGroup, …conditions] }`).\n */\nexport function schemaToFilter(schema: ListSchema, searchParams: URLSearchParams): Filter {\n const conditions: FieldCondition[] = [];\n const groups: FilterNode[] = [];\n\n for (const [param, d] of Object.entries(schema) as [string, FieldDescriptor][]) {\n const key = d.key ?? param;\n\n // range → two inclusive conditions (>= , <=)\n if (d.range) {\n const from = searchParams.get(d.range[0]);\n const to = searchParams.get(d.range[1]);\n if (from) conditions.push(cond(key, \">=\", from));\n if (to) conditions.push(cond(key, \"<=\", to));\n continue;\n }\n\n // between → one condition with a 2-tuple value\n if (d.between) {\n const from = searchParams.get(d.between[0]);\n const to = searchParams.get(d.between[1]);\n if (from && to) conditions.push(cond(key, \"between\", [from, to]));\n continue;\n }\n\n // read value, falling back to `default` only when the param is ABSENT\n // (an empty `?x=` means the user cleared the filter → prune, don't default).\n const raw = searchParams.get(param);\n let value: FilterValue | undefined = raw !== null ? raw : d.default;\n if (typeof value === \"string\" && d.trim) value = value.trim();\n if (value === undefined || value === null || value === \"\") continue;\n if (Array.isArray(value) && value.length === 0) continue;\n\n // search → OR of `contains` across the listed fields (needs a string)\n if (d.search && typeof value === \"string\") {\n groups.push({ or: d.search.map(field => cond(field, \"%_%\", value as string)) });\n continue;\n }\n\n // split → comma-string → array (for `in`/`notIn`); guarded against empties\n if (d.split && typeof value === \"string\") {\n const delimiter = d.split === true ? \",\" : d.split;\n const parts = value\n .split(delimiter)\n .map(s => s.trim())\n .filter(Boolean);\n if (parts.length === 0) continue;\n value = parts;\n }\n\n conditions.push(cond(key, d.operation ?? \"=\", value));\n }\n\n return groups.length === 0 ? conditions : { and: [...groups, ...conditions] };\n}\n\nfunction cond(key: string, operation: FieldCondition[\"operation\"], value: FilterValue): FieldCondition {\n return { key, operation, value };\n}\n\n/** searchParams → normalizatsiyalanmagan {@link ListParams} (filter/sort/page/perPage). */\nexport function readListParams(schema: ListSchema, searchParams: URLSearchParams, url: UrlConfig = {}): ListParams {\n const cfg = { ...URL_DEFAULTS, ...url };\n const size = searchParams.get(cfg.sizeParam);\n return {\n filter: schemaToFilter(schema, searchParams),\n sort: searchParams.get(cfg.sortParam) ?? undefined,\n page: Number(searchParams.get(cfg.pageParam)) || 1,\n perPage: size ? Number(size) : undefined,\n };\n}\n\n/** searchParams → to'liq, yuborishga tayyor {@link ListPayload}. */\nexport function searchParamsToPayload(schema: ListSchema, searchParams: URLSearchParams, url?: UrlConfig): ListPayload {\n return buildListParams(readListParams(schema, searchParams, url));\n}\n\n/* ------------------------- URL yozish (immutable) ------------------------- */\n/* Har biri YANGI URLSearchParams qaytaradi; filter/sort o'zgarsa `page` reset. */\n\nfunction clone(searchParams: URLSearchParams): URLSearchParams {\n return new URLSearchParams(searchParams);\n}\n\n/** Filter param'ini o'rnatadi/o'chiradi va `page`ni reset qiladi. */\nexport function setParam(searchParams: URLSearchParams, name: string, value: string | null | undefined, url: UrlConfig = {}): URLSearchParams {\n const cfg = { ...URL_DEFAULTS, ...url };\n const next = clone(searchParams);\n next.delete(cfg.pageParam);\n if (value === null || value === undefined || value === \"\") next.delete(name);\n else next.set(name, value);\n return next;\n}\n\n/** Sahifani o'rnatadi (`page` reset qilinmaydi). */\nexport function setPage(searchParams: URLSearchParams, page: number, url: UrlConfig = {}): URLSearchParams {\n const cfg = { ...URL_DEFAULTS, ...url };\n const next = clone(searchParams);\n next.set(cfg.pageParam, String(page));\n return next;\n}\n\n/** Sahifa o'lchamini o'rnatadi va `page`ni reset qiladi. */\nexport function setSize(searchParams: URLSearchParams, size: number, url: UrlConfig = {}): URLSearchParams {\n const cfg = { ...URL_DEFAULTS, ...url };\n const next = clone(searchParams);\n next.delete(cfg.pageParam);\n next.set(cfg.sizeParam, String(size));\n return next;\n}\n\n/** Sortni o'rnatadi (`\"-createdAt\"` yoki `{name,direction}`) va `page`ni reset qiladi. */\nexport function setSort(searchParams: URLSearchParams, sort: SortInput, url: UrlConfig = {}): URLSearchParams {\n const cfg = { ...URL_DEFAULTS, ...url };\n const next = clone(searchParams);\n next.delete(cfg.pageParam);\n const encoded = typeof sort === \"string\" ? sort : encodeSort(sort);\n if (encoded) next.set(cfg.sortParam, encoded);\n else next.delete(cfg.sortParam);\n return next;\n}\n\n/** Barcha list param'larini tozalaydi (ixtiyoriy saqlanadigan kalitlar bilan). */\nexport function resetParams(searchParams: URLSearchParams, keep: string[] = []): URLSearchParams {\n const next = new URLSearchParams();\n for (const key of keep) {\n const value = searchParams.get(key);\n if (value !== null) next.set(key, value);\n }\n return next;\n}\n","import { createQuery, type QueryConfig } from \"./query\";\nimport { createFilters, f as rawF } from \"./filters\";\nimport { mapMeta, mapInfiniteMeta, mapCursorMeta } from \"./meta\";\nimport { defineListSchema, type ListSchema } from \"./schema\";\nimport { decodeSort, readListParams, type UrlConfig } from \"./url\";\nimport type { AdapterName, WithFor } from \"./adapter\";\nimport type {\n CursorMeta,\n CursorParams,\n CursorPayload,\n FieldKey,\n Filter,\n InfiniteMeta,\n InfiniteParams,\n InfinitePayload,\n ListParams,\n ListPayload,\n Meta,\n Params,\n QueryPayload,\n RawCursorMeta,\n RawInfiniteMeta,\n RawMeta,\n Sort,\n SortDirection,\n SortInput,\n} from \"./types\";\n\n/* ---------------- resource inputs: entity-typed, adapter-aware `with` ------ */\n\nexport type ResourceListParams<T, A extends AdapterName> = Omit<ListParams<T>, \"with\"> & { with?: WithFor<A> };\nexport type ResourceInfiniteParams<T, A extends AdapterName> = Omit<InfiniteParams<T>, \"with\"> & { with?: WithFor<A> };\nexport type ResourceCursorParams<T, A extends AdapterName> = Omit<CursorParams<T>, \"with\"> & { with?: WithFor<A> };\nexport type ResourceParams<T, A extends AdapterName> = Omit<Params<T>, \"with\"> & { with?: WithFor<A> };\n\n/* ---------------------------- responses / results ------------------------- */\n\ninterface RawResponse<T, M> {\n data?: T[];\n meta?: M | null;\n}\nexport interface ListResult<T> {\n data: T[];\n meta: Meta;\n}\nexport interface InfiniteResult<T> {\n data: T[];\n meta: InfiniteMeta;\n}\nexport interface CursorResult<T> {\n data: T[];\n meta: CursorMeta;\n}\n\n/* -------------------------------- query keys ------------------------------ */\n\nexport interface ResourceKeys {\n all: readonly unknown[];\n list(payload: unknown): readonly unknown[];\n infinite(payload: unknown): readonly unknown[];\n cursor(payload: unknown): readonly unknown[];\n detail(id: unknown): readonly unknown[];\n}\n\n/* -------------------------------- resource -------------------------------- */\n\nexport interface Resource<T, A extends AdapterName> {\n /** Build an offset (page) payload. */\n list(input?: ResourceListParams<T, A>): ListPayload;\n /** Build an infinite (limit/offset) payload. */\n infinite(input?: ResourceInfiniteParams<T, A>): InfinitePayload;\n /** Build a cursor (keyset) payload. */\n cursor(input?: ResourceCursorParams<T, A>): CursorPayload;\n /** Build a paginationless payload (filter/sort/columns/with). */\n params(input?: ResourceParams<T, A>): QueryPayload;\n /** Filter builder typed to `T`'s fields. */\n f: ReturnType<typeof createFilters<T>>;\n /** Search preset — OR of `contains` across `fields` (e.g. one input → many columns). */\n search(term: string, fields: FieldKey<T>[]): Filter<T>;\n /** Declare a URL↔filter schema (identity helper). */\n schema<S extends ListSchema>(s: S): S;\n /** Build a list payload from URL search params (SSR — the non-hook `useListParams`). */\n fromSearchParams(searchParams: URLSearchParams, options: { schema: ListSchema; url?: UrlConfig; with?: WithFor<A> }): ListPayload;\n /** Stable query keys for TanStack/SWR caches. */\n keys: ResourceKeys;\n /** Map a list response's meta to camelCase (`data` typed to `T`). */\n parseList(raw?: RawResponse<T, RawMeta> | null): ListResult<T>;\n parseInfinite(raw?: RawResponse<T, RawInfiniteMeta> | null): InfiniteResult<T>;\n parseCursor(raw?: RawResponse<T, RawCursorMeta> | null): CursorResult<T>;\n}\n\n/* -------------------------------- registry -------------------------------- */\n\nexport interface RegistryDefaults {\n /** `list` page size. */\n perPage?: number;\n /** `infinite` + `cursor` page size. */\n limit?: number;\n /** `list`/`infinite` sort (`\"-createdAt\"` or `{name,direction}`). */\n sort?: SortInput;\n /** Cursor-only defaults. */\n cursor?: { order?: SortDirection };\n}\n\nexport interface RegistryConfig<A extends AdapterName> {\n adapter: A;\n defaults?: RegistryDefaults;\n /** Drop empty filter values built from form inputs (default `true`). */\n pruneEmpty?: boolean;\n}\n\nexport interface Registry<A extends AdapterName> {\n readonly adapter: A;\n /** Entity-typed builders + filters + schema + keys + parsers. `name` = cache-key namespace (required, must be unique). */\n resource<T>(name: string): Resource<T, A>;\n /** Registry-level meta parsing (entity-agnostic — `data: unknown[]`). */\n parseList(raw?: RawResponse<unknown, RawMeta> | null): ListResult<unknown>;\n parseInfinite(raw?: RawResponse<unknown, RawInfiniteMeta> | null): InfiniteResult<unknown>;\n parseCursor(raw?: RawResponse<unknown, RawCursorMeta> | null): CursorResult<unknown>;\n}\n\n/**\n * Create a web query registry — configure defaults + backend adapter once, then\n * `registry.resource<T>()` yields entity-typed, adapter-aware query builders,\n * filters, a URL↔filter schema, cache keys and meta parsers.\n *\n * @example\n * ```ts\n * export const qk = createRegistry({ adapter: \"mongoose\", defaults: { perPage: 20, sort: \"-createdAt\" } });\n * const users = qk.resource<IUser>(\"users\");\n * const body = users.list({ filter: users.f.eq(\"status\", \"active\"), page });\n * ```\n */\nexport function createRegistry<A extends AdapterName>(config: RegistryConfig<A>): Registry<A> {\n const defaults = config.defaults ?? {};\n const sort: Sort | undefined = typeof defaults.sort === \"string\" ? decodeSort(defaults.sort) : defaults.sort;\n const cursorOrder: SortDirection = defaults.cursor?.order ?? \"asc\";\n\n // Only set keys that are provided — createQuery merges over its own defaults,\n // and passing `undefined` would clobber them.\n const qcfg: QueryConfig = {};\n if (defaults.perPage !== undefined) qcfg.defaultPerPage = defaults.perPage;\n if (defaults.limit !== undefined) qcfg.defaultLimit = defaults.limit;\n if (sort?.name) qcfg.defaultSort = sort; // only override when a real sort field is given\n if (config.pruneEmpty !== undefined) qcfg.pruneEmpty = config.pruneEmpty;\n const q = createQuery(qcfg);\n\n const parseList = (raw?: RawResponse<unknown, RawMeta> | null): ListResult<unknown> => ({ data: raw?.data ?? [], meta: mapMeta(raw?.meta) });\n const parseInfinite = (raw?: RawResponse<unknown, RawInfiniteMeta> | null): InfiniteResult<unknown> => ({\n data: raw?.data ?? [],\n meta: mapInfiniteMeta(raw?.meta),\n });\n const parseCursor = (raw?: RawResponse<unknown, RawCursorMeta> | null): CursorResult<unknown> => ({\n data: raw?.data ?? [],\n meta: mapCursorMeta(raw?.meta),\n });\n\n function resource<T>(name: string): Resource<T, A> {\n const f = createFilters<T>();\n const keys: ResourceKeys = {\n all: [name],\n list: p => [name, \"list\", p],\n infinite: p => [name, \"infinite\", p],\n cursor: p => [name, \"cursor\", p],\n detail: id => [name, \"detail\", id],\n };\n return {\n list: input => q.list(input as unknown as ListParams) as unknown as ListPayload,\n infinite: input => q.infinite(input as unknown as InfiniteParams) as unknown as InfinitePayload,\n cursor: input => q.cursor({ ...(input as unknown as CursorParams), order: input?.order ?? cursorOrder }) as unknown as CursorPayload,\n params: input => q.params(input as unknown as Params) as unknown as QueryPayload,\n f,\n search: (term, fields) => rawF.or(...fields.map(field => rawF.contains(field, term))) as unknown as Filter<T>,\n schema: s => defineListSchema(s),\n fromSearchParams: (searchParams, options) =>\n q.list({ ...readListParams(options.schema, searchParams, options.url), with: options.with } as unknown as ListParams) as unknown as ListPayload,\n keys,\n parseList: raw => parseList(raw) as ListResult<T>,\n parseInfinite: raw => parseInfinite(raw) as InfiniteResult<T>,\n parseCursor: raw => parseCursor(raw) as CursorResult<T>,\n };\n }\n\n return { adapter: config.adapter, resource, parseList, parseInfinite, parseCursor };\n}\n"]}
1
+ {"version":3,"sources":["../src/filters.ts","../src/query.ts","../src/meta.ts","../src/schema.ts","../src/url.ts","../src/registry.ts"],"names":["coreCreateFilters","DEFAULT_PER_PAGE","DEFAULT_LIMIT","f"],"mappings":"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","file":"index.cjs","sourcesContent":["import { createFilters as coreCreateFilters, f } from \"@querykitjs/core\";\n\nimport type { AndGroup, FieldCondition, FieldKey, FilterNode, FilterScalar, FilterValue, NotGroup, OrGroup } from \"./types\";\n\n/** Keys of `T` whose value is assignable to `V`. */\ntype ValueKeys<T, V> = { [K in keyof T]-?: NonNullable<T[K]> extends V ? Extract<K, string> : never }[keyof T];\n/** String-valued field keys (for `contains`/`startsWith`/`like`/…). */\ntype StringKeys<T> = ValueKeys<T, string>;\n/** Comparable field keys — string/number/bigint/Date (for `gt`/`between`/…). */\ntype ComparableKeys<T> = ValueKeys<T, string | number | bigint | Date>;\n\ntype Node<T> = FilterNode<T>;\n\n/**\n * Field-type-aware filter builder: string-match operators are offered only for\n * string fields, comparison only for comparable fields, so nonsensical filters\n * (e.g. `contains` on a number) are compile errors. Runtime is\n * `@querykitjs/core`'s builder unchanged.\n */\nexport interface TypedFilters<T> {\n eq<K extends FieldKey<T>>(key: K, value: FilterValue): FieldCondition<T>;\n ne<K extends FieldKey<T>>(key: K, value: FilterValue): FieldCondition<T>;\n\n gt<K extends ComparableKeys<T>>(key: K, value: FilterValue): FieldCondition<T>;\n gte<K extends ComparableKeys<T>>(key: K, value: FilterValue): FieldCondition<T>;\n lt<K extends ComparableKeys<T>>(key: K, value: FilterValue): FieldCondition<T>;\n lte<K extends ComparableKeys<T>>(key: K, value: FilterValue): FieldCondition<T>;\n between<K extends ComparableKeys<T>>(key: K, min: FilterScalar | Date, max: FilterScalar | Date): FieldCondition<T>;\n range<K extends ComparableKeys<T>>(key: K, from: FilterScalar | Date, to: FilterScalar | Date): FieldCondition<T>[];\n\n contains<K extends StringKeys<T>>(key: K, value: string): FieldCondition<T>;\n startsWith<K extends StringKeys<T>>(key: K, value: string): FieldCondition<T>;\n endsWith<K extends StringKeys<T>>(key: K, value: string): FieldCondition<T>;\n like<K extends StringKeys<T>>(key: K, value: string): FieldCondition<T>;\n ilike<K extends StringKeys<T>>(key: K, value: string): FieldCondition<T>;\n notLike<K extends StringKeys<T>>(key: K, value: string): FieldCondition<T>;\n\n in<K extends FieldKey<T>>(key: K, value: Array<string | number>): FieldCondition<T>;\n notIn<K extends FieldKey<T>>(key: K, value: Array<string | number>): FieldCondition<T>;\n\n isNull<K extends FieldKey<T>>(key: K): FieldCondition<T>;\n isNotNull<K extends FieldKey<T>>(key: K): FieldCondition<T>;\n\n and(...nodes: Node<T>[]): AndGroup<T>;\n or(...nodes: Node<T>[]): OrGroup<T>;\n not(node: Node<T>): NotGroup<T>;\n}\n\n/**\n * Typed, ergonomic filter builder for an entity — field-name autocomplete plus\n * field-type-aware operators (see {@link TypedFilters}).\n *\n * @typeParam T - the list entity type (`Buyer`, `Product`, …).\n * @example\n * ```ts\n * const f = createFilters<Buyer>();\n * const filter = f.and(f.contains(\"buyerName\", s), f.gte(\"age\", 18));\n * // f.contains(\"age\", …) → compile error (age is a number)\n * ```\n */\nexport function createFilters<T = Record<string, unknown>>(): TypedFilters<T> {\n return coreCreateFilters<FieldKey<T>>() as unknown as TypedFilters<T>;\n}\n\n/** Untyped (entity-agnostic) filter builder — quick use, no field-type checks. */\nexport { f };\n","import { DEFAULT_LIMIT, DEFAULT_PER_PAGE } from \"@querykitjs/core\";\n\nimport type {\n CursorParams,\n CursorPayload,\n FieldCondition,\n Filter,\n FilterNode,\n FilterValue,\n InfiniteParams,\n InfinitePayload,\n ListParams,\n ListPayload,\n Params,\n QueryPayload,\n Sort,\n SortInput,\n} from \"./types\";\n\n/** {@link createQuery} sozlamalari — wire field nomlari va default qiymatlar. */\nexport interface QueryConfig {\n filterField?: string;\n sortField?: string;\n columnsField?: string;\n withField?: string;\n withDeletedField?: string;\n pageField?: string;\n perPageField?: string;\n limitField?: string;\n offsetField?: string;\n cursorField?: string;\n defaultPerPage?: number;\n defaultLimit?: number;\n defaultSort?: Sort;\n /** Bo'sh qiymatli filterlarni tashlash (default `true`). */\n pruneEmpty?: boolean;\n}\n\nconst DEFAULTS: Required<QueryConfig> = {\n filterField: \"filter\",\n sortField: \"sort\",\n columnsField: \"columns\",\n withField: \"with\",\n withDeletedField: \"withDeleted\",\n pageField: \"page\",\n perPageField: \"perPage\",\n limitField: \"limit\",\n offsetField: \"offset\",\n cursorField: \"cursor\",\n defaultPerPage: DEFAULT_PER_PAGE,\n defaultLimit: DEFAULT_LIMIT,\n defaultSort: [{ key: \"createdAt\", direction: \"desc\" }],\n pruneEmpty: true,\n};\n\n/** Bo'sh (yuborilmaydigan) qiymatmi: undefined/null/\"\"/[] . `false`/`0` — bo'sh emas. */\nfunction isEmptyValue(value: FilterValue | undefined): boolean {\n if (value === undefined || value === null || value === \"\") return true;\n if (Array.isArray(value) && value.length === 0) return true;\n return false;\n}\n\n/** A `\"-field\"`/`\"field\"` shorthand string or a `{ key, direction }` item → a `SortItem`. */\nfunction toSortItem(item: Sort[number] | string): Sort[number] | undefined {\n if (typeof item === \"string\") {\n const desc = item.startsWith(\"-\");\n const key = (desc ? item.slice(1) : item).trim();\n return key ? { key, direction: desc ? \"desc\" : \"asc\" } : undefined;\n }\n return item && item.key ? { key: item.key, direction: item.direction ?? \"asc\" } : undefined;\n}\n\n/** Normalize a sort array (objects and/or `\"-field\"` strings) → canonical `SortItem[]`; empty → fallback. */\nexport function normalizeSort(input: SortInput | undefined, fallback: Sort): Sort {\n if (!input || input.length === 0) return fallback;\n const items = input.map(toSortItem).filter((i): i is Sort[number] => i !== undefined);\n return items.length ? items : fallback;\n}\n\nfunction normalizeCondition(condition: FieldCondition, prune: boolean): FieldCondition | undefined {\n const operation = condition.operation ?? \"=\";\n const noValue = operation === \"isNull\" || operation === \"isNotNull\";\n const value = condition.value as FilterValue;\n\n if (!noValue && prune && isEmptyValue(value)) return undefined;\n\n const out: FieldCondition = { key: condition.key, operation };\n if (!noValue) out.value = value;\n return out;\n}\n\nfunction normalizeNode(node: FilterNode, prune: boolean): FilterNode | undefined {\n if (\"and\" in node) {\n const kids = node.and.map(n => normalizeNode(n, prune)).filter((n): n is FilterNode => !!n);\n return kids.length ? { and: kids } : undefined;\n }\n if (\"or\" in node) {\n const kids = node.or.map(n => normalizeNode(n, prune)).filter((n): n is FilterNode => !!n);\n return kids.length ? { or: kids } : undefined;\n }\n if (\"not\" in node) {\n const inner = normalizeNode(node.not, prune);\n return inner ? { not: inner } : undefined;\n }\n return normalizeCondition(node, prune);\n}\n\n/** Filterni normalizatsiya qiladi: bo'sh shartlarni prune. Massiv → flat massiv. */\nexport function normalizeFilter(filter: Filter | undefined, prune: boolean): FieldCondition[] | FilterNode {\n if (!filter) return [];\n if (Array.isArray(filter)) {\n return filter.map(c => normalizeCondition(c, prune)).filter((c): c is FieldCondition => !!c);\n }\n return normalizeNode(filter, prune) ?? [];\n}\n\n/** Umumiy qism: filter/columns/with (+ withDeleted). Sort qo'shilmaydi. */\nfunction buildBase(input: Params, cfg: Required<QueryConfig>): Record<string, unknown> {\n const base: Record<string, unknown> = {\n [cfg.filterField]: normalizeFilter(input.filter, cfg.pruneEmpty),\n [cfg.columnsField]: input.columns ?? {},\n [cfg.withField]: input.with ?? {},\n };\n if (input.withDeleted !== undefined) base[cfg.withDeletedField] = input.withDeleted;\n return base;\n}\n\nfunction clampInt(value: number | undefined, fallback: number): number {\n return value === undefined || value < 1 || Number.isNaN(value) ? fallback : Math.trunc(value);\n}\n\nfunction build(input: Params, cfg: Required<QueryConfig>): Record<string, unknown> {\n return { ...buildBase(input, cfg), [cfg.sortField]: normalizeSort(input.sort, cfg.defaultSort) };\n}\n\nfunction buildList(input: ListParams, cfg: Required<QueryConfig>): Record<string, unknown> {\n return {\n ...build(input, cfg),\n [cfg.pageField]: clampInt(input.page, 1), // page >= 1 (kasr/0/manfiy → 1)\n [cfg.perPageField]: clampInt(input.perPage, cfg.defaultPerPage),\n };\n}\n\nfunction buildInfinite(input: InfiniteParams, cfg: Required<QueryConfig>): Record<string, unknown> {\n return {\n ...build(input, cfg),\n [cfg.limitField]: clampInt(input.limit, cfg.defaultLimit),\n [cfg.offsetField]: input.offset && input.offset > 0 ? Math.trunc(input.offset) : 0,\n };\n}\n\nfunction buildCursor(input: CursorParams, cfg: Required<QueryConfig>): Record<string, unknown> {\n const payload: Record<string, unknown> = {\n ...buildBase(input, cfg),\n [cfg.limitField]: clampInt(input.limit, cfg.defaultLimit),\n [cfg.cursorField]: input.cursor ?? null,\n order: input.order ?? \"asc\",\n direction: input.direction ?? \"forward\",\n };\n if (input.cursorKey !== undefined) payload.cursorKey = input.cursorKey;\n return payload;\n}\n\n/**\n * Config bilan bog'langan query quruvchilarni qaytaradi. Boshqa backend field\n * nomlari (masalan `perPage`, `withPopulates`) uchun.\n *\n * @example\n * ```ts\n * const q = createQuery({ withField: \"withPopulates\", defaultPerPage: 20 });\n * const params = q.list({ filter, page, perPage });\n * ```\n */\nexport function createQuery(config: QueryConfig = {}) {\n const cfg = { ...DEFAULTS, ...config };\n return {\n params: (input: Params = {}) => build(input, cfg),\n list: (input: ListParams = {}) => buildList(input, cfg),\n infinite: (input: InfiniteParams = {}) => buildInfinite(input, cfg),\n cursor: (input: CursorParams = {}) => buildCursor(input, cfg),\n };\n}\n\n/**\n * Params'ni normalizatsiya qiladi (paginatsiyasiz): filter prune, sort decode,\n * `with`/`columns` pass-through. Default querykit wire-format.\n *\n * @example\n * ```ts\n * const payload = buildParams({\n * filter: [{ key: \"name\", operation: \"%_%\", value: s }],\n * sort: [{ key: \"createdAt\", direction: \"desc\" }],\n * with: { supervisor: true },\n * });\n * ```\n */\nexport function buildParams(input: Params = {}): QueryPayload {\n return build(input, DEFAULTS) as unknown as QueryPayload;\n}\n\n/**\n * {@link buildParams} + `page`/`perPage` (default `perPage = 20`, `@querykitjs/core`).\n *\n * @example\n * ```ts\n * const payload = buildListParams({ filter, sort: [{ key: \"createdAt\", direction: \"desc\" }], page: 2, perPage: 20 });\n * // -> { filter, sort: [{ key, direction }], columns, with, page, perPage }\n * ```\n */\nexport function buildListParams(input: ListParams = {}): ListPayload {\n return buildList(input, DEFAULTS) as unknown as ListPayload;\n}\n\n/**\n * Infinite-scroll payload — {@link buildParams} + `limit`/`offset` (default\n * `limit = 20`).\n *\n * @example\n * ```ts\n * const payload = buildInfiniteParams({ filter, limit: 20, offset: 40 });\n * // -> { filter, sort, columns, with, limit, offset }\n * ```\n */\nexport function buildInfiniteParams(input: InfiniteParams = {}): InfinitePayload {\n return buildInfinite(input, DEFAULTS) as unknown as InfinitePayload;\n}\n\n/**\n * Cursor (keyset) payload — `sort` o'rniga `order`/`direction`. `cursor`\n * oldingi javob meta'sidagi `next_cursor`/`prev_cursor` tokeni.\n *\n * @example\n * ```ts\n * const payload = buildCursorParams({ filter, limit: 20, cursor, order: \"asc\" });\n * // -> { filter, columns, with, limit, cursor, order, direction }\n * ```\n */\nexport function buildCursorParams(input: CursorParams = {}): CursorPayload {\n return buildCursor(input, DEFAULTS) as unknown as CursorPayload;\n}\n","import type { CursorMeta, InfiniteMeta, Meta, RawCursorMeta, RawInfiniteMeta, RawMeta } from \"./types\";\n\n/**\n * **Offset** (list) meta'sini snake_case → camelCase map qiladi.\n *\n * @example\n * ```ts\n * const { data, meta } = (await http.post(\"/buyers/list\", params)).data;\n * setMeta(mapMeta(meta)); // { totalPages, totalCount, currentPage, perPage, hasNext, hasPrev }\n * ```\n */\nexport function mapMeta(raw?: RawMeta | null): Meta {\n return {\n totalPages: raw?.total_pages ?? 0,\n totalCount: raw?.total_items ?? 0,\n currentPage: raw?.current_page ?? 0,\n perPage: raw?.per_page ?? 0,\n hasNext: raw?.has_next ?? false,\n hasPrev: raw?.has_prev ?? false,\n };\n}\n\n/**\n * **Infinite-scroll** meta'sini map qiladi.\n *\n * @example\n * ```ts\n * const m = mapInfiniteMeta(res.meta); // { limit, offset, count, hasMore, nextOffset }\n * if (m.hasMore) load(m.nextOffset);\n * ```\n */\nexport function mapInfiniteMeta(raw?: RawInfiniteMeta | null): InfiniteMeta {\n return {\n limit: raw?.limit ?? 0,\n offset: raw?.offset ?? 0,\n count: raw?.count ?? 0,\n hasMore: raw?.has_more ?? false,\n nextOffset: raw?.next_offset ?? null,\n };\n}\n\n/**\n * **Cursor** (keyset) meta'sini map qiladi.\n *\n * @example\n * ```ts\n * const m = mapCursorMeta(res.meta); // { limit, hasNext, hasPrev, nextCursor, prevCursor }\n * ```\n */\nexport function mapCursorMeta(raw?: RawCursorMeta | null): CursorMeta {\n return {\n limit: raw?.limit ?? 0,\n hasNext: raw?.has_next ?? false,\n hasPrev: raw?.has_prev ?? false,\n nextCursor: raw?.next_cursor ?? null,\n prevCursor: raw?.prev_cursor ?? null,\n };\n}\n","import type { FilterOperator, FilterValue } from \"./types\";\n\n/** Forbids the listed keys (`?: never`) so modes can't be mixed. */\ntype Without<K extends string> = { [P in K]?: never };\n\n/** Filter-key override, shared by the single-key modes. */\ninterface KeyBase {\n /** Backend field key (defaults to the schema param name). */\n key?: string;\n}\n\n/**\n * **Simple** mode — one URL param → one condition. `operation` defaults to `\"=\"`;\n * `trim`/`default`/`split` shape the value.\n */\nexport interface SimpleField extends KeyBase {\n /** Filter operation (default `\"=\"`). */\n operation?: FilterOperator;\n /** Trim the string value. */\n trim?: boolean;\n /** Value used when the URL param is absent. */\n default?: FilterValue;\n /**\n * For array operations (`in`/`notIn`): split a comma-string into an array.\n * `true` → delimiter `\",\"`; or a custom delimiter. Guarded: absent/empty →\n * pruned; parts trimmed, empties dropped.\n */\n split?: boolean | string;\n}\n\n/** **Range** mode — `[fromParam, toParam]` → two inclusive conditions (`>=`, `<=`). */\nexport interface RangeField extends KeyBase {\n range: [string, string];\n}\n\n/** **Between** mode — `[fromParam, toParam]` → one `between` condition (2-tuple). */\nexport interface BetweenField extends KeyBase {\n between: [string, string];\n}\n\n/** **Search** mode — one URL param → OR of `contains` across these field keys. */\nexport interface SearchField {\n search: string[];\n trim?: boolean;\n default?: FilterValue;\n}\n\n/**\n * One list field's URL→filter mapping. Exactly **one mode** per descriptor —\n * Simple / Range / Between / Search — enforced at compile time (mixing e.g.\n * `range` + `search`, or `range` + `between`, is a type error).\n */\nexport type FieldDescriptor =\n | (SimpleField & Without<\"range\" | \"between\" | \"search\">)\n | (RangeField & Without<\"operation\" | \"trim\" | \"default\" | \"split\" | \"between\" | \"search\">)\n | (BetweenField & Without<\"operation\" | \"trim\" | \"default\" | \"split\" | \"range\" | \"search\">)\n | (SearchField & Without<\"key\" | \"operation\" | \"split\" | \"range\" | \"between\">);\n\n/** URL param → {@link FieldDescriptor} map. */\nexport type ListSchema = Record<string, FieldDescriptor>;\n\n/**\n * Declares a list filter schema (identity helper — preserves the literal type).\n * Maps URL params to `{key, operation, value}` conditions so pages never build\n * `IFilter[]` by hand.\n *\n * @example\n * ```ts\n * const buyersSchema = defineListSchema({\n * id: { operation: \"=\" },\n * status: { operation: \"=\", default: \"active\" },\n * ids: { operation: \"in\", split: true },\n * q: { search: [\"name\", \"email\"] },\n * createdAt: { range: [\"fromDate\", \"toDate\"] },\n * });\n * ```\n */\nexport function defineListSchema<S extends ListSchema>(schema: S): S {\n return schema;\n}\n","import { buildListParams } from \"./query\";\nimport type { FieldDescriptor, ListSchema } from \"./schema\";\nimport type { FieldCondition, Filter, FilterNode, FilterValue, ListParams, ListPayload, Sort, SortDirection, SortInput } from \"./types\";\n\n/** URL param nomlari (sahifa/o'lcham/sort) — sozlanadigan. */\nexport interface UrlConfig {\n pageParam?: string;\n sizeParam?: string;\n sortParam?: string;\n}\n\nconst URL_DEFAULTS: Required<UrlConfig> = {\n pageParam: \"page\",\n sizeParam: \"size\",\n sortParam: \"sortType\",\n};\n\n/**\n * `\"-createdAt,id,-appNumber\"` → `[{ key, direction }, …]` — comma-separated,\n * order preserved, `-` prefix = `desc` (else `asc`). Empty → `undefined`.\n */\nexport function decodeSort(value: string | null | undefined): Sort | undefined {\n if (!value) return undefined;\n const items = value\n .split(\",\")\n .map(s => s.trim())\n .filter(Boolean)\n .map(tok => {\n const desc = tok.startsWith(\"-\");\n return { key: desc ? tok.slice(1) : tok, direction: (desc ? \"desc\" : \"asc\") as SortDirection };\n })\n .filter(i => i.key); // drop empty keys (e.g. a lone \"-\")\n return items.length ? items : undefined;\n}\n\n/** `[{ key, direction }, …]` (or `\"-field\"` shorthand strings) → `\"-createdAt,id,-appNumber\"` (empty → `\"\"`). */\nexport function encodeSort(sort: SortInput): string {\n return sort\n .map(i => (typeof i === \"string\" ? i.trim() : i && i.key ? (i.direction === \"desc\" ? \"-\" : \"\") + i.key : \"\"))\n .filter(Boolean)\n .join(\",\");\n}\n\n/**\n * Schema + searchParams → filter. Applies `range`/`between`/`search`/`split`/\n * `default`/`trim`; empty/absent params are dropped. Returns a flat\n * `FieldCondition[]` (implicit AND), or a tree when a `search` OR-group is\n * present (`{ and: [orGroup, …conditions] }`).\n */\nexport function schemaToFilter(schema: ListSchema, searchParams: URLSearchParams): Filter {\n const conditions: FieldCondition[] = [];\n const groups: FilterNode[] = [];\n\n for (const [param, d] of Object.entries(schema) as [string, FieldDescriptor][]) {\n const key = d.key ?? param;\n\n // range → two inclusive conditions (>= , <=)\n if (d.range) {\n const from = searchParams.get(d.range[0]);\n const to = searchParams.get(d.range[1]);\n if (from) conditions.push(cond(key, \">=\", from));\n if (to) conditions.push(cond(key, \"<=\", to));\n continue;\n }\n\n // between → one condition with a 2-tuple value\n if (d.between) {\n const from = searchParams.get(d.between[0]);\n const to = searchParams.get(d.between[1]);\n if (from && to) conditions.push(cond(key, \"between\", [from, to]));\n continue;\n }\n\n // read value, falling back to `default` only when the param is ABSENT\n // (an empty `?x=` means the user cleared the filter → prune, don't default).\n const raw = searchParams.get(param);\n let value: FilterValue | undefined = raw !== null ? raw : d.default;\n if (typeof value === \"string\" && d.trim) value = value.trim();\n if (value === undefined || value === null || value === \"\") continue;\n if (Array.isArray(value) && value.length === 0) continue;\n\n // search → OR of `contains` across the listed fields (needs a string)\n if (d.search && typeof value === \"string\") {\n groups.push({ or: d.search.map(field => cond(field, \"%_%\", value as string)) });\n continue;\n }\n\n // split → comma-string → array (for `in`/`notIn`); guarded against empties\n if (d.split && typeof value === \"string\") {\n const delimiter = d.split === true ? \",\" : d.split;\n const parts = value\n .split(delimiter)\n .map(s => s.trim())\n .filter(Boolean);\n if (parts.length === 0) continue;\n value = parts;\n }\n\n conditions.push(cond(key, d.operation ?? \"=\", value));\n }\n\n return groups.length === 0 ? conditions : { and: [...groups, ...conditions] };\n}\n\nfunction cond(key: string, operation: FieldCondition[\"operation\"], value: FilterValue): FieldCondition {\n return { key, operation, value };\n}\n\n/** searchParams → normalizatsiyalanmagan {@link ListParams} (filter/sort/page/perPage). */\nexport function readListParams(schema: ListSchema, searchParams: URLSearchParams, url: UrlConfig = {}): ListParams {\n const cfg = { ...URL_DEFAULTS, ...url };\n const size = searchParams.get(cfg.sizeParam);\n return {\n filter: schemaToFilter(schema, searchParams),\n sort: decodeSort(searchParams.get(cfg.sortParam)),\n page: Number(searchParams.get(cfg.pageParam)) || 1,\n perPage: size ? Number(size) : undefined,\n };\n}\n\n/** searchParams → to'liq, yuborishga tayyor {@link ListPayload}. */\nexport function searchParamsToPayload(schema: ListSchema, searchParams: URLSearchParams, url?: UrlConfig): ListPayload {\n return buildListParams(readListParams(schema, searchParams, url));\n}\n\n/* ------------------------- URL yozish (immutable) ------------------------- */\n/* Har biri YANGI URLSearchParams qaytaradi; filter/sort o'zgarsa `page` reset. */\n\nfunction clone(searchParams: URLSearchParams): URLSearchParams {\n return new URLSearchParams(searchParams);\n}\n\n/** Filter param'ini o'rnatadi/o'chiradi va `page`ni reset qiladi. */\nexport function setParam(searchParams: URLSearchParams, name: string, value: string | null | undefined, url: UrlConfig = {}): URLSearchParams {\n const cfg = { ...URL_DEFAULTS, ...url };\n const next = clone(searchParams);\n next.delete(cfg.pageParam);\n if (value === null || value === undefined || value === \"\") next.delete(name);\n else next.set(name, value);\n return next;\n}\n\n/** Sahifani o'rnatadi (`page` reset qilinmaydi). */\nexport function setPage(searchParams: URLSearchParams, page: number, url: UrlConfig = {}): URLSearchParams {\n const cfg = { ...URL_DEFAULTS, ...url };\n const next = clone(searchParams);\n next.set(cfg.pageParam, String(page));\n return next;\n}\n\n/** Sahifa o'lchamini o'rnatadi va `page`ni reset qiladi. */\nexport function setSize(searchParams: URLSearchParams, size: number, url: UrlConfig = {}): URLSearchParams {\n const cfg = { ...URL_DEFAULTS, ...url };\n const next = clone(searchParams);\n next.delete(cfg.pageParam);\n next.set(cfg.sizeParam, String(size));\n return next;\n}\n\n/** Sortni o'rnatadi (`[{ key, direction }, …]`) va `page`ni reset qiladi. */\nexport function setSort(searchParams: URLSearchParams, sort: SortInput, url: UrlConfig = {}): URLSearchParams {\n const cfg = { ...URL_DEFAULTS, ...url };\n const next = clone(searchParams);\n next.delete(cfg.pageParam);\n const encoded = encodeSort(sort);\n if (encoded) next.set(cfg.sortParam, encoded);\n else next.delete(cfg.sortParam);\n return next;\n}\n\n/** Barcha list param'larini tozalaydi (ixtiyoriy saqlanadigan kalitlar bilan). */\nexport function resetParams(searchParams: URLSearchParams, keep: string[] = []): URLSearchParams {\n const next = new URLSearchParams();\n for (const key of keep) {\n const value = searchParams.get(key);\n if (value !== null) next.set(key, value);\n }\n return next;\n}\n","import { createQuery, normalizeSort, type QueryConfig } from \"./query\";\nimport { createFilters, f as rawF } from \"./filters\";\nimport { mapMeta, mapInfiniteMeta, mapCursorMeta } from \"./meta\";\nimport { defineListSchema, type ListSchema } from \"./schema\";\nimport { readListParams, type UrlConfig } from \"./url\";\nimport type { AdapterName, WithFor } from \"./adapter\";\nimport type {\n CursorMeta,\n CursorParams,\n CursorPayload,\n FieldKey,\n Filter,\n InfiniteMeta,\n InfiniteParams,\n InfinitePayload,\n ListParams,\n ListPayload,\n Meta,\n Params,\n QueryPayload,\n RawCursorMeta,\n RawInfiniteMeta,\n RawMeta,\n Sort,\n SortDirection,\n SortInput,\n} from \"./types\";\n\n/* ---------------- resource inputs: entity-typed, adapter-aware `with` ------ */\n\nexport type ResourceListParams<T, A extends AdapterName> = Omit<ListParams<T>, \"with\"> & { with?: WithFor<A> };\nexport type ResourceInfiniteParams<T, A extends AdapterName> = Omit<InfiniteParams<T>, \"with\"> & { with?: WithFor<A> };\nexport type ResourceCursorParams<T, A extends AdapterName> = Omit<CursorParams<T>, \"with\"> & { with?: WithFor<A> };\nexport type ResourceParams<T, A extends AdapterName> = Omit<Params<T>, \"with\"> & { with?: WithFor<A> };\n\n/* ---------------------------- responses / results ------------------------- */\n\ninterface RawResponse<T, M> {\n data?: T[];\n meta?: M | null;\n}\nexport interface ListResult<T> {\n data: T[];\n meta: Meta;\n}\nexport interface InfiniteResult<T> {\n data: T[];\n meta: InfiniteMeta;\n}\nexport interface CursorResult<T> {\n data: T[];\n meta: CursorMeta;\n}\n\n/* -------------------------------- query keys ------------------------------ */\n\nexport interface ResourceKeys {\n all: readonly unknown[];\n list(payload: unknown): readonly unknown[];\n infinite(payload: unknown): readonly unknown[];\n cursor(payload: unknown): readonly unknown[];\n detail(id: unknown): readonly unknown[];\n}\n\n/* -------------------------------- resource -------------------------------- */\n\nexport interface Resource<T, A extends AdapterName> {\n /** Build an offset (page) payload. */\n list(input?: ResourceListParams<T, A>): ListPayload;\n /** Build an infinite (limit/offset) payload. */\n infinite(input?: ResourceInfiniteParams<T, A>): InfinitePayload;\n /** Build a cursor (keyset) payload. */\n cursor(input?: ResourceCursorParams<T, A>): CursorPayload;\n /** Build a paginationless payload (filter/sort/columns/with). */\n params(input?: ResourceParams<T, A>): QueryPayload;\n /** Filter builder typed to `T`'s fields. */\n f: ReturnType<typeof createFilters<T>>;\n /** Search preset — OR of `contains` across `fields` (e.g. one input → many columns). */\n search(term: string, fields: FieldKey<T>[]): Filter<T>;\n /** Declare a URL↔filter schema (identity helper). */\n schema<S extends ListSchema>(s: S): S;\n /** Build a list payload from URL search params (SSR — the non-hook `useListParams`). */\n fromSearchParams(searchParams: URLSearchParams, options: { schema: ListSchema; url?: UrlConfig; with?: WithFor<A> }): ListPayload;\n /** Stable query keys for TanStack/SWR caches. */\n keys: ResourceKeys;\n /** Map a list response's meta to camelCase (`data` typed to `T`). */\n parseList(raw?: RawResponse<T, RawMeta> | null): ListResult<T>;\n parseInfinite(raw?: RawResponse<T, RawInfiniteMeta> | null): InfiniteResult<T>;\n parseCursor(raw?: RawResponse<T, RawCursorMeta> | null): CursorResult<T>;\n}\n\n/* -------------------------------- registry -------------------------------- */\n\nexport interface RegistryDefaults {\n /** `list` page size. */\n perPage?: number;\n /** `infinite` + `cursor` page size. */\n limit?: number;\n /** `list`/`infinite` sort — `[{key,direction}]` or `[\"-createdAt\", \"id\"]` shorthand. */\n sort?: SortInput;\n /** Cursor-only defaults. */\n cursor?: { order?: SortDirection };\n}\n\nexport interface RegistryConfig<A extends AdapterName> {\n adapter: A;\n defaults?: RegistryDefaults;\n /** Drop empty filter values built from form inputs (default `true`). */\n pruneEmpty?: boolean;\n}\n\nexport interface Registry<A extends AdapterName> {\n readonly adapter: A;\n /** Entity-typed builders + filters + schema + keys + parsers. `name` = cache-key namespace (required, must be unique). */\n resource<T>(name: string): Resource<T, A>;\n /** Registry-level meta parsing (entity-agnostic — `data: unknown[]`). */\n parseList(raw?: RawResponse<unknown, RawMeta> | null): ListResult<unknown>;\n parseInfinite(raw?: RawResponse<unknown, RawInfiniteMeta> | null): InfiniteResult<unknown>;\n parseCursor(raw?: RawResponse<unknown, RawCursorMeta> | null): CursorResult<unknown>;\n}\n\n/**\n * Create a web query registry — configure defaults + backend adapter once, then\n * `registry.resource<T>()` yields entity-typed, adapter-aware query builders,\n * filters, a URL↔filter schema, cache keys and meta parsers.\n *\n * @example\n * ```ts\n * export const qk = createRegistry({ adapter: \"mongoose\", defaults: { perPage: 20, sort: [\"-createdAt\"] } });\n * const users = qk.resource<IUser>(\"users\");\n * const body = users.list({ filter: users.f.eq(\"status\", \"active\"), page });\n * ```\n */\nexport function createRegistry<A extends AdapterName>(config: RegistryConfig<A>): Registry<A> {\n const defaults = config.defaults ?? {};\n const sort: Sort = normalizeSort(defaults.sort, []); // accepts {key,direction}[] or \"-field\"[] shorthand\n const cursorOrder: SortDirection = defaults.cursor?.order ?? \"asc\";\n\n // Only set keys that are provided — createQuery merges over its own defaults,\n // and passing `undefined` would clobber them.\n const qcfg: QueryConfig = {};\n if (defaults.perPage !== undefined) qcfg.defaultPerPage = defaults.perPage;\n if (defaults.limit !== undefined) qcfg.defaultLimit = defaults.limit;\n if (sort.length) qcfg.defaultSort = sort; // only override when a real sort is given\n if (config.pruneEmpty !== undefined) qcfg.pruneEmpty = config.pruneEmpty;\n const q = createQuery(qcfg);\n\n const parseList = (raw?: RawResponse<unknown, RawMeta> | null): ListResult<unknown> => ({ data: raw?.data ?? [], meta: mapMeta(raw?.meta) });\n const parseInfinite = (raw?: RawResponse<unknown, RawInfiniteMeta> | null): InfiniteResult<unknown> => ({\n data: raw?.data ?? [],\n meta: mapInfiniteMeta(raw?.meta),\n });\n const parseCursor = (raw?: RawResponse<unknown, RawCursorMeta> | null): CursorResult<unknown> => ({\n data: raw?.data ?? [],\n meta: mapCursorMeta(raw?.meta),\n });\n\n function resource<T>(name: string): Resource<T, A> {\n const f = createFilters<T>();\n const keys: ResourceKeys = {\n all: [name],\n list: p => [name, \"list\", p],\n infinite: p => [name, \"infinite\", p],\n cursor: p => [name, \"cursor\", p],\n detail: id => [name, \"detail\", id],\n };\n return {\n list: input => q.list(input as unknown as ListParams) as unknown as ListPayload,\n infinite: input => q.infinite(input as unknown as InfiniteParams) as unknown as InfinitePayload,\n cursor: input => q.cursor({ ...(input as unknown as CursorParams), order: input?.order ?? cursorOrder }) as unknown as CursorPayload,\n params: input => q.params(input as unknown as Params) as unknown as QueryPayload,\n f,\n search: (term, fields) => rawF.or(...fields.map(field => rawF.contains(field, term))) as unknown as Filter<T>,\n schema: s => defineListSchema(s),\n fromSearchParams: (searchParams, options) =>\n q.list({ ...readListParams(options.schema, searchParams, options.url), with: options.with } as unknown as ListParams) as unknown as ListPayload,\n keys,\n parseList: raw => parseList(raw) as ListResult<T>,\n parseInfinite: raw => parseInfinite(raw) as InfiniteResult<T>,\n parseCursor: raw => parseCursor(raw) as CursorResult<T>,\n };\n }\n\n return { adapter: config.adapter, resource, parseList, parseInfinite, parseCursor };\n}\n"]}
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { S as Sort, C as CursorParams, a as CursorPayload, I as InfiniteParams, b as InfinitePayload, L as ListParams, c as ListPayload, P as Params, Q as QueryPayload, F as Filter, d as FieldCondition, e as FilterNode, f as SortInput } from './registry-DPIEOvLW.cjs';
2
- export { A as AdapterName, g as AndGroup, h as CursorMeta, i as CursorResult, D as DrizzleWith, j as FieldDescriptor, k as FieldKey, l as FilterOperator, m as FilterScalar, n as FilterValue, o as InfiniteMeta, p as InfiniteResult, q as ListResult, r as ListSchema, M as Meta, s as MongoosePopulate, N as NotGroup, O as OrGroup, t as PrismaInclude, R as RawCursorMeta, u as RawInfiniteMeta, v as RawMeta, w as Registry, x as RegistryConfig, y as RegistryDefaults, z as Resource, B as ResourceCursorParams, E as ResourceInfiniteParams, G as ResourceKeys, H as ResourceListParams, J as ResourceParams, K as SortDirection, U as UrlConfig, W as WithFor, T as createFilters, V as createRegistry, X as decodeSort, Y as defineListSchema, Z as encodeSort, _ as readListParams, $ as resetParams, a0 as schemaToFilter, a1 as searchParamsToPayload, a2 as setPage, a3 as setParam, a4 as setSize, a5 as setSort } from './registry-DPIEOvLW.cjs';
1
+ import { S as Sort, C as CursorParams, a as CursorPayload, I as InfiniteParams, b as InfinitePayload, L as ListParams, c as ListPayload, P as Params, Q as QueryPayload, F as Filter, d as FieldCondition, e as FilterNode, f as SortInput } from './registry-DbZQk28q.cjs';
2
+ export { A as AdapterName, g as AndGroup, h as CursorMeta, i as CursorResult, D as DrizzleWith, j as FieldDescriptor, k as FieldKey, l as FilterOperator, m as FilterScalar, n as FilterValue, o as InfiniteMeta, p as InfiniteResult, q as ListResult, r as ListSchema, M as Meta, s as MongoosePopulate, N as NotGroup, O as OrGroup, t as PrismaInclude, R as RawCursorMeta, u as RawInfiniteMeta, v as RawMeta, w as Registry, x as RegistryConfig, y as RegistryDefaults, z as Resource, B as ResourceCursorParams, E as ResourceInfiniteParams, G as ResourceKeys, H as ResourceListParams, J as ResourceParams, K as SortDirection, T as SortItem, U as UrlConfig, W as WithFor, V as createFilters, X as createRegistry, Y as decodeSort, Z as defineListSchema, _ as encodeSort, $ as readListParams, a0 as resetParams, a1 as schemaToFilter, a2 as searchParamsToPayload, a3 as setPage, a4 as setParam, a5 as setSize, a6 as setSort } from './registry-DbZQk28q.cjs';
3
3
  export { f } from '@querykitjs/core';
4
4
 
5
5
  /** {@link createQuery} sozlamalari — wire field nomlari va default qiymatlar. */
@@ -20,7 +20,7 @@ interface QueryConfig {
20
20
  /** Bo'sh qiymatli filterlarni tashlash (default `true`). */
21
21
  pruneEmpty?: boolean;
22
22
  }
23
- /** `"-createdAt"` yoki `{ name, direction }` → `{ name, direction }`. */
23
+ /** Normalize a sort array (objects and/or `"-field"` strings) → canonical `SortItem[]`; empty → fallback. */
24
24
  declare function normalizeSort(input: SortInput | undefined, fallback: Sort): Sort;
25
25
  /** Filterni normalizatsiya qiladi: bo'sh shartlarni prune. Massiv → flat massiv. */
26
26
  declare function normalizeFilter(filter: Filter | undefined, prune: boolean): FieldCondition[] | FilterNode;
@@ -48,7 +48,7 @@ declare function createQuery(config?: QueryConfig): {
48
48
  * ```ts
49
49
  * const payload = buildParams({
50
50
  * filter: [{ key: "name", operation: "%_%", value: s }],
51
- * sort: "-createdAt",
51
+ * sort: [{ key: "createdAt", direction: "desc" }],
52
52
  * with: { supervisor: true },
53
53
  * });
54
54
  * ```
@@ -59,8 +59,8 @@ declare function buildParams(input?: Params): QueryPayload;
59
59
  *
60
60
  * @example
61
61
  * ```ts
62
- * const payload = buildListParams({ filter, sort: "-createdAt", page: 2, perPage: 20 });
63
- * // -> { filter, sort:{name,direction}, columns, with, page, perPage }
62
+ * const payload = buildListParams({ filter, sort: [{ key: "createdAt", direction: "desc" }], page: 2, perPage: 20 });
63
+ * // -> { filter, sort: [{ key, direction }], columns, with, page, perPage }
64
64
  * ```
65
65
  */
66
66
  declare function buildListParams(input?: ListParams): ListPayload;