@querykitjs/web 1.0.0 → 2.0.1

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.
@@ -1,21 +1,23 @@
1
- import { p as ListSchema, U as UrlConfig, c as ListPayload, g as SortInput } from '../url-BpslCTRx.js';
1
+ import { A as AdapterName, r as ListSchema, U as UrlConfig, W as WithFor, c as ListPayload, f as SortInput, z as Resource } from '../registry-DPIEOvLW.js';
2
2
  import '@querykitjs/core';
3
3
 
4
- interface UseListParamsOptions {
5
- /** Joriy URL search params (react-router `useSearchParams` yoki boshqa manba). */
4
+ interface UseListParamsBaseOptions<A extends AdapterName> {
5
+ /** URL↔filter schema ({@link defineListSchema} / `resource.schema`). Memoize it. */
6
+ schema: ListSchema;
7
+ /** Current URL search params (from your router). */
6
8
  searchParams: URLSearchParams;
7
- /** Yangi search params'ni qo'llovchi setter (`(next) => void`). */
9
+ /** Apply new search params (`(next) => void`). */
8
10
  setSearchParams: (next: URLSearchParams) => void;
9
- /** List filter schema'si ({@link defineListSchema}). Memoize qiling. */
10
- schema: ListSchema;
11
- /** URL param nomlari (page/size/sortType) — ixtiyoriy. Memoize qiling. */
11
+ /** URL param names (page/size/sortType) — optional. Memoize it. */
12
12
  url?: UrlConfig;
13
+ /** Fixed relations to load on every request (not URL-driven). */
14
+ with?: WithFor<A>;
13
15
  }
14
16
  interface UseListParamsResult {
15
- /** Yuborishga tayyor normalizatsiyalangan payload. */
17
+ /** Ready-to-send list payload (built from the URL via the resource's defaults). */
16
18
  params: ListPayload;
17
19
  searchParams: URLSearchParams;
18
- /** Filter param'ini o'rnatadi/o'chiradi (`page` reset). */
20
+ /** Set/clear a filter param (resets `page`). */
19
21
  setParam: (name: string, value: string | null | undefined) => void;
20
22
  setPage: (page: number) => void;
21
23
  setSize: (size: number) => void;
@@ -23,19 +25,38 @@ interface UseListParamsResult {
23
25
  reset: (keep?: string[]) => void;
24
26
  }
25
27
  /**
26
- * List sahifasi uchun URL-state sync hook'i. `searchParams`ni tashqaridan oladi
27
- * (router-agnostik), schema'dan yuborishga tayyor `params` quradi va URL'ga
28
- * yozuvchi setter'lar beradi (filter/sort o'zgarsa `page` avtomatik reset).
28
+ * Router-agnostic list URL-state hook. Reads the URL via the schema, builds a
29
+ * ready-to-send payload through the `resource` (registry defaults + adapter), and
30
+ * returns URL setters (filter/sort/size changes reset `page`). Bring your own
31
+ * `searchParams`/`setSearchParams` (Next.js, TanStack Router, …).
32
+ */
33
+ declare function useListParamsBase<T, A extends AdapterName>(resource: Resource<T, A>, options: UseListParamsBaseOptions<A>): UseListParamsResult;
34
+
35
+ interface UseListParamsOptions<A extends AdapterName> {
36
+ /** URL↔filter schema ({@link defineListSchema} / `resource.schema`). Memoize it. */
37
+ schema: ListSchema;
38
+ /** URL param names (page/size/sortType) — optional. Memoize it. */
39
+ url?: UrlConfig;
40
+ /** Fixed relations to load on every request (not URL-driven). */
41
+ with?: WithFor<A>;
42
+ }
43
+ /**
44
+ * List URL-state hook — turnkey with **react-router-dom** (uses `useSearchParams`
45
+ * internally). Reads filters/sort/page from the URL via the schema, builds a
46
+ * ready-to-send payload through the `resource`, and returns URL setters (which
47
+ * reset `page` on filter/sort/size change). Does **not** fetch — pass `params`
48
+ * to your own axios / TanStack Query.
49
+ *
50
+ * For other routers (Next.js, TanStack Router), use {@link useListParamsBase} and
51
+ * supply `searchParams`/`setSearchParams` yourself.
29
52
  *
30
53
  * @example
31
54
  * ```tsx
32
- * const [searchParams, setSearchParams] = useSearchParams(); // react-router
33
- * const { params, setParam, setPage, setSort } = useListParams({
34
- * searchParams, setSearchParams, schema: buyersSchema,
35
- * });
36
- * // params -> http.post("/buyers/list", params)
55
+ * const users = qk.resource<IUser>("users");
56
+ * const { params, setPage, setSort } = useListParams(users, { schema: usersSchema });
57
+ * const { data } = useQuery({ queryKey: users.keys.list(params), queryFn: () => post("/users/list", params) });
37
58
  * ```
38
59
  */
39
- declare function useListParams(options: UseListParamsOptions): UseListParamsResult;
60
+ declare function useListParams<T, A extends AdapterName>(resource: Resource<T, A>, options: UseListParamsOptions<A>): UseListParamsResult;
40
61
 
41
- export { type UseListParamsOptions, type UseListParamsResult, useListParams };
62
+ export { type UseListParamsBaseOptions, type UseListParamsOptions, type UseListParamsResult, useListParams, useListParamsBase };
@@ -1,89 +1,7 @@
1
+ import { useSearchParams } from 'react-router-dom';
1
2
  import { useMemo, useCallback } from 'react';
2
- import { DEFAULT_PER_PAGE } from '@querykitjs/core';
3
3
 
4
4
  // src/react/use-list-params.ts
5
- var DEFAULTS = {
6
- filterField: "filter",
7
- sortField: "sort",
8
- columnsField: "columns",
9
- withField: "with",
10
- withDeletedField: "withDeleted",
11
- pageField: "page",
12
- perPageField: "perPage",
13
- defaultPerPage: DEFAULT_PER_PAGE,
14
- defaultSort: { name: "createdAt", direction: "desc" },
15
- pruneEmpty: true
16
- };
17
- function isEmptyValue(value) {
18
- if (value === void 0 || value === null || value === "") return true;
19
- if (Array.isArray(value) && value.length === 0) return true;
20
- return false;
21
- }
22
- function normalizeSort(input, fallback) {
23
- if (input === void 0 || input === "") return fallback;
24
- if (typeof input === "string") {
25
- const desc = input.startsWith("-");
26
- return { name: desc ? input.slice(1) : input, direction: desc ? "desc" : "asc" };
27
- }
28
- return { name: input.name ?? fallback.name, direction: input.direction ?? fallback.direction };
29
- }
30
- function normalizeCondition(condition, prune) {
31
- const operation = condition.operation ?? "=";
32
- const noValue = operation === "isNull" || operation === "isNotNull";
33
- const value = condition.value;
34
- if (!noValue && prune && isEmptyValue(value)) return void 0;
35
- const out = { key: condition.key, operation };
36
- if (!noValue) out.value = value;
37
- return out;
38
- }
39
- function normalizeNode(node, prune) {
40
- if ("and" in node) {
41
- const kids = node.and.map((n) => normalizeNode(n, prune)).filter((n) => !!n);
42
- return kids.length ? { and: kids } : void 0;
43
- }
44
- if ("or" in node) {
45
- const kids = node.or.map((n) => normalizeNode(n, prune)).filter((n) => !!n);
46
- return kids.length ? { or: kids } : void 0;
47
- }
48
- if ("not" in node) {
49
- const inner = normalizeNode(node.not, prune);
50
- return inner ? { not: inner } : void 0;
51
- }
52
- return normalizeCondition(node, prune);
53
- }
54
- function normalizeFilter(filter, prune) {
55
- if (!filter) return [];
56
- if (Array.isArray(filter)) {
57
- return filter.map((c) => normalizeCondition(c, prune)).filter((c) => !!c);
58
- }
59
- return normalizeNode(filter, prune) ?? [];
60
- }
61
- function buildBase(input, cfg) {
62
- const base = {
63
- [cfg.filterField]: normalizeFilter(input.filter, cfg.pruneEmpty),
64
- [cfg.columnsField]: input.columns ?? {},
65
- [cfg.withField]: input.with ?? {}
66
- };
67
- if (input.withDeleted !== void 0) base[cfg.withDeletedField] = input.withDeleted;
68
- return base;
69
- }
70
- function clampInt(value, fallback) {
71
- return value === void 0 || value < 1 || Number.isNaN(value) ? fallback : Math.trunc(value);
72
- }
73
- function build(input, cfg) {
74
- return { ...buildBase(input, cfg), [cfg.sortField]: normalizeSort(input.sort, cfg.defaultSort) };
75
- }
76
- function buildList(input, cfg) {
77
- return {
78
- ...build(input, cfg),
79
- [cfg.pageField]: clampInt(input.page, 1),
80
- // page >= 1 (kasr/0/manfiy → 1)
81
- [cfg.perPageField]: clampInt(input.perPage, cfg.defaultPerPage)
82
- };
83
- }
84
- function buildListParams(input = {}) {
85
- return buildList(input, DEFAULTS);
86
- }
87
5
 
88
6
  // src/url.ts
89
7
  var URL_DEFAULTS = {
@@ -96,24 +14,41 @@ function encodeSort(sort) {
96
14
  return (sort.direction === "desc" ? "-" : "") + sort.name;
97
15
  }
98
16
  function schemaToFilter(schema, searchParams) {
99
- const out = [];
100
- for (const [param, descriptor] of Object.entries(schema)) {
101
- const key = descriptor.key ?? param;
102
- if (descriptor.range) {
103
- const [fromParam, toParam] = descriptor.range;
104
- const from = searchParams.get(fromParam);
105
- const to = searchParams.get(toParam);
106
- if (from) out.push(cond(key, ">=", from));
107
- if (to) out.push(cond(key, "<=", to));
17
+ const conditions = [];
18
+ const groups = [];
19
+ for (const [param, d] of Object.entries(schema)) {
20
+ const key = d.key ?? param;
21
+ if (d.range) {
22
+ const from = searchParams.get(d.range[0]);
23
+ const to = searchParams.get(d.range[1]);
24
+ if (from) conditions.push(cond(key, ">=", from));
25
+ if (to) conditions.push(cond(key, "<=", to));
26
+ continue;
27
+ }
28
+ if (d.between) {
29
+ const from = searchParams.get(d.between[0]);
30
+ const to = searchParams.get(d.between[1]);
31
+ if (from && to) conditions.push(cond(key, "between", [from, to]));
32
+ continue;
33
+ }
34
+ const raw = searchParams.get(param);
35
+ let value = raw !== null ? raw : d.default;
36
+ if (typeof value === "string" && d.trim) value = value.trim();
37
+ if (value === void 0 || value === null || value === "") continue;
38
+ if (Array.isArray(value) && value.length === 0) continue;
39
+ if (d.search && typeof value === "string") {
40
+ groups.push({ or: d.search.map((field) => cond(field, "%_%", value)) });
108
41
  continue;
109
42
  }
110
- let value = searchParams.get(param);
111
- if (value === null || value === "") continue;
112
- if (descriptor.trim) value = value.trim();
113
- if (value === "") continue;
114
- out.push(cond(key, descriptor.operation ?? "=", value));
43
+ if (d.split && typeof value === "string") {
44
+ const delimiter = d.split === true ? "," : d.split;
45
+ const parts = value.split(delimiter).map((s) => s.trim()).filter(Boolean);
46
+ if (parts.length === 0) continue;
47
+ value = parts;
48
+ }
49
+ conditions.push(cond(key, d.operation ?? "=", value));
115
50
  }
116
- return out;
51
+ return groups.length === 0 ? conditions : { and: [...groups, ...conditions] };
117
52
  }
118
53
  function cond(key, operation, value) {
119
54
  return { key, operation, value };
@@ -128,9 +63,6 @@ function readListParams(schema, searchParams, url = {}) {
128
63
  perPage: size ? Number(size) : void 0
129
64
  };
130
65
  }
131
- function searchParamsToPayload(schema, searchParams, url) {
132
- return buildListParams(readListParams(schema, searchParams, url));
133
- }
134
66
  function clone(searchParams) {
135
67
  return new URLSearchParams(searchParams);
136
68
  }
@@ -173,10 +105,13 @@ function resetParams(searchParams, keep = []) {
173
105
  return next;
174
106
  }
175
107
 
176
- // src/react/use-list-params.ts
177
- function useListParams(options) {
178
- const { searchParams, setSearchParams, schema, url } = options;
179
- const params = useMemo(() => searchParamsToPayload(schema, searchParams, url), [schema, searchParams, url]);
108
+ // src/react/use-list-params-base.ts
109
+ function useListParamsBase(resource, options) {
110
+ const { schema, searchParams, setSearchParams, url, with: withRel } = options;
111
+ const params = useMemo(
112
+ () => resource.list({ ...readListParams(schema, searchParams, url), with: withRel }),
113
+ [resource, schema, searchParams, url, withRel]
114
+ );
180
115
  return {
181
116
  params,
182
117
  searchParams,
@@ -188,6 +123,16 @@ function useListParams(options) {
188
123
  };
189
124
  }
190
125
 
191
- export { useListParams };
126
+ // src/react/use-list-params.ts
127
+ function useListParams(resource, options) {
128
+ const [searchParams, setSearchParams] = useSearchParams();
129
+ return useListParamsBase(resource, {
130
+ ...options,
131
+ searchParams,
132
+ setSearchParams: (next) => setSearchParams(next)
133
+ });
134
+ }
135
+
136
+ export { useListParams, useListParamsBase };
192
137
  //# sourceMappingURL=index.js.map
193
138
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/query.ts","../../src/url.ts","../../src/react/use-list-params.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["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 { buildListParams } from \"./query\";\nimport type { FieldDescriptor, ListSchema } from \"./schema\";\nimport type { FieldCondition, 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/** Schema + searchParams → `FieldCondition[]` (bo'sh param'lar tashlanadi). */\nexport function schemaToFilter(schema: ListSchema, searchParams: URLSearchParams): FieldCondition[] {\n const out: FieldCondition[] = [];\n\n for (const [param, descriptor] of Object.entries(schema) as [string, FieldDescriptor][]) {\n const key = descriptor.key ?? param;\n\n if (descriptor.range) {\n const [fromParam, toParam] = descriptor.range;\n const from = searchParams.get(fromParam);\n const to = searchParams.get(toParam);\n if (from) out.push(cond(key, \">=\", from));\n if (to) out.push(cond(key, \"<=\", to));\n continue;\n }\n\n let value = searchParams.get(param);\n if (value === null || value === \"\") continue;\n if (descriptor.trim) value = value.trim();\n if (value === \"\") continue;\n out.push(cond(key, descriptor.operation ?? \"=\", value));\n }\n\n return out;\n}\n\nfunction cond(key: string, operation: FieldCondition[\"operation\"], value: string): 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 { useCallback, useMemo } from \"react\";\n\nimport type { ListSchema } from \"../schema\";\nimport type { ListPayload, SortInput } from \"../types\";\nimport type { UrlConfig } from \"../url\";\nimport { resetParams, searchParamsToPayload, setPage, setParam, setSize, setSort } from \"../url\";\n\nexport interface UseListParamsOptions {\n /** Joriy URL search params (react-router `useSearchParams` yoki boshqa manba). */\n searchParams: URLSearchParams;\n /** Yangi search params'ni qo'llovchi setter (`(next) => void`). */\n setSearchParams: (next: URLSearchParams) => void;\n /** List filter schema'si ({@link defineListSchema}). Memoize qiling. */\n schema: ListSchema;\n /** URL param nomlari (page/size/sortType) — ixtiyoriy. Memoize qiling. */\n url?: UrlConfig;\n}\n\nexport interface UseListParamsResult {\n /** Yuborishga tayyor normalizatsiyalangan payload. */\n params: ListPayload;\n searchParams: URLSearchParams;\n /** Filter param'ini o'rnatadi/o'chiradi (`page` reset). */\n setParam: (name: string, value: string | null | undefined) => void;\n setPage: (page: number) => void;\n setSize: (size: number) => void;\n setSort: (sort: SortInput) => void;\n reset: (keep?: string[]) => void;\n}\n\n/**\n * List sahifasi uchun URL-state sync hook'i. `searchParams`ni tashqaridan oladi\n * (router-agnostik), schema'dan yuborishga tayyor `params` quradi va URL'ga\n * yozuvchi setter'lar beradi (filter/sort o'zgarsa `page` avtomatik reset).\n *\n * @example\n * ```tsx\n * const [searchParams, setSearchParams] = useSearchParams(); // react-router\n * const { params, setParam, setPage, setSort } = useListParams({\n * searchParams, setSearchParams, schema: buyersSchema,\n * });\n * // params -> http.post(\"/buyers/list\", params)\n * ```\n */\nexport function useListParams(options: UseListParamsOptions): UseListParamsResult {\n const { searchParams, setSearchParams, schema, url } = options;\n\n const params = useMemo(() => searchParamsToPayload(schema, searchParams, url), [schema, searchParams, url]);\n\n return {\n params,\n searchParams,\n setParam: useCallback((name, value) => setSearchParams(setParam(searchParams, name, value, url)), [searchParams, setSearchParams, url]),\n setPage: useCallback((page: number) => setSearchParams(setPage(searchParams, page, url)), [searchParams, setSearchParams, url]),\n setSize: useCallback((size: number) => setSearchParams(setSize(searchParams, size, url)), [searchParams, setSearchParams, url]),\n setSort: useCallback((sort: SortInput) => setSearchParams(setSort(searchParams, sort, url)), [searchParams, setSearchParams, url]),\n reset: useCallback((keep?: string[]) => setSearchParams(resetParams(searchParams, keep)), [searchParams, setSearchParams]),\n };\n}\n"]}
1
+ {"version":3,"sources":["../../src/url.ts","../../src/react/use-list-params-base.ts","../../src/react/use-list-params.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["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 { useCallback, useMemo } from \"react\";\n\nimport type { AdapterName, WithFor } from \"../adapter\";\nimport type { Resource, ResourceListParams } from \"../registry\";\nimport type { ListSchema } from \"../schema\";\nimport type { ListPayload, SortInput } from \"../types\";\nimport type { UrlConfig } from \"../url\";\nimport { readListParams, resetParams, setPage, setParam, setSize, setSort } from \"../url\";\n\nexport interface UseListParamsBaseOptions<A extends AdapterName> {\n /** URL↔filter schema ({@link defineListSchema} / `resource.schema`). Memoize it. */\n schema: ListSchema;\n /** Current URL search params (from your router). */\n searchParams: URLSearchParams;\n /** Apply new search params (`(next) => void`). */\n setSearchParams: (next: URLSearchParams) => void;\n /** URL param names (page/size/sortType) — optional. Memoize it. */\n url?: UrlConfig;\n /** Fixed relations to load on every request (not URL-driven). */\n with?: WithFor<A>;\n}\n\nexport interface UseListParamsResult {\n /** Ready-to-send list payload (built from the URL via the resource's defaults). */\n params: ListPayload;\n searchParams: URLSearchParams;\n /** Set/clear a filter param (resets `page`). */\n setParam: (name: string, value: string | null | undefined) => void;\n setPage: (page: number) => void;\n setSize: (size: number) => void;\n setSort: (sort: SortInput) => void;\n reset: (keep?: string[]) => void;\n}\n\n/**\n * Router-agnostic list URL-state hook. Reads the URL via the schema, builds a\n * ready-to-send payload through the `resource` (registry defaults + adapter), and\n * returns URL setters (filter/sort/size changes reset `page`). Bring your own\n * `searchParams`/`setSearchParams` (Next.js, TanStack Router, …).\n */\nexport function useListParamsBase<T, A extends AdapterName>(resource: Resource<T, A>, options: UseListParamsBaseOptions<A>): UseListParamsResult {\n const { schema, searchParams, setSearchParams, url, with: withRel } = options;\n\n const params = useMemo(\n () => resource.list({ ...readListParams(schema, searchParams, url), with: withRel } as ResourceListParams<T, A>),\n [resource, schema, searchParams, url, withRel],\n );\n\n return {\n params,\n searchParams,\n setParam: useCallback((name, value) => setSearchParams(setParam(searchParams, name, value, url)), [searchParams, setSearchParams, url]),\n setPage: useCallback((page: number) => setSearchParams(setPage(searchParams, page, url)), [searchParams, setSearchParams, url]),\n setSize: useCallback((size: number) => setSearchParams(setSize(searchParams, size, url)), [searchParams, setSearchParams, url]),\n setSort: useCallback((sort: SortInput) => setSearchParams(setSort(searchParams, sort, url)), [searchParams, setSearchParams, url]),\n reset: useCallback((keep?: string[]) => setSearchParams(resetParams(searchParams, keep)), [searchParams, setSearchParams]),\n };\n}\n","import { useSearchParams } from \"react-router-dom\";\n\nimport type { AdapterName, WithFor } from \"../adapter\";\nimport type { Resource } from \"../registry\";\nimport type { ListSchema } from \"../schema\";\nimport type { UrlConfig } from \"../url\";\nimport { useListParamsBase, type UseListParamsResult } from \"./use-list-params-base\";\n\nexport interface UseListParamsOptions<A extends AdapterName> {\n /** URL↔filter schema ({@link defineListSchema} / `resource.schema`). Memoize it. */\n schema: ListSchema;\n /** URL param names (page/size/sortType) — optional. Memoize it. */\n url?: UrlConfig;\n /** Fixed relations to load on every request (not URL-driven). */\n with?: WithFor<A>;\n}\n\n/**\n * List URL-state hook — turnkey with **react-router-dom** (uses `useSearchParams`\n * internally). Reads filters/sort/page from the URL via the schema, builds a\n * ready-to-send payload through the `resource`, and returns URL setters (which\n * reset `page` on filter/sort/size change). Does **not** fetch — pass `params`\n * to your own axios / TanStack Query.\n *\n * For other routers (Next.js, TanStack Router), use {@link useListParamsBase} and\n * supply `searchParams`/`setSearchParams` yourself.\n *\n * @example\n * ```tsx\n * const users = qk.resource<IUser>(\"users\");\n * const { params, setPage, setSort } = useListParams(users, { schema: usersSchema });\n * const { data } = useQuery({ queryKey: users.keys.list(params), queryFn: () => post(\"/users/list\", params) });\n * ```\n */\nexport function useListParams<T, A extends AdapterName>(resource: Resource<T, A>, options: UseListParamsOptions<A>): UseListParamsResult {\n const [searchParams, setSearchParams] = useSearchParams();\n return useListParamsBase(resource, {\n ...options,\n searchParams,\n setSearchParams: next => setSearchParams(next),\n });\n}\n"]}