@querykitjs/web 1.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.
@@ -0,0 +1,193 @@
1
+ import { useMemo, useCallback } from 'react';
2
+ import { DEFAULT_PER_PAGE } from '@querykitjs/core';
3
+
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
+
88
+ // src/url.ts
89
+ var URL_DEFAULTS = {
90
+ pageParam: "page",
91
+ sizeParam: "size",
92
+ sortParam: "sortType"
93
+ };
94
+ function encodeSort(sort) {
95
+ if (!sort.name) return "";
96
+ return (sort.direction === "desc" ? "-" : "") + sort.name;
97
+ }
98
+ 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));
108
+ continue;
109
+ }
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));
115
+ }
116
+ return out;
117
+ }
118
+ function cond(key, operation, value) {
119
+ return { key, operation, value };
120
+ }
121
+ function readListParams(schema, searchParams, url = {}) {
122
+ const cfg = { ...URL_DEFAULTS, ...url };
123
+ const size = searchParams.get(cfg.sizeParam);
124
+ return {
125
+ filter: schemaToFilter(schema, searchParams),
126
+ sort: searchParams.get(cfg.sortParam) ?? void 0,
127
+ page: Number(searchParams.get(cfg.pageParam)) || 1,
128
+ perPage: size ? Number(size) : void 0
129
+ };
130
+ }
131
+ function searchParamsToPayload(schema, searchParams, url) {
132
+ return buildListParams(readListParams(schema, searchParams, url));
133
+ }
134
+ function clone(searchParams) {
135
+ return new URLSearchParams(searchParams);
136
+ }
137
+ function setParam(searchParams, name, value, url = {}) {
138
+ const cfg = { ...URL_DEFAULTS, ...url };
139
+ const next = clone(searchParams);
140
+ next.delete(cfg.pageParam);
141
+ if (value === null || value === void 0 || value === "") next.delete(name);
142
+ else next.set(name, value);
143
+ return next;
144
+ }
145
+ function setPage(searchParams, page, url = {}) {
146
+ const cfg = { ...URL_DEFAULTS, ...url };
147
+ const next = clone(searchParams);
148
+ next.set(cfg.pageParam, String(page));
149
+ return next;
150
+ }
151
+ function setSize(searchParams, size, url = {}) {
152
+ const cfg = { ...URL_DEFAULTS, ...url };
153
+ const next = clone(searchParams);
154
+ next.delete(cfg.pageParam);
155
+ next.set(cfg.sizeParam, String(size));
156
+ return next;
157
+ }
158
+ function setSort(searchParams, sort, url = {}) {
159
+ const cfg = { ...URL_DEFAULTS, ...url };
160
+ const next = clone(searchParams);
161
+ next.delete(cfg.pageParam);
162
+ const encoded = typeof sort === "string" ? sort : encodeSort(sort);
163
+ if (encoded) next.set(cfg.sortParam, encoded);
164
+ else next.delete(cfg.sortParam);
165
+ return next;
166
+ }
167
+ function resetParams(searchParams, keep = []) {
168
+ const next = new URLSearchParams();
169
+ for (const key of keep) {
170
+ const value = searchParams.get(key);
171
+ if (value !== null) next.set(key, value);
172
+ }
173
+ return next;
174
+ }
175
+
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]);
180
+ return {
181
+ params,
182
+ searchParams,
183
+ setParam: useCallback((name, value) => setSearchParams(setParam(searchParams, name, value, url)), [searchParams, setSearchParams, url]),
184
+ setPage: useCallback((page) => setSearchParams(setPage(searchParams, page, url)), [searchParams, setSearchParams, url]),
185
+ setSize: useCallback((size) => setSearchParams(setSize(searchParams, size, url)), [searchParams, setSearchParams, url]),
186
+ setSort: useCallback((sort) => setSearchParams(setSort(searchParams, sort, url)), [searchParams, setSearchParams, url]),
187
+ reset: useCallback((keep) => setSearchParams(resetParams(searchParams, keep)), [searchParams, setSearchParams])
188
+ };
189
+ }
190
+
191
+ export { useListParams };
192
+ //# sourceMappingURL=index.js.map
193
+ //# sourceMappingURL=index.js.map
@@ -0,0 +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"]}
@@ -0,0 +1,180 @@
1
+ import * as _querykitjs_core from '@querykitjs/core';
2
+
3
+ /**
4
+ * Filter/query DSL tiplari — `@querykitjs/core`dan, entity maydoni (`FieldKey`)
5
+ * bilan ixtisoslashtirilgan. querykit backend (`@querykitjs/drizzle-pg`) qabul
6
+ * qiladigan wire-format bilan mos (`{key, operation, value}`).
7
+ */
8
+
9
+ type FilterOperator = _querykitjs_core.FilterOperator;
10
+ type FilterScalar = _querykitjs_core.FilterScalar;
11
+ type FilterValue = _querykitjs_core.FilterValue;
12
+ /** Entity ustun (maydon) kaliti. */
13
+ type FieldKey<T> = Extract<keyof T, string>;
14
+ /** Bitta maydon sharti (`operation` default `"="`). */
15
+ type FieldCondition<T = Record<string, unknown>> = _querykitjs_core.FieldCondition<FieldKey<T>>;
16
+ type AndGroup<T = Record<string, unknown>> = _querykitjs_core.AndGroup<FieldKey<T>>;
17
+ type OrGroup<T = Record<string, unknown>> = _querykitjs_core.OrGroup<FieldKey<T>>;
18
+ type NotGroup<T = Record<string, unknown>> = _querykitjs_core.NotGroup<FieldKey<T>>;
19
+ /** Filter daraxti tuguni: shart yoki mantiqiy guruh. */
20
+ type FilterNode<T = Record<string, unknown>> = _querykitjs_core.FilterNode<FieldKey<T>>;
21
+ /**
22
+ * Public filter: daraxt/tugun yoki flat massiv. Flat massiv implicit `AND` va
23
+ * legacy backend (idistr) `IFilter[]` bilan to'liq mos.
24
+ */
25
+ type Filter<T = Record<string, unknown>> = _querykitjs_core.Filter<FieldKey<T>>;
26
+ type SortDirection = _querykitjs_core.SortDirection;
27
+ interface Sort {
28
+ name?: string;
29
+ direction?: SortDirection;
30
+ }
31
+ /** Sort kirishi: `"-createdAt"` (sortType string) yoki `{ name, direction }`. */
32
+ type SortInput = string | Sort;
33
+ interface Params<T = Record<string, unknown>> {
34
+ filter?: Filter<T>;
35
+ sort?: SortInput;
36
+ columns?: Record<string, boolean>;
37
+ /** Yuklanadigan relationlar (default `with` deb yuboriladi). */
38
+ with?: Record<string, unknown>;
39
+ /** Soft-delete qilingan qatorlarni ham qo'shish (backend read'lari uchun). */
40
+ withDeleted?: boolean;
41
+ }
42
+ /** Offset (sahifali) paginatsiya kirishi. */
43
+ interface ListParams<T = Record<string, unknown>> extends Params<T> {
44
+ page?: number;
45
+ perPage?: number;
46
+ }
47
+ /** Infinite-scroll (limit + offset) paginatsiya kirishi. */
48
+ interface InfiniteParams<T = Record<string, unknown>> extends Params<T> {
49
+ limit?: number;
50
+ offset?: number;
51
+ }
52
+ /** Cursor (keyset) paginatsiya kirishi. */
53
+ interface CursorParams<T = Record<string, unknown>> extends Params<T> {
54
+ limit?: number;
55
+ cursor?: string | null;
56
+ cursorKey?: string;
57
+ order?: SortDirection;
58
+ direction?: "forward" | "backward";
59
+ }
60
+ /** Normalizatsiya qilingan payload (default field nomlari bilan). */
61
+ interface QueryPayload {
62
+ filter: FilterNode | FieldCondition[];
63
+ sort: Sort;
64
+ columns: Record<string, boolean>;
65
+ with: Record<string, unknown>;
66
+ }
67
+ interface ListPayload extends QueryPayload {
68
+ page: number;
69
+ perPage: number;
70
+ }
71
+ interface InfinitePayload extends QueryPayload {
72
+ limit: number;
73
+ offset: number;
74
+ }
75
+ /** Cursor payload — `sort` o'rniga `order`/`direction` boshqaradi. */
76
+ interface CursorPayload {
77
+ filter: FilterNode | FieldCondition[];
78
+ columns: Record<string, boolean>;
79
+ with: Record<string, unknown>;
80
+ limit: number;
81
+ cursor: string | null;
82
+ order: SortDirection;
83
+ direction: "forward" | "backward";
84
+ cursorKey?: string;
85
+ }
86
+ /**
87
+ * Xom (server, snake_case) meta tiplari — `@querykitjs/core`dan (adapter shu
88
+ * shaklda qaytaradi). Server ba'zi maydonlarni bermasligi mumkinligi uchun
89
+ * mapper'lar `Partial` qabul qiladi.
90
+ */
91
+ type RawMeta = Partial<_querykitjs_core.OffsetMeta>;
92
+ type RawInfiniteMeta = Partial<_querykitjs_core.InfiniteMeta>;
93
+ type RawCursorMeta = Partial<_querykitjs_core.CursorMeta>;
94
+ /** Offset (list) — normalizatsiya qilingan meta (camelCase). */
95
+ interface Meta {
96
+ totalPages: number;
97
+ totalCount: number;
98
+ currentPage: number;
99
+ perPage: number;
100
+ hasNext: boolean;
101
+ hasPrev: boolean;
102
+ }
103
+ /** Infinite-scroll — normalizatsiya qilingan meta. */
104
+ interface InfiniteMeta {
105
+ limit: number;
106
+ offset: number;
107
+ count: number;
108
+ hasMore: boolean;
109
+ nextOffset: number | null;
110
+ }
111
+ /** Cursor — normalizatsiya qilingan meta. */
112
+ interface CursorMeta {
113
+ limit: number;
114
+ hasNext: boolean;
115
+ hasPrev: boolean;
116
+ nextCursor: string | null;
117
+ prevCursor: string | null;
118
+ }
119
+
120
+ /**
121
+ * Bitta list maydonining deklarativ ta'rifi: URL param → filter shartiga qanday
122
+ * aylantirilishi. `key` berilmasa param nomi ishlatiladi; `operation` default `=`.
123
+ */
124
+ interface FieldDescriptor {
125
+ /** Backend ustun kaliti (default — schema'dagi param nomi). */
126
+ key?: string;
127
+ /** Filter operatori (default `"="`). */
128
+ operation?: FilterOperator;
129
+ /** String qiymatni trim qilish. */
130
+ trim?: boolean;
131
+ /** Diapazon: `[fromParam, toParam]` URL param nomlari → `>=` va `<=` shartlar. */
132
+ range?: [string, string];
133
+ }
134
+ /** URL param → {@link FieldDescriptor} tavsiflar to'plami. */
135
+ type ListSchema = Record<string, FieldDescriptor>;
136
+ /**
137
+ * List filter schema'sini e'lon qiladi (identity helper — tiplarni saqlaydi).
138
+ * URL param'larni `{key, operation}` shartlariga bog'laydi, shu bilan har
139
+ * sahifada qo'lda `IFilter[]` qurishni bartaraf qiladi.
140
+ *
141
+ * @example
142
+ * ```ts
143
+ * const buyersSchema = defineListSchema({
144
+ * id: { operation: "=" },
145
+ * buyerName: { operation: "%_%", trim: true },
146
+ * status: { operation: "=" },
147
+ * createdAt: { range: ["fromDate", "toDate"] },
148
+ * });
149
+ * ```
150
+ */
151
+ declare function defineListSchema<S extends ListSchema>(schema: S): S;
152
+
153
+ /** URL param nomlari (sahifa/o'lcham/sort) — sozlanadigan. */
154
+ interface UrlConfig {
155
+ pageParam?: string;
156
+ sizeParam?: string;
157
+ sortParam?: string;
158
+ }
159
+ /** `"-createdAt"` → `{ name, direction }` (bo'sh bo'lsa `undefined`). */
160
+ declare function decodeSort(value: string | null | undefined): Sort | undefined;
161
+ /** `{ name, direction }` → `"-createdAt"` / `"createdAt"` (nomsiz bo'lsa `""`). */
162
+ declare function encodeSort(sort: Sort): string;
163
+ /** Schema + searchParams → `FieldCondition[]` (bo'sh param'lar tashlanadi). */
164
+ declare function schemaToFilter(schema: ListSchema, searchParams: URLSearchParams): FieldCondition[];
165
+ /** searchParams → normalizatsiyalanmagan {@link ListParams} (filter/sort/page/perPage). */
166
+ declare function readListParams(schema: ListSchema, searchParams: URLSearchParams, url?: UrlConfig): ListParams;
167
+ /** searchParams → to'liq, yuborishga tayyor {@link ListPayload}. */
168
+ declare function searchParamsToPayload(schema: ListSchema, searchParams: URLSearchParams, url?: UrlConfig): ListPayload;
169
+ /** Filter param'ini o'rnatadi/o'chiradi va `page`ni reset qiladi. */
170
+ declare function setParam(searchParams: URLSearchParams, name: string, value: string | null | undefined, url?: UrlConfig): URLSearchParams;
171
+ /** Sahifani o'rnatadi (`page` reset qilinmaydi). */
172
+ declare function setPage(searchParams: URLSearchParams, page: number, url?: UrlConfig): URLSearchParams;
173
+ /** Sahifa o'lchamini o'rnatadi va `page`ni reset qiladi. */
174
+ declare function setSize(searchParams: URLSearchParams, size: number, url?: UrlConfig): URLSearchParams;
175
+ /** Sortni o'rnatadi (`"-createdAt"` yoki `{name,direction}`) va `page`ni reset qiladi. */
176
+ declare function setSort(searchParams: URLSearchParams, sort: SortInput, url?: UrlConfig): URLSearchParams;
177
+ /** Barcha list param'larini tozalaydi (ixtiyoriy saqlanadigan kalitlar bilan). */
178
+ declare function resetParams(searchParams: URLSearchParams, keep?: string[]): URLSearchParams;
179
+
180
+ export { type AndGroup as A, setSize as B, type CursorParams as C, setSort as D, type FieldKey as F, type InfiniteParams as I, type ListParams as L, type Meta as M, type NotGroup as N, type OrGroup as O, type Params as P, type QueryPayload as Q, type RawCursorMeta as R, type Sort as S, type UrlConfig as U, type CursorPayload as a, type InfinitePayload as b, type ListPayload as c, type Filter as d, type FieldCondition as e, type FilterNode as f, type SortInput as g, type CursorMeta as h, type RawInfiniteMeta as i, type InfiniteMeta as j, type RawMeta as k, type FieldDescriptor as l, type FilterOperator as m, type FilterScalar as n, type FilterValue as o, type ListSchema as p, type SortDirection as q, decodeSort as r, defineListSchema as s, encodeSort as t, readListParams as u, resetParams as v, schemaToFilter as w, searchParamsToPayload as x, setPage as y, setParam as z };
@@ -0,0 +1,180 @@
1
+ import * as _querykitjs_core from '@querykitjs/core';
2
+
3
+ /**
4
+ * Filter/query DSL tiplari — `@querykitjs/core`dan, entity maydoni (`FieldKey`)
5
+ * bilan ixtisoslashtirilgan. querykit backend (`@querykitjs/drizzle-pg`) qabul
6
+ * qiladigan wire-format bilan mos (`{key, operation, value}`).
7
+ */
8
+
9
+ type FilterOperator = _querykitjs_core.FilterOperator;
10
+ type FilterScalar = _querykitjs_core.FilterScalar;
11
+ type FilterValue = _querykitjs_core.FilterValue;
12
+ /** Entity ustun (maydon) kaliti. */
13
+ type FieldKey<T> = Extract<keyof T, string>;
14
+ /** Bitta maydon sharti (`operation` default `"="`). */
15
+ type FieldCondition<T = Record<string, unknown>> = _querykitjs_core.FieldCondition<FieldKey<T>>;
16
+ type AndGroup<T = Record<string, unknown>> = _querykitjs_core.AndGroup<FieldKey<T>>;
17
+ type OrGroup<T = Record<string, unknown>> = _querykitjs_core.OrGroup<FieldKey<T>>;
18
+ type NotGroup<T = Record<string, unknown>> = _querykitjs_core.NotGroup<FieldKey<T>>;
19
+ /** Filter daraxti tuguni: shart yoki mantiqiy guruh. */
20
+ type FilterNode<T = Record<string, unknown>> = _querykitjs_core.FilterNode<FieldKey<T>>;
21
+ /**
22
+ * Public filter: daraxt/tugun yoki flat massiv. Flat massiv implicit `AND` va
23
+ * legacy backend (idistr) `IFilter[]` bilan to'liq mos.
24
+ */
25
+ type Filter<T = Record<string, unknown>> = _querykitjs_core.Filter<FieldKey<T>>;
26
+ type SortDirection = _querykitjs_core.SortDirection;
27
+ interface Sort {
28
+ name?: string;
29
+ direction?: SortDirection;
30
+ }
31
+ /** Sort kirishi: `"-createdAt"` (sortType string) yoki `{ name, direction }`. */
32
+ type SortInput = string | Sort;
33
+ interface Params<T = Record<string, unknown>> {
34
+ filter?: Filter<T>;
35
+ sort?: SortInput;
36
+ columns?: Record<string, boolean>;
37
+ /** Yuklanadigan relationlar (default `with` deb yuboriladi). */
38
+ with?: Record<string, unknown>;
39
+ /** Soft-delete qilingan qatorlarni ham qo'shish (backend read'lari uchun). */
40
+ withDeleted?: boolean;
41
+ }
42
+ /** Offset (sahifali) paginatsiya kirishi. */
43
+ interface ListParams<T = Record<string, unknown>> extends Params<T> {
44
+ page?: number;
45
+ perPage?: number;
46
+ }
47
+ /** Infinite-scroll (limit + offset) paginatsiya kirishi. */
48
+ interface InfiniteParams<T = Record<string, unknown>> extends Params<T> {
49
+ limit?: number;
50
+ offset?: number;
51
+ }
52
+ /** Cursor (keyset) paginatsiya kirishi. */
53
+ interface CursorParams<T = Record<string, unknown>> extends Params<T> {
54
+ limit?: number;
55
+ cursor?: string | null;
56
+ cursorKey?: string;
57
+ order?: SortDirection;
58
+ direction?: "forward" | "backward";
59
+ }
60
+ /** Normalizatsiya qilingan payload (default field nomlari bilan). */
61
+ interface QueryPayload {
62
+ filter: FilterNode | FieldCondition[];
63
+ sort: Sort;
64
+ columns: Record<string, boolean>;
65
+ with: Record<string, unknown>;
66
+ }
67
+ interface ListPayload extends QueryPayload {
68
+ page: number;
69
+ perPage: number;
70
+ }
71
+ interface InfinitePayload extends QueryPayload {
72
+ limit: number;
73
+ offset: number;
74
+ }
75
+ /** Cursor payload — `sort` o'rniga `order`/`direction` boshqaradi. */
76
+ interface CursorPayload {
77
+ filter: FilterNode | FieldCondition[];
78
+ columns: Record<string, boolean>;
79
+ with: Record<string, unknown>;
80
+ limit: number;
81
+ cursor: string | null;
82
+ order: SortDirection;
83
+ direction: "forward" | "backward";
84
+ cursorKey?: string;
85
+ }
86
+ /**
87
+ * Xom (server, snake_case) meta tiplari — `@querykitjs/core`dan (adapter shu
88
+ * shaklda qaytaradi). Server ba'zi maydonlarni bermasligi mumkinligi uchun
89
+ * mapper'lar `Partial` qabul qiladi.
90
+ */
91
+ type RawMeta = Partial<_querykitjs_core.OffsetMeta>;
92
+ type RawInfiniteMeta = Partial<_querykitjs_core.InfiniteMeta>;
93
+ type RawCursorMeta = Partial<_querykitjs_core.CursorMeta>;
94
+ /** Offset (list) — normalizatsiya qilingan meta (camelCase). */
95
+ interface Meta {
96
+ totalPages: number;
97
+ totalCount: number;
98
+ currentPage: number;
99
+ perPage: number;
100
+ hasNext: boolean;
101
+ hasPrev: boolean;
102
+ }
103
+ /** Infinite-scroll — normalizatsiya qilingan meta. */
104
+ interface InfiniteMeta {
105
+ limit: number;
106
+ offset: number;
107
+ count: number;
108
+ hasMore: boolean;
109
+ nextOffset: number | null;
110
+ }
111
+ /** Cursor — normalizatsiya qilingan meta. */
112
+ interface CursorMeta {
113
+ limit: number;
114
+ hasNext: boolean;
115
+ hasPrev: boolean;
116
+ nextCursor: string | null;
117
+ prevCursor: string | null;
118
+ }
119
+
120
+ /**
121
+ * Bitta list maydonining deklarativ ta'rifi: URL param → filter shartiga qanday
122
+ * aylantirilishi. `key` berilmasa param nomi ishlatiladi; `operation` default `=`.
123
+ */
124
+ interface FieldDescriptor {
125
+ /** Backend ustun kaliti (default — schema'dagi param nomi). */
126
+ key?: string;
127
+ /** Filter operatori (default `"="`). */
128
+ operation?: FilterOperator;
129
+ /** String qiymatni trim qilish. */
130
+ trim?: boolean;
131
+ /** Diapazon: `[fromParam, toParam]` URL param nomlari → `>=` va `<=` shartlar. */
132
+ range?: [string, string];
133
+ }
134
+ /** URL param → {@link FieldDescriptor} tavsiflar to'plami. */
135
+ type ListSchema = Record<string, FieldDescriptor>;
136
+ /**
137
+ * List filter schema'sini e'lon qiladi (identity helper — tiplarni saqlaydi).
138
+ * URL param'larni `{key, operation}` shartlariga bog'laydi, shu bilan har
139
+ * sahifada qo'lda `IFilter[]` qurishni bartaraf qiladi.
140
+ *
141
+ * @example
142
+ * ```ts
143
+ * const buyersSchema = defineListSchema({
144
+ * id: { operation: "=" },
145
+ * buyerName: { operation: "%_%", trim: true },
146
+ * status: { operation: "=" },
147
+ * createdAt: { range: ["fromDate", "toDate"] },
148
+ * });
149
+ * ```
150
+ */
151
+ declare function defineListSchema<S extends ListSchema>(schema: S): S;
152
+
153
+ /** URL param nomlari (sahifa/o'lcham/sort) — sozlanadigan. */
154
+ interface UrlConfig {
155
+ pageParam?: string;
156
+ sizeParam?: string;
157
+ sortParam?: string;
158
+ }
159
+ /** `"-createdAt"` → `{ name, direction }` (bo'sh bo'lsa `undefined`). */
160
+ declare function decodeSort(value: string | null | undefined): Sort | undefined;
161
+ /** `{ name, direction }` → `"-createdAt"` / `"createdAt"` (nomsiz bo'lsa `""`). */
162
+ declare function encodeSort(sort: Sort): string;
163
+ /** Schema + searchParams → `FieldCondition[]` (bo'sh param'lar tashlanadi). */
164
+ declare function schemaToFilter(schema: ListSchema, searchParams: URLSearchParams): FieldCondition[];
165
+ /** searchParams → normalizatsiyalanmagan {@link ListParams} (filter/sort/page/perPage). */
166
+ declare function readListParams(schema: ListSchema, searchParams: URLSearchParams, url?: UrlConfig): ListParams;
167
+ /** searchParams → to'liq, yuborishga tayyor {@link ListPayload}. */
168
+ declare function searchParamsToPayload(schema: ListSchema, searchParams: URLSearchParams, url?: UrlConfig): ListPayload;
169
+ /** Filter param'ini o'rnatadi/o'chiradi va `page`ni reset qiladi. */
170
+ declare function setParam(searchParams: URLSearchParams, name: string, value: string | null | undefined, url?: UrlConfig): URLSearchParams;
171
+ /** Sahifani o'rnatadi (`page` reset qilinmaydi). */
172
+ declare function setPage(searchParams: URLSearchParams, page: number, url?: UrlConfig): URLSearchParams;
173
+ /** Sahifa o'lchamini o'rnatadi va `page`ni reset qiladi. */
174
+ declare function setSize(searchParams: URLSearchParams, size: number, url?: UrlConfig): URLSearchParams;
175
+ /** Sortni o'rnatadi (`"-createdAt"` yoki `{name,direction}`) va `page`ni reset qiladi. */
176
+ declare function setSort(searchParams: URLSearchParams, sort: SortInput, url?: UrlConfig): URLSearchParams;
177
+ /** Barcha list param'larini tozalaydi (ixtiyoriy saqlanadigan kalitlar bilan). */
178
+ declare function resetParams(searchParams: URLSearchParams, keep?: string[]): URLSearchParams;
179
+
180
+ export { type AndGroup as A, setSize as B, type CursorParams as C, setSort as D, type FieldKey as F, type InfiniteParams as I, type ListParams as L, type Meta as M, type NotGroup as N, type OrGroup as O, type Params as P, type QueryPayload as Q, type RawCursorMeta as R, type Sort as S, type UrlConfig as U, type CursorPayload as a, type InfinitePayload as b, type ListPayload as c, type Filter as d, type FieldCondition as e, type FilterNode as f, type SortInput as g, type CursorMeta as h, type RawInfiniteMeta as i, type InfiniteMeta as j, type RawMeta as k, type FieldDescriptor as l, type FilterOperator as m, type FilterScalar as n, type FilterValue as o, type ListSchema as p, type SortDirection as q, decodeSort as r, defineListSchema as s, encodeSort as t, readListParams as u, resetParams as v, schemaToFilter as w, searchParamsToPayload as x, setPage as y, setParam as z };