nestjs-paginate-client 0.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.
package/LICENSE.md ADDED
@@ -0,0 +1,20 @@
1
+ # MIT License
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ 'Software'), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,111 @@
1
+ # nestjs-paginate-client
2
+
3
+ [![CI](https://github.com/M0D1xD/nestjs-paginate-client/actions/workflows/ci.yaml/badge.svg?branch=main)](https://github.com/M0D1xD/nestjs-paginate-client/actions/workflows/ci.yaml)
4
+ [![npm version](https://img.shields.io/npm/v/nestjs-paginate-client.svg)](https://www.npmjs.com/package/nestjs-paginate-client)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
+
7
+ Type-safe query string builder for backends that use [nestjs-paginate](https://github.com/ppetzold/nestjs-paginate). Build `page`, `limit`, `sortBy`, `search`, `searchBy`, `select`, and `filter` query params with TypeScript types so column names match your frontend types.
8
+
9
+ ## Installation
10
+
11
+ ```bash
12
+ npm install nestjs-paginate-client
13
+ ```
14
+
15
+ ## Compatibility
16
+
17
+ Generated query strings match the format expected by nestjs-paginate:
18
+
19
+ - **Pagination:** `page`, `limit`
20
+ - **Sort:** `sortBy=column:ASC` or `sortBy=column:DESC` (multiple allowed)
21
+ - **Search:** `search`, `searchBy` (array of column names)
22
+ - **Select:** `select=col1,col2,...`
23
+ - **Filter:** `filter.<column>=<token>` where token format is `[comparator]:[suffix]:[operator]:value`
24
+ - **Cursor:** `cursor`, `withDeleted`
25
+
26
+ ### Filter operators
27
+
28
+ | Operator | Token | Example / value |
29
+ | --------------------- | ----------- | --------------------- |
30
+ | Equals | `$eq` | `$eq:John` |
31
+ | Not | `$not` | prefix: `$not:$eq:x` |
32
+ | Greater than | `$gt` | `$gt:5` |
33
+ | Greater or equal | `$gte` | `$gte:3` |
34
+ | Less than | `$lt` | `$lt:10` |
35
+ | Less or equal | `$lte` | `$lte:7` |
36
+ | In list | `$in` | `$in:a,b,c` |
37
+ | Is null | `$null` | no value |
38
+ | Between | `$btw` | `$btw:1,10` |
39
+ | Case-insensitive like | `$ilike` | `$ilike:term` |
40
+ | Starts with | `$sw` | `$sw:prefix` |
41
+ | Array contains | `$contains` | `$contains:a,b` |
42
+ | OR | `$or` | prefix: `$or:$eq:foo` |
43
+
44
+ Nested/relation columns use dot notation: `offers.name`, `offers.price`.
45
+
46
+ ## Usage
47
+
48
+ Define your types and use the builder with typed column paths:
49
+
50
+ ```ts
51
+ import { createPaginateParams, eq, gte, in as filterIn } from 'nestjs-paginate-client';
52
+
53
+ type Offer = { name: string; price: number };
54
+ type User = { name: string; email: string; offers: Offer[] };
55
+
56
+ const params = createPaginateParams<User>()
57
+ .page(1)
58
+ .limit(10)
59
+ .sortBy('name', 'ASC')
60
+ .sortBy('email', 'DESC')
61
+ .search('john')
62
+ .searchBy(['name', 'email'])
63
+ .filter('name', eq('John'))
64
+ .filter('offers.price', gte(100))
65
+ .filter('offers.name', filterIn(['A', 'B']));
66
+
67
+ // Query string for URL
68
+ const queryString = params.toQueryString();
69
+ // e.g. ?page=1&limit=10&sortBy=name%3AASC&sortBy=email%3ADESC&search=john&...
70
+
71
+ // Params object for axios/fetch
72
+ const obj = params.toParams();
73
+ // { page: '1', limit: '10', sortBy: ['name:ASC', 'email:DESC'], 'filter.name': '$eq:John', ... }
74
+ ```
75
+
76
+ ### Filter helpers
77
+
78
+ - `eq(value)`, `gt(value)`, `gte(value)`, `lt(value)`, `lte(value)`
79
+ - `inOp(values)` / `in(values)` — in list
80
+ - `nullOp()` — is null
81
+ - `btw(min, max)` — between
82
+ - `ilike(value)`, `sw(value)` — string match
83
+ - `contains(values)` — array contains
84
+ - `not(token)` — negate (e.g. `not(eq('x'))` → `$not:$eq:x`)
85
+ - `or(token)` — OR comparator (e.g. `or(eq('foo'))` → `$or:$eq:foo`)
86
+
87
+ For full control use `buildFilterToken({ comparator, suffix, operator, value })` from the package.
88
+
89
+ ## API
90
+
91
+ - **createPaginateParams&lt;T&gt;()** — returns a `PaginateQueryBuilder<T>`.
92
+ - **PaginateQueryBuilder&lt;T&gt;** — fluent builder with:
93
+ - `.page(n)`, `.limit(n)`, `.sortBy(column, 'ASC'|'DESC')`, `.search(term)`, `.searchBy(columns)`, `.select(columns)`, `.filter(column, token)`, `.cursor(c)`, `.withDeleted(bool)`
94
+ - `.toParams()` — `Record<string, string | string[]>`
95
+ - `.toQueryString()` — `?key=value&...`
96
+ - **ColumnPath&lt;T&gt;** — type of allowed column paths for `T` (including nested, e.g. `offers.price`).
97
+ - **toQueryString(params)** — serialize a params object to a query string.
98
+
99
+ ## Contributing
100
+
101
+ Contributions are welcome. See [CONTRIBUTING.md](.github/CONTRIBUTING.md) for guidelines and [DEVELOPMENT.md](.github/DEVELOPMENT.md) for local setup and scripts.
102
+
103
+ Releases to npm are automated via [semantic-release](https://github.com/semantic-release/semantic-release) on the default branch. For token setup and release flow, see [docs/RELEASE_AND_TOKENS.md](docs/RELEASE_AND_TOKENS.md).
104
+
105
+ ## Credits
106
+
107
+ This library was inspired by [nestjs-paginate](https://github.com/ppetzold/nestjs-paginate/tree/master) by [ppetzold](https://github.com/ppetzold). The query string format (pagination, sort, search, filter, etc.) is designed to work with backends using that package.
108
+
109
+ ## License
110
+
111
+ MIT
@@ -0,0 +1,5 @@
1
+ import { Column, ColumnPath, FilterComparator, FilterOperator, FilterSuffix, PaginateParamsInput, PaginateParamsRaw, SortDirection } from "./lib/types.mjs";
2
+ import { PaginateQueryBuilder, createPaginateParams } from "./lib/builder.mjs";
3
+ import { FilterTokenOptions, btw, buildFilterToken, contains, eq, gt, gte, ilike, inOp, lt, lte, not, nullOp, or, sw } from "./lib/filter.mjs";
4
+ import { toQueryString } from "./lib/query-string.mjs";
5
+ export { type Column, type ColumnPath, FilterComparator, FilterOperator, FilterSuffix, type FilterTokenOptions, type PaginateParamsInput, type PaginateParamsRaw, PaginateQueryBuilder, type SortDirection, btw, buildFilterToken, contains, createPaginateParams, eq, gt, gte, ilike, inOp as in, inOp, lt, lte, not, nullOp, or, sw, toQueryString };
package/dist/index.mjs ADDED
@@ -0,0 +1,6 @@
1
+ import { toQueryString } from "./lib/query-string.mjs";
2
+ import { PaginateQueryBuilder, createPaginateParams } from "./lib/builder.mjs";
3
+ import { FilterComparator, FilterOperator, FilterSuffix } from "./lib/types.mjs";
4
+ import { btw, buildFilterToken, contains, eq, gt, gte, ilike, inOp, lt, lte, not, nullOp, or, sw } from "./lib/filter.mjs";
5
+
6
+ export { FilterComparator, FilterOperator, FilterSuffix, PaginateQueryBuilder, btw, buildFilterToken, contains, createPaginateParams, eq, gt, gte, ilike, inOp as in, inOp, lt, lte, not, nullOp, or, sw, toQueryString };
@@ -0,0 +1,127 @@
1
+ import { ColumnPath, PaginateParamsRaw, SortDirection } from "./types.mjs";
2
+
3
+ //#region src/lib/builder.d.ts
4
+ /**
5
+ * Fluent builder for nestjs-paginate query parameters.
6
+ * Use {@link createPaginateParams} to create an instance, then chain methods and call
7
+ * {@link PaginateQueryBuilder.toParams} or {@link PaginateQueryBuilder.toQueryString} to get the result.
8
+ *
9
+ * @typeParam T - The entity type (e.g. `User`). Column names are constrained to {@link ColumnPath}<T>.
10
+ */
11
+ declare class PaginateQueryBuilder<T> {
12
+ private _page?;
13
+ private _limit?;
14
+ private _sortBy;
15
+ private _search?;
16
+ private _searchBy;
17
+ private _select;
18
+ private _filter;
19
+ private _cursor?;
20
+ private _withDeleted?;
21
+ /**
22
+ * Set the page number to retrieve.
23
+ * If invalid, the backend will apply its default (usually 1).
24
+ *
25
+ * @param n - Page number (1-based).
26
+ * @returns This builder for chaining.
27
+ */
28
+ page(n: number): this;
29
+ /**
30
+ * Set the number of records per page.
31
+ * Backend may cap this to its configured max limit.
32
+ *
33
+ * @param n - Items per page.
34
+ * @returns This builder for chaining.
35
+ */
36
+ limit(n: number): this;
37
+ /**
38
+ * Add a sort rule. Call multiple times to sort by several columns; order of calls defines sort priority.
39
+ *
40
+ * @param column - Column path to sort by (must be in {@link ColumnPath}<T>).
41
+ * @param direction - `'ASC'` or `'DESC'`.
42
+ * @returns This builder for chaining.
43
+ */
44
+ sortBy(column: ColumnPath<T>, direction: SortDirection): this;
45
+ /**
46
+ * Set the search term to filter results across searchable columns.
47
+ *
48
+ * @param term - Search string (e.g. user-typed query).
49
+ * @returns This builder for chaining.
50
+ */
51
+ search(term: string): this;
52
+ /**
53
+ * Set which columns to search when using {@link PaginateQueryBuilder.search}.
54
+ * When not set, the backend uses all configured searchable columns.
55
+ *
56
+ * @param columns - Column paths to search in.
57
+ * @returns This builder for chaining.
58
+ */
59
+ searchBy(columns: ColumnPath<T>[]): this;
60
+ /**
61
+ * Set the list of fields to select (sparse fieldsets). When not set, the backend returns all fields.
62
+ *
63
+ * @param columns - Column paths to include in the response.
64
+ * @returns This builder for chaining.
65
+ */
66
+ select(columns: ColumnPath<T>[]): this;
67
+ /**
68
+ * Add a filter on a column. Use filter helpers (e.g. {@link eq}, {@link gte}, {@link inOp}) to build token strings.
69
+ * Call multiple times for the same column to add multiple conditions (e.g. OR filters).
70
+ *
71
+ * @param column - Column path to filter on (must be in {@link ColumnPath}<T>).
72
+ * @param token - Filter token string or array of tokens (e.g. `eq('John')`, `[or(eq('A')), or(eq('B'))]`).
73
+ * @returns This builder for chaining.
74
+ */
75
+ filter(column: ColumnPath<T>, token: string | string[]): this;
76
+ /**
77
+ * Set the cursor for cursor-based pagination (next/previous page).
78
+ * Use the value from the previous response (e.g. `meta.cursor` or `links.next` query string).
79
+ *
80
+ * @param c - Opaque cursor string from the backend.
81
+ * @returns This builder for chaining.
82
+ */
83
+ cursor(c: string): this;
84
+ /**
85
+ * Include soft-deleted records when the backend supports it.
86
+ *
87
+ * @param value - `true` to include deleted records.
88
+ * @returns This builder for chaining.
89
+ */
90
+ withDeleted(value: boolean): this;
91
+ /**
92
+ * Build a params object suitable for `URLSearchParams`, axios `params`, or fetch query string.
93
+ * Keys match nestjs-paginate: `page`, `limit`, `sortBy` (array), `search`, `searchBy`, `select`, `filter.<column>`, `cursor`, `withDeleted`.
94
+ *
95
+ * @returns Record of query parameter names to string or string[] values.
96
+ */
97
+ toParams(): PaginateParamsRaw;
98
+ /**
99
+ * Build a query string (e.g. `?page=1&limit=10&sortBy=name:ASC`) compatible with nestjs-paginate.
100
+ * Values are encoded with `encodeURIComponent`; repeated keys (sortBy, searchBy) are emitted as multiple key=value pairs.
101
+ *
102
+ * @returns Query string including leading `?`, or empty string if no params.
103
+ */
104
+ toQueryString(): string;
105
+ }
106
+ /**
107
+ * Create a new paginate query builder for entity type `T`.
108
+ * Column names in `sortBy`, `searchBy`, `select`, and `filter` will be type-checked against {@link ColumnPath}<T>.
109
+ *
110
+ * @typeParam T - The entity type (e.g. `User`, `Offer`).
111
+ * @returns A new {@link PaginateQueryBuilder} instance.
112
+ *
113
+ * @example
114
+ * ```ts
115
+ * type User = { name: string; email: string };
116
+ * const params = createPaginateParams<User>()
117
+ * .page(1)
118
+ * .limit(10)
119
+ * .sortBy('name', 'ASC')
120
+ * .filter('email', eq('a@b.com'))
121
+ * .toQueryString();
122
+ * ```
123
+ */
124
+ declare function createPaginateParams<T>(): PaginateQueryBuilder<T>;
125
+ //#endregion
126
+ export { PaginateQueryBuilder, createPaginateParams };
127
+ //# sourceMappingURL=builder.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder.d.mts","names":[],"sources":["../../src/lib/builder.ts"],"mappings":";;;;;AAUA;;;;;cAAa,oBAAA;EAAA,QACH,KAAA;EAAA,QACA,MAAA;EAAA,QACA,OAAA;EAAA,QACA,OAAA;EAAA,QACA,SAAA;EAAA,QACA,OAAA;EAAA,QACA,OAAA;EAAA,QACA,OAAA;EAAA,QACA,YAAA;EATwB;;;;;;;EAkBhC,IAAA,CAAK,CAAA;EAVG;;;;;;;EAsBR,KAAA,CAAM,CAAA;EAYoB;;;;;;;EAA1B,MAAA,CAAO,MAAA,EAAQ,UAAA,CAAW,CAAA,GAAI,SAAA,EAAW,aAAA;EAuBZ;;;;;;EAZ7B,MAAA,CAAO,IAAA;EAoCQ;;;;;;;EAxBf,QAAA,CAAS,OAAA,EAAS,UAAA,CAAW,CAAA;EAiE7B;;;;;AA2CF;EAjGE,MAAA,CAAO,OAAA,EAAS,UAAA,CAAW,CAAA;EAiGO;;;;;;;;EApFlC,MAAA,CAAO,MAAA,EAAQ,UAAA,CAAW,CAAA,GAAI,KAAA;;;;;;;;EAmB9B,MAAA,CAAO,CAAA;;;;;;;EAWP,WAAA,CAAY,KAAA;;;;;;;EAWZ,QAAA,CAAA,GAAY,iBAAA;;;;;;;EAoBZ,aAAA,CAAA;AAAA;;;;;;;;;;;;;;;;;;;iBAuBc,oBAAA,GAAA,CAAA,GAA2B,oBAAA,CAAqB,CAAA"}
@@ -0,0 +1,171 @@
1
+ import { toQueryString } from "./query-string.mjs";
2
+
3
+ //#region src/lib/builder.ts
4
+ /**
5
+ * Fluent builder for nestjs-paginate query parameters.
6
+ * Use {@link createPaginateParams} to create an instance, then chain methods and call
7
+ * {@link PaginateQueryBuilder.toParams} or {@link PaginateQueryBuilder.toQueryString} to get the result.
8
+ *
9
+ * @typeParam T - The entity type (e.g. `User`). Column names are constrained to {@link ColumnPath}<T>.
10
+ */
11
+ var PaginateQueryBuilder = class {
12
+ constructor() {
13
+ this._sortBy = [];
14
+ this._searchBy = [];
15
+ this._select = [];
16
+ this._filter = {};
17
+ }
18
+ /**
19
+ * Set the page number to retrieve.
20
+ * If invalid, the backend will apply its default (usually 1).
21
+ *
22
+ * @param n - Page number (1-based).
23
+ * @returns This builder for chaining.
24
+ */
25
+ page(n) {
26
+ this._page = n;
27
+ return this;
28
+ }
29
+ /**
30
+ * Set the number of records per page.
31
+ * Backend may cap this to its configured max limit.
32
+ *
33
+ * @param n - Items per page.
34
+ * @returns This builder for chaining.
35
+ */
36
+ limit(n) {
37
+ this._limit = n;
38
+ return this;
39
+ }
40
+ /**
41
+ * Add a sort rule. Call multiple times to sort by several columns; order of calls defines sort priority.
42
+ *
43
+ * @param column - Column path to sort by (must be in {@link ColumnPath}<T>).
44
+ * @param direction - `'ASC'` or `'DESC'`.
45
+ * @returns This builder for chaining.
46
+ */
47
+ sortBy(column, direction) {
48
+ this._sortBy.push([column, direction]);
49
+ return this;
50
+ }
51
+ /**
52
+ * Set the search term to filter results across searchable columns.
53
+ *
54
+ * @param term - Search string (e.g. user-typed query).
55
+ * @returns This builder for chaining.
56
+ */
57
+ search(term) {
58
+ this._search = term;
59
+ return this;
60
+ }
61
+ /**
62
+ * Set which columns to search when using {@link PaginateQueryBuilder.search}.
63
+ * When not set, the backend uses all configured searchable columns.
64
+ *
65
+ * @param columns - Column paths to search in.
66
+ * @returns This builder for chaining.
67
+ */
68
+ searchBy(columns) {
69
+ this._searchBy = columns.slice();
70
+ return this;
71
+ }
72
+ /**
73
+ * Set the list of fields to select (sparse fieldsets). When not set, the backend returns all fields.
74
+ *
75
+ * @param columns - Column paths to include in the response.
76
+ * @returns This builder for chaining.
77
+ */
78
+ select(columns) {
79
+ this._select = columns.slice();
80
+ return this;
81
+ }
82
+ /**
83
+ * Add a filter on a column. Use filter helpers (e.g. {@link eq}, {@link gte}, {@link inOp}) to build token strings.
84
+ * Call multiple times for the same column to add multiple conditions (e.g. OR filters).
85
+ *
86
+ * @param column - Column path to filter on (must be in {@link ColumnPath}<T>).
87
+ * @param token - Filter token string or array of tokens (e.g. `eq('John')`, `[or(eq('A')), or(eq('B'))]`).
88
+ * @returns This builder for chaining.
89
+ */
90
+ filter(column, token) {
91
+ const key = column;
92
+ const existing = this._filter[key];
93
+ const next = Array.isArray(token) ? token : [token];
94
+ this._filter[key] = existing ? [...Array.isArray(existing) ? existing : [existing], ...next] : next.length === 1 ? next[0] : next;
95
+ return this;
96
+ }
97
+ /**
98
+ * Set the cursor for cursor-based pagination (next/previous page).
99
+ * Use the value from the previous response (e.g. `meta.cursor` or `links.next` query string).
100
+ *
101
+ * @param c - Opaque cursor string from the backend.
102
+ * @returns This builder for chaining.
103
+ */
104
+ cursor(c) {
105
+ this._cursor = c;
106
+ return this;
107
+ }
108
+ /**
109
+ * Include soft-deleted records when the backend supports it.
110
+ *
111
+ * @param value - `true` to include deleted records.
112
+ * @returns This builder for chaining.
113
+ */
114
+ withDeleted(value) {
115
+ this._withDeleted = value;
116
+ return this;
117
+ }
118
+ /**
119
+ * Build a params object suitable for `URLSearchParams`, axios `params`, or fetch query string.
120
+ * Keys match nestjs-paginate: `page`, `limit`, `sortBy` (array), `search`, `searchBy`, `select`, `filter.<column>`, `cursor`, `withDeleted`.
121
+ *
122
+ * @returns Record of query parameter names to string or string[] values.
123
+ */
124
+ toParams() {
125
+ const raw = {};
126
+ if (this._page !== void 0) raw.page = String(this._page);
127
+ if (this._limit !== void 0) raw.limit = String(this._limit);
128
+ if (this._sortBy.length) raw.sortBy = this._sortBy.map(([col, dir]) => `${col}:${dir}`);
129
+ if (this._search !== void 0 && this._search !== "") raw.search = this._search;
130
+ if (this._searchBy.length) raw.searchBy = this._searchBy;
131
+ if (this._select.length) raw.select = this._select.join(",");
132
+ if (this._cursor !== void 0) raw.cursor = this._cursor;
133
+ if (this._withDeleted !== void 0) raw.withDeleted = String(this._withDeleted);
134
+ for (const [column, value] of Object.entries(this._filter)) raw[`filter.${column}`] = value;
135
+ return raw;
136
+ }
137
+ /**
138
+ * Build a query string (e.g. `?page=1&limit=10&sortBy=name:ASC`) compatible with nestjs-paginate.
139
+ * Values are encoded with `encodeURIComponent`; repeated keys (sortBy, searchBy) are emitted as multiple key=value pairs.
140
+ *
141
+ * @returns Query string including leading `?`, or empty string if no params.
142
+ */
143
+ toQueryString() {
144
+ return toQueryString(this.toParams());
145
+ }
146
+ };
147
+ /**
148
+ * Create a new paginate query builder for entity type `T`.
149
+ * Column names in `sortBy`, `searchBy`, `select`, and `filter` will be type-checked against {@link ColumnPath}<T>.
150
+ *
151
+ * @typeParam T - The entity type (e.g. `User`, `Offer`).
152
+ * @returns A new {@link PaginateQueryBuilder} instance.
153
+ *
154
+ * @example
155
+ * ```ts
156
+ * type User = { name: string; email: string };
157
+ * const params = createPaginateParams<User>()
158
+ * .page(1)
159
+ * .limit(10)
160
+ * .sortBy('name', 'ASC')
161
+ * .filter('email', eq('a@b.com'))
162
+ * .toQueryString();
163
+ * ```
164
+ */
165
+ function createPaginateParams() {
166
+ return new PaginateQueryBuilder();
167
+ }
168
+
169
+ //#endregion
170
+ export { PaginateQueryBuilder, createPaginateParams };
171
+ //# sourceMappingURL=builder.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder.mjs","names":[],"sources":["../../src/lib/builder.ts"],"sourcesContent":["import type { ColumnPath, PaginateParamsRaw, SortDirection } from './types';\nimport { toQueryString } from './query-string';\n\n/**\n * Fluent builder for nestjs-paginate query parameters.\n * Use {@link createPaginateParams} to create an instance, then chain methods and call\n * {@link PaginateQueryBuilder.toParams} or {@link PaginateQueryBuilder.toQueryString} to get the result.\n *\n * @typeParam T - The entity type (e.g. `User`). Column names are constrained to {@link ColumnPath}<T>.\n */\nexport class PaginateQueryBuilder<T> {\n private _page?: number;\n private _limit?: number;\n private _sortBy: [string, SortDirection][] = [];\n private _search?: string;\n private _searchBy: string[] = [];\n private _select: string[] = [];\n private _filter: Record<string, string | string[]> = {};\n private _cursor?: string;\n private _withDeleted?: boolean;\n\n /**\n * Set the page number to retrieve.\n * If invalid, the backend will apply its default (usually 1).\n *\n * @param n - Page number (1-based).\n * @returns This builder for chaining.\n */\n page(n: number): this {\n this._page = n;\n return this;\n }\n\n /**\n * Set the number of records per page.\n * Backend may cap this to its configured max limit.\n *\n * @param n - Items per page.\n * @returns This builder for chaining.\n */\n limit(n: number): this {\n this._limit = n;\n return this;\n }\n\n /**\n * Add a sort rule. Call multiple times to sort by several columns; order of calls defines sort priority.\n *\n * @param column - Column path to sort by (must be in {@link ColumnPath}<T>).\n * @param direction - `'ASC'` or `'DESC'`.\n * @returns This builder for chaining.\n */\n sortBy(column: ColumnPath<T>, direction: SortDirection): this {\n this._sortBy.push([column, direction]);\n return this;\n }\n\n /**\n * Set the search term to filter results across searchable columns.\n *\n * @param term - Search string (e.g. user-typed query).\n * @returns This builder for chaining.\n */\n search(term: string): this {\n this._search = term;\n return this;\n }\n\n /**\n * Set which columns to search when using {@link PaginateQueryBuilder.search}.\n * When not set, the backend uses all configured searchable columns.\n *\n * @param columns - Column paths to search in.\n * @returns This builder for chaining.\n */\n searchBy(columns: ColumnPath<T>[]): this {\n this._searchBy = columns.slice();\n return this;\n }\n\n /**\n * Set the list of fields to select (sparse fieldsets). When not set, the backend returns all fields.\n *\n * @param columns - Column paths to include in the response.\n * @returns This builder for chaining.\n */\n select(columns: ColumnPath<T>[]): this {\n this._select = columns.slice();\n return this;\n }\n\n /**\n * Add a filter on a column. Use filter helpers (e.g. {@link eq}, {@link gte}, {@link inOp}) to build token strings.\n * Call multiple times for the same column to add multiple conditions (e.g. OR filters).\n *\n * @param column - Column path to filter on (must be in {@link ColumnPath}<T>).\n * @param token - Filter token string or array of tokens (e.g. `eq('John')`, `[or(eq('A')), or(eq('B'))]`).\n * @returns This builder for chaining.\n */\n filter(column: ColumnPath<T>, token: string | string[]): this {\n const key = column as string;\n const existing = this._filter[key];\n const next = Array.isArray(token) ? token : [token];\n this._filter[key] = existing\n ? [...(Array.isArray(existing) ? existing : [existing]), ...next]\n : next.length === 1\n ? next[0]\n : next;\n return this;\n }\n\n /**\n * Set the cursor for cursor-based pagination (next/previous page).\n * Use the value from the previous response (e.g. `meta.cursor` or `links.next` query string).\n *\n * @param c - Opaque cursor string from the backend.\n * @returns This builder for chaining.\n */\n cursor(c: string): this {\n this._cursor = c;\n return this;\n }\n\n /**\n * Include soft-deleted records when the backend supports it.\n *\n * @param value - `true` to include deleted records.\n * @returns This builder for chaining.\n */\n withDeleted(value: boolean): this {\n this._withDeleted = value;\n return this;\n }\n\n /**\n * Build a params object suitable for `URLSearchParams`, axios `params`, or fetch query string.\n * Keys match nestjs-paginate: `page`, `limit`, `sortBy` (array), `search`, `searchBy`, `select`, `filter.<column>`, `cursor`, `withDeleted`.\n *\n * @returns Record of query parameter names to string or string[] values.\n */\n toParams(): PaginateParamsRaw {\n const raw: PaginateParamsRaw = {};\n if (this._page !== undefined) raw.page = String(this._page);\n if (this._limit !== undefined) raw.limit = String(this._limit);\n if (this._sortBy.length) raw.sortBy = this._sortBy.map(([col, dir]) => `${col}:${dir}`);\n if (this._search !== undefined && this._search !== '') raw.search = this._search;\n if (this._searchBy.length) raw.searchBy = this._searchBy;\n if (this._select.length) raw.select = this._select.join(',');\n if (this._cursor !== undefined) raw.cursor = this._cursor;\n if (this._withDeleted !== undefined) raw.withDeleted = String(this._withDeleted);\n for (const [column, value] of Object.entries(this._filter)) raw[`filter.${column}`] = value;\n return raw;\n }\n\n /**\n * Build a query string (e.g. `?page=1&limit=10&sortBy=name:ASC`) compatible with nestjs-paginate.\n * Values are encoded with `encodeURIComponent`; repeated keys (sortBy, searchBy) are emitted as multiple key=value pairs.\n *\n * @returns Query string including leading `?`, or empty string if no params.\n */\n toQueryString(): string {\n return toQueryString(this.toParams());\n }\n}\n\n/**\n * Create a new paginate query builder for entity type `T`.\n * Column names in `sortBy`, `searchBy`, `select`, and `filter` will be type-checked against {@link ColumnPath}<T>.\n *\n * @typeParam T - The entity type (e.g. `User`, `Offer`).\n * @returns A new {@link PaginateQueryBuilder} instance.\n *\n * @example\n * ```ts\n * type User = { name: string; email: string };\n * const params = createPaginateParams<User>()\n * .page(1)\n * .limit(10)\n * .sortBy('name', 'ASC')\n * .filter('email', eq('a@b.com'))\n * .toQueryString();\n * ```\n */\nexport function createPaginateParams<T>(): PaginateQueryBuilder<T> {\n return new PaginateQueryBuilder<T>();\n}\n"],"mappings":";;;;;;;;;;AAUA,IAAa,uBAAb,MAAqC;;iBAGU,EAAE;mBAEjB,EAAE;iBACJ,EAAE;iBACuB,EAAE;;;;;;;;;CAWvD,KAAK,GAAiB;AACpB,OAAK,QAAQ;AACb,SAAO;;;;;;;;;CAUT,MAAM,GAAiB;AACrB,OAAK,SAAS;AACd,SAAO;;;;;;;;;CAUT,OAAO,QAAuB,WAAgC;AAC5D,OAAK,QAAQ,KAAK,CAAC,QAAQ,UAAU,CAAC;AACtC,SAAO;;;;;;;;CAST,OAAO,MAAoB;AACzB,OAAK,UAAU;AACf,SAAO;;;;;;;;;CAUT,SAAS,SAAgC;AACvC,OAAK,YAAY,QAAQ,OAAO;AAChC,SAAO;;;;;;;;CAST,OAAO,SAAgC;AACrC,OAAK,UAAU,QAAQ,OAAO;AAC9B,SAAO;;;;;;;;;;CAWT,OAAO,QAAuB,OAAgC;EAC5D,MAAM,MAAM;EACZ,MAAM,WAAW,KAAK,QAAQ;EAC9B,MAAM,OAAO,MAAM,QAAQ,MAAM,GAAG,QAAQ,CAAC,MAAM;AACnD,OAAK,QAAQ,OAAO,WAChB,CAAC,GAAI,MAAM,QAAQ,SAAS,GAAG,WAAW,CAAC,SAAS,EAAG,GAAG,KAAK,GAC/D,KAAK,WAAW,IACd,KAAK,KACL;AACN,SAAO;;;;;;;;;CAUT,OAAO,GAAiB;AACtB,OAAK,UAAU;AACf,SAAO;;;;;;;;CAST,YAAY,OAAsB;AAChC,OAAK,eAAe;AACpB,SAAO;;;;;;;;CAST,WAA8B;EAC5B,MAAM,MAAyB,EAAE;AACjC,MAAI,KAAK,UAAU,OAAW,KAAI,OAAO,OAAO,KAAK,MAAM;AAC3D,MAAI,KAAK,WAAW,OAAW,KAAI,QAAQ,OAAO,KAAK,OAAO;AAC9D,MAAI,KAAK,QAAQ,OAAQ,KAAI,SAAS,KAAK,QAAQ,KAAK,CAAC,KAAK,SAAS,GAAG,IAAI,GAAG,MAAM;AACvF,MAAI,KAAK,YAAY,UAAa,KAAK,YAAY,GAAI,KAAI,SAAS,KAAK;AACzE,MAAI,KAAK,UAAU,OAAQ,KAAI,WAAW,KAAK;AAC/C,MAAI,KAAK,QAAQ,OAAQ,KAAI,SAAS,KAAK,QAAQ,KAAK,IAAI;AAC5D,MAAI,KAAK,YAAY,OAAW,KAAI,SAAS,KAAK;AAClD,MAAI,KAAK,iBAAiB,OAAW,KAAI,cAAc,OAAO,KAAK,aAAa;AAChF,OAAK,MAAM,CAAC,QAAQ,UAAU,OAAO,QAAQ,KAAK,QAAQ,CAAE,KAAI,UAAU,YAAY;AACtF,SAAO;;;;;;;;CAST,gBAAwB;AACtB,SAAO,cAAc,KAAK,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;AAsBzC,SAAgB,uBAAmD;AACjE,QAAO,IAAI,sBAAyB"}
@@ -0,0 +1,123 @@
1
+ import { FilterComparator, FilterOperator, FilterSuffix } from "./types.mjs";
2
+
3
+ //#region src/lib/filter.d.ts
4
+ /**
5
+ * Options for building a single filter token string.
6
+ * Used by `buildFilterToken` to produce nestjs-paginate–compatible filter values.
7
+ */
8
+ interface FilterTokenOptions {
9
+ /** Logical grouping: `$and` (default) or `$or`. Omitted when `$and`. */
10
+ comparator?: FilterComparator;
11
+ /** Negate the condition, e.g. `$not`. */
12
+ suffix?: FilterSuffix;
13
+ /** The filter operator (e.g. `$eq`, `$gte`, `$in`). */
14
+ operator: FilterOperator;
15
+ /** Value for the operator. Omit for `$null`; use `[min, max]` for `$btw`; comma-separated string or array for `$in`/`$contains`. */
16
+ value?: string | number | [number, number];
17
+ }
18
+ /**
19
+ * Builds a single filter token string compatible with nestjs-paginate.
20
+ *
21
+ * Token format: `[comparator]:[suffix]:[operator]:value`
22
+ * - `$null` has no value.
23
+ * - `$in` and `$contains` use a comma-separated value.
24
+ * - `$btw` uses a two-element array `[min, max]`.
25
+ *
26
+ * @param options - Token options (comparator, suffix, operator, value).
27
+ * @returns The filter token string (e.g. `$eq:5`, `$gte:3`, `$or:$eq:foo`).
28
+ */
29
+ declare function buildFilterToken(options: FilterTokenOptions): string;
30
+ /**
31
+ * Equals. Produces a token like `$eq:value`.
32
+ *
33
+ * @param value - The value to match (string or number).
34
+ * @returns Filter token string.
35
+ */
36
+ declare function eq(value: string | number): string;
37
+ /**
38
+ * Greater than. Produces a token like `$gt:value`.
39
+ *
40
+ * @param value - The numeric lower bound (exclusive).
41
+ * @returns Filter token string.
42
+ */
43
+ declare function gt(value: number): string;
44
+ /**
45
+ * Greater than or equal. Produces a token like `$gte:value`.
46
+ *
47
+ * @param value - The numeric lower bound (inclusive).
48
+ * @returns Filter token string.
49
+ */
50
+ declare function gte(value: number): string;
51
+ /**
52
+ * Less than. Produces a token like `$lt:value`.
53
+ *
54
+ * @param value - The numeric upper bound (exclusive).
55
+ * @returns Filter token string.
56
+ */
57
+ declare function lt(value: number): string;
58
+ /**
59
+ * Less than or equal. Produces a token like `$lte:value`.
60
+ *
61
+ * @param value - The numeric upper bound (inclusive).
62
+ * @returns Filter token string.
63
+ */
64
+ declare function lte(value: number): string;
65
+ /**
66
+ * In list. Produces a token like `$in:a,b,c` for “column value is one of these”.
67
+ *
68
+ * @param values - Array of allowed values (strings or numbers).
69
+ * @returns Filter token string.
70
+ */
71
+ declare function inOp(values: (string | number)[]): string;
72
+ /**
73
+ * Is null. Produces the token `$null` (no value).
74
+ *
75
+ * @returns Filter token string.
76
+ */
77
+ declare function nullOp(): string;
78
+ /**
79
+ * Between (inclusive). Produces a token like `$btw:min,max`.
80
+ *
81
+ * @param min - Lower bound (inclusive).
82
+ * @param max - Upper bound (inclusive).
83
+ * @returns Filter token string.
84
+ */
85
+ declare function btw(min: number, max: number): string;
86
+ /**
87
+ * Case-insensitive like. Produces a token like `$ilike:value` (backend typically wraps in `%` for substring match).
88
+ *
89
+ * @param value - The string to match.
90
+ * @returns Filter token string.
91
+ */
92
+ declare function ilike(value: string): string;
93
+ /**
94
+ * Starts with. Produces a token like `$sw:value` (backend typically appends `%`).
95
+ *
96
+ * @param value - The prefix string.
97
+ * @returns Filter token string.
98
+ */
99
+ declare function sw(value: string): string;
100
+ /**
101
+ * Array contains. Produces a token like `$contains:a,b` for array columns.
102
+ *
103
+ * @param values - Values that must be contained in the array.
104
+ * @returns Filter token string.
105
+ */
106
+ declare function contains(values: (string | number)[]): string;
107
+ /**
108
+ * Negate a filter token. Prepends `$not:` to the given token (e.g. `not(eq('x'))` → `$not:$eq:x`).
109
+ *
110
+ * @param token - A filter token string from another helper (e.g. `eq('x')`, `nullOp()`).
111
+ * @returns Filter token string.
112
+ */
113
+ declare function not(token: string): string;
114
+ /**
115
+ * OR comparator. Prepends `$or:` to the given token so the condition is combined with OR (e.g. `or(eq('foo'))` → `$or:$eq:foo`).
116
+ *
117
+ * @param token - A filter token string.
118
+ * @returns Filter token string.
119
+ */
120
+ declare function or(token: string): string;
121
+ //#endregion
122
+ export { FilterTokenOptions, btw, buildFilterToken, contains, eq, gt, gte, ilike, inOp, lt, lte, not, nullOp, or, sw };
123
+ //# sourceMappingURL=filter.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter.d.mts","names":[],"sources":["../../src/lib/filter.ts"],"mappings":";;;;;AAMA;;UAAiB,kBAAA;EAEF;EAAb,UAAA,GAAa,gBAAA;EAIH;EAFV,MAAA,GAAS,YAAA;EAEe;EAAxB,QAAA,EAAU,cAAA;EAJG;EAMb,KAAA;AAAA;;;;;;AAgBF;;;;;AAyBA;iBAzBgB,gBAAA,CAAiB,OAAA,EAAS,kBAAA;;;;AAmC1C;;;iBAVgB,EAAA,CAAG,KAAA;;AAoBnB;;;;;iBAVgB,EAAA,CAAG,KAAA;;;;;AA8BnB;;iBApBgB,GAAA,CAAI,KAAA;;;AA8BpB;;;;iBApBgB,EAAA,CAAG,KAAA;AAgCnB;;;;;AAWA;AAXA,iBAtBgB,GAAA,CAAI,KAAA;;;;AA2CpB;;;iBAjCgB,IAAA,CAAK,MAAA;;AA2CrB;;;;iBA/BgB,MAAA,CAAA;AAyChB;;;;;AAaA;;AAbA,iBA9BgB,GAAA,CAAI,GAAA,UAAa,GAAA;;;AAqDjC;;;;iBA3CgB,KAAA,CAAM,KAAA;;;;;;;iBAUN,EAAA,CAAG,KAAA;;;;;;;iBAUH,QAAA,CAAS,MAAA;;;;;;;iBAaT,GAAA,CAAI,KAAA;;;;;;;iBAUJ,EAAA,CAAG,KAAA"}
@@ -0,0 +1,180 @@
1
+ import { FilterComparator, FilterOperator, FilterSuffix } from "./types.mjs";
2
+
3
+ //#region src/lib/filter.ts
4
+ const SEP = ":";
5
+ /**
6
+ * Builds a single filter token string compatible with nestjs-paginate.
7
+ *
8
+ * Token format: `[comparator]:[suffix]:[operator]:value`
9
+ * - `$null` has no value.
10
+ * - `$in` and `$contains` use a comma-separated value.
11
+ * - `$btw` uses a two-element array `[min, max]`.
12
+ *
13
+ * @param options - Token options (comparator, suffix, operator, value).
14
+ * @returns The filter token string (e.g. `$eq:5`, `$gte:3`, `$or:$eq:foo`).
15
+ */
16
+ function buildFilterToken(options) {
17
+ const { comparator, suffix, operator, value } = options;
18
+ const parts = [];
19
+ if (comparator && comparator !== FilterComparator.AND) parts.push(comparator);
20
+ if (suffix) parts.push(suffix);
21
+ parts.push(operator);
22
+ if (operator === FilterOperator.NULL) return parts.join(SEP);
23
+ let valueStr;
24
+ if (Array.isArray(value)) valueStr = value.map(String).join(",");
25
+ else if (value !== void 0 && value !== null) valueStr = String(value);
26
+ else return parts.join(SEP);
27
+ parts.push(valueStr);
28
+ return parts.join(SEP);
29
+ }
30
+ /**
31
+ * Equals. Produces a token like `$eq:value`.
32
+ *
33
+ * @param value - The value to match (string or number).
34
+ * @returns Filter token string.
35
+ */
36
+ function eq(value) {
37
+ return buildFilterToken({
38
+ operator: FilterOperator.EQ,
39
+ value
40
+ });
41
+ }
42
+ /**
43
+ * Greater than. Produces a token like `$gt:value`.
44
+ *
45
+ * @param value - The numeric lower bound (exclusive).
46
+ * @returns Filter token string.
47
+ */
48
+ function gt(value) {
49
+ return buildFilterToken({
50
+ operator: FilterOperator.GT,
51
+ value
52
+ });
53
+ }
54
+ /**
55
+ * Greater than or equal. Produces a token like `$gte:value`.
56
+ *
57
+ * @param value - The numeric lower bound (inclusive).
58
+ * @returns Filter token string.
59
+ */
60
+ function gte(value) {
61
+ return buildFilterToken({
62
+ operator: FilterOperator.GTE,
63
+ value
64
+ });
65
+ }
66
+ /**
67
+ * Less than. Produces a token like `$lt:value`.
68
+ *
69
+ * @param value - The numeric upper bound (exclusive).
70
+ * @returns Filter token string.
71
+ */
72
+ function lt(value) {
73
+ return buildFilterToken({
74
+ operator: FilterOperator.LT,
75
+ value
76
+ });
77
+ }
78
+ /**
79
+ * Less than or equal. Produces a token like `$lte:value`.
80
+ *
81
+ * @param value - The numeric upper bound (inclusive).
82
+ * @returns Filter token string.
83
+ */
84
+ function lte(value) {
85
+ return buildFilterToken({
86
+ operator: FilterOperator.LTE,
87
+ value
88
+ });
89
+ }
90
+ /**
91
+ * In list. Produces a token like `$in:a,b,c` for “column value is one of these”.
92
+ *
93
+ * @param values - Array of allowed values (strings or numbers).
94
+ * @returns Filter token string.
95
+ */
96
+ function inOp(values) {
97
+ return buildFilterToken({
98
+ operator: FilterOperator.IN,
99
+ value: values.map(String).join(",")
100
+ });
101
+ }
102
+ /**
103
+ * Is null. Produces the token `$null` (no value).
104
+ *
105
+ * @returns Filter token string.
106
+ */
107
+ function nullOp() {
108
+ return buildFilterToken({ operator: FilterOperator.NULL });
109
+ }
110
+ /**
111
+ * Between (inclusive). Produces a token like `$btw:min,max`.
112
+ *
113
+ * @param min - Lower bound (inclusive).
114
+ * @param max - Upper bound (inclusive).
115
+ * @returns Filter token string.
116
+ */
117
+ function btw(min, max) {
118
+ return buildFilterToken({
119
+ operator: FilterOperator.BTW,
120
+ value: [min, max]
121
+ });
122
+ }
123
+ /**
124
+ * Case-insensitive like. Produces a token like `$ilike:value` (backend typically wraps in `%` for substring match).
125
+ *
126
+ * @param value - The string to match.
127
+ * @returns Filter token string.
128
+ */
129
+ function ilike(value) {
130
+ return buildFilterToken({
131
+ operator: FilterOperator.ILIKE,
132
+ value
133
+ });
134
+ }
135
+ /**
136
+ * Starts with. Produces a token like `$sw:value` (backend typically appends `%`).
137
+ *
138
+ * @param value - The prefix string.
139
+ * @returns Filter token string.
140
+ */
141
+ function sw(value) {
142
+ return buildFilterToken({
143
+ operator: FilterOperator.SW,
144
+ value
145
+ });
146
+ }
147
+ /**
148
+ * Array contains. Produces a token like `$contains:a,b` for array columns.
149
+ *
150
+ * @param values - Values that must be contained in the array.
151
+ * @returns Filter token string.
152
+ */
153
+ function contains(values) {
154
+ return buildFilterToken({
155
+ operator: FilterOperator.CONTAINS,
156
+ value: values.map(String).join(",")
157
+ });
158
+ }
159
+ /**
160
+ * Negate a filter token. Prepends `$not:` to the given token (e.g. `not(eq('x'))` → `$not:$eq:x`).
161
+ *
162
+ * @param token - A filter token string from another helper (e.g. `eq('x')`, `nullOp()`).
163
+ * @returns Filter token string.
164
+ */
165
+ function not(token) {
166
+ return `${FilterSuffix.NOT}${SEP}${token}`;
167
+ }
168
+ /**
169
+ * OR comparator. Prepends `$or:` to the given token so the condition is combined with OR (e.g. `or(eq('foo'))` → `$or:$eq:foo`).
170
+ *
171
+ * @param token - A filter token string.
172
+ * @returns Filter token string.
173
+ */
174
+ function or(token) {
175
+ return `${FilterComparator.OR}${SEP}${token}`;
176
+ }
177
+
178
+ //#endregion
179
+ export { btw, buildFilterToken, contains, eq, gt, gte, ilike, inOp, lt, lte, not, nullOp, or, sw };
180
+ //# sourceMappingURL=filter.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter.mjs","names":[],"sources":["../../src/lib/filter.ts"],"sourcesContent":["import { FilterComparator, FilterOperator, FilterSuffix } from './types';\n\n/**\n * Options for building a single filter token string.\n * Used by `buildFilterToken` to produce nestjs-paginate–compatible filter values.\n */\nexport interface FilterTokenOptions {\n /** Logical grouping: `$and` (default) or `$or`. Omitted when `$and`. */\n comparator?: FilterComparator;\n /** Negate the condition, e.g. `$not`. */\n suffix?: FilterSuffix;\n /** The filter operator (e.g. `$eq`, `$gte`, `$in`). */\n operator: FilterOperator;\n /** Value for the operator. Omit for `$null`; use `[min, max]` for `$btw`; comma-separated string or array for `$in`/`$contains`. */\n value?: string | number | [number, number];\n}\n\nconst SEP = ':';\n\n/**\n * Builds a single filter token string compatible with nestjs-paginate.\n *\n * Token format: `[comparator]:[suffix]:[operator]:value`\n * - `$null` has no value.\n * - `$in` and `$contains` use a comma-separated value.\n * - `$btw` uses a two-element array `[min, max]`.\n *\n * @param options - Token options (comparator, suffix, operator, value).\n * @returns The filter token string (e.g. `$eq:5`, `$gte:3`, `$or:$eq:foo`).\n */\nexport function buildFilterToken(options: FilterTokenOptions): string {\n const { comparator, suffix, operator, value } = options;\n const parts: string[] = [];\n\n if (comparator && comparator !== FilterComparator.AND) parts.push(comparator);\n if (suffix) parts.push(suffix);\n parts.push(operator);\n\n if (operator === FilterOperator.NULL) return parts.join(SEP);\n\n let valueStr: string;\n if (Array.isArray(value)) valueStr = value.map(String).join(',');\n else if (value !== undefined && value !== null) valueStr = String(value);\n else return parts.join(SEP);\n\n parts.push(valueStr);\n return parts.join(SEP);\n}\n\n/**\n * Equals. Produces a token like `$eq:value`.\n *\n * @param value - The value to match (string or number).\n * @returns Filter token string.\n */\nexport function eq(value: string | number): string {\n return buildFilterToken({ operator: FilterOperator.EQ, value });\n}\n\n/**\n * Greater than. Produces a token like `$gt:value`.\n *\n * @param value - The numeric lower bound (exclusive).\n * @returns Filter token string.\n */\nexport function gt(value: number): string {\n return buildFilterToken({ operator: FilterOperator.GT, value });\n}\n\n/**\n * Greater than or equal. Produces a token like `$gte:value`.\n *\n * @param value - The numeric lower bound (inclusive).\n * @returns Filter token string.\n */\nexport function gte(value: number): string {\n return buildFilterToken({ operator: FilterOperator.GTE, value });\n}\n\n/**\n * Less than. Produces a token like `$lt:value`.\n *\n * @param value - The numeric upper bound (exclusive).\n * @returns Filter token string.\n */\nexport function lt(value: number): string {\n return buildFilterToken({ operator: FilterOperator.LT, value });\n}\n\n/**\n * Less than or equal. Produces a token like `$lte:value`.\n *\n * @param value - The numeric upper bound (inclusive).\n * @returns Filter token string.\n */\nexport function lte(value: number): string {\n return buildFilterToken({ operator: FilterOperator.LTE, value });\n}\n\n/**\n * In list. Produces a token like `$in:a,b,c` for “column value is one of these”.\n *\n * @param values - Array of allowed values (strings or numbers).\n * @returns Filter token string.\n */\nexport function inOp(values: (string | number)[]): string {\n return buildFilterToken({\n operator: FilterOperator.IN,\n value: values.map(String).join(','),\n });\n}\n\n/**\n * Is null. Produces the token `$null` (no value).\n *\n * @returns Filter token string.\n */\nexport function nullOp(): string {\n return buildFilterToken({ operator: FilterOperator.NULL });\n}\n\n/**\n * Between (inclusive). Produces a token like `$btw:min,max`.\n *\n * @param min - Lower bound (inclusive).\n * @param max - Upper bound (inclusive).\n * @returns Filter token string.\n */\nexport function btw(min: number, max: number): string {\n return buildFilterToken({ operator: FilterOperator.BTW, value: [min, max] });\n}\n\n/**\n * Case-insensitive like. Produces a token like `$ilike:value` (backend typically wraps in `%` for substring match).\n *\n * @param value - The string to match.\n * @returns Filter token string.\n */\nexport function ilike(value: string): string {\n return buildFilterToken({ operator: FilterOperator.ILIKE, value });\n}\n\n/**\n * Starts with. Produces a token like `$sw:value` (backend typically appends `%`).\n *\n * @param value - The prefix string.\n * @returns Filter token string.\n */\nexport function sw(value: string): string {\n return buildFilterToken({ operator: FilterOperator.SW, value });\n}\n\n/**\n * Array contains. Produces a token like `$contains:a,b` for array columns.\n *\n * @param values - Values that must be contained in the array.\n * @returns Filter token string.\n */\nexport function contains(values: (string | number)[]): string {\n return buildFilterToken({\n operator: FilterOperator.CONTAINS,\n value: values.map(String).join(','),\n });\n}\n\n/**\n * Negate a filter token. Prepends `$not:` to the given token (e.g. `not(eq('x'))` → `$not:$eq:x`).\n *\n * @param token - A filter token string from another helper (e.g. `eq('x')`, `nullOp()`).\n * @returns Filter token string.\n */\nexport function not(token: string): string {\n return `${FilterSuffix.NOT}${SEP}${token}`;\n}\n\n/**\n * OR comparator. Prepends `$or:` to the given token so the condition is combined with OR (e.g. `or(eq('foo'))` → `$or:$eq:foo`).\n *\n * @param token - A filter token string.\n * @returns Filter token string.\n */\nexport function or(token: string): string {\n return `${FilterComparator.OR}${SEP}${token}`;\n}\n\n/** Alias for `inOp` (use when `in` is not a reserved word in your context). */\nexport { inOp as in };\n"],"mappings":";;;AAiBA,MAAM,MAAM;;;;;;;;;;;;AAaZ,SAAgB,iBAAiB,SAAqC;CACpE,MAAM,EAAE,YAAY,QAAQ,UAAU,UAAU;CAChD,MAAM,QAAkB,EAAE;AAE1B,KAAI,cAAc,eAAe,iBAAiB,IAAK,OAAM,KAAK,WAAW;AAC7E,KAAI,OAAQ,OAAM,KAAK,OAAO;AAC9B,OAAM,KAAK,SAAS;AAEpB,KAAI,aAAa,eAAe,KAAM,QAAO,MAAM,KAAK,IAAI;CAE5D,IAAI;AACJ,KAAI,MAAM,QAAQ,MAAM,CAAE,YAAW,MAAM,IAAI,OAAO,CAAC,KAAK,IAAI;UACvD,UAAU,UAAa,UAAU,KAAM,YAAW,OAAO,MAAM;KACnE,QAAO,MAAM,KAAK,IAAI;AAE3B,OAAM,KAAK,SAAS;AACpB,QAAO,MAAM,KAAK,IAAI;;;;;;;;AASxB,SAAgB,GAAG,OAAgC;AACjD,QAAO,iBAAiB;EAAE,UAAU,eAAe;EAAI;EAAO,CAAC;;;;;;;;AASjE,SAAgB,GAAG,OAAuB;AACxC,QAAO,iBAAiB;EAAE,UAAU,eAAe;EAAI;EAAO,CAAC;;;;;;;;AASjE,SAAgB,IAAI,OAAuB;AACzC,QAAO,iBAAiB;EAAE,UAAU,eAAe;EAAK;EAAO,CAAC;;;;;;;;AASlE,SAAgB,GAAG,OAAuB;AACxC,QAAO,iBAAiB;EAAE,UAAU,eAAe;EAAI;EAAO,CAAC;;;;;;;;AASjE,SAAgB,IAAI,OAAuB;AACzC,QAAO,iBAAiB;EAAE,UAAU,eAAe;EAAK;EAAO,CAAC;;;;;;;;AASlE,SAAgB,KAAK,QAAqC;AACxD,QAAO,iBAAiB;EACtB,UAAU,eAAe;EACzB,OAAO,OAAO,IAAI,OAAO,CAAC,KAAK,IAAI;EACpC,CAAC;;;;;;;AAQJ,SAAgB,SAAiB;AAC/B,QAAO,iBAAiB,EAAE,UAAU,eAAe,MAAM,CAAC;;;;;;;;;AAU5D,SAAgB,IAAI,KAAa,KAAqB;AACpD,QAAO,iBAAiB;EAAE,UAAU,eAAe;EAAK,OAAO,CAAC,KAAK,IAAI;EAAE,CAAC;;;;;;;;AAS9E,SAAgB,MAAM,OAAuB;AAC3C,QAAO,iBAAiB;EAAE,UAAU,eAAe;EAAO;EAAO,CAAC;;;;;;;;AASpE,SAAgB,GAAG,OAAuB;AACxC,QAAO,iBAAiB;EAAE,UAAU,eAAe;EAAI;EAAO,CAAC;;;;;;;;AASjE,SAAgB,SAAS,QAAqC;AAC5D,QAAO,iBAAiB;EACtB,UAAU,eAAe;EACzB,OAAO,OAAO,IAAI,OAAO,CAAC,KAAK,IAAI;EACpC,CAAC;;;;;;;;AASJ,SAAgB,IAAI,OAAuB;AACzC,QAAO,GAAG,aAAa,MAAM,MAAM;;;;;;;;AASrC,SAAgB,GAAG,OAAuB;AACxC,QAAO,GAAG,iBAAiB,KAAK,MAAM"}
@@ -0,0 +1,11 @@
1
+ import { PaginateParamsRaw } from "./types.mjs";
2
+
3
+ //#region src/lib/query-string.d.ts
4
+ /**
5
+ * Serialize params to a query string compatible with nestjs-paginate.
6
+ * Repeated keys (e.g. sortBy, searchBy) are emitted as multiple key=value pairs.
7
+ */
8
+ declare function toQueryString(params: PaginateParamsRaw): string;
9
+ //#endregion
10
+ export { toQueryString };
11
+ //# sourceMappingURL=query-string.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-string.d.mts","names":[],"sources":["../../src/lib/query-string.ts"],"mappings":";;;;;AAMA;;iBAAgB,aAAA,CAAc,MAAA,EAAQ,iBAAA"}
@@ -0,0 +1,19 @@
1
+ //#region src/lib/query-string.ts
2
+ /**
3
+ * Serialize params to a query string compatible with nestjs-paginate.
4
+ * Repeated keys (e.g. sortBy, searchBy) are emitted as multiple key=value pairs.
5
+ */
6
+ function toQueryString(params) {
7
+ const pairs = [];
8
+ for (const [key, val] of Object.entries(params)) {
9
+ if (val === void 0 || val === null) continue;
10
+ if (Array.isArray(val)) {
11
+ for (const v of val) if (v !== void 0 && v !== null && v !== "") pairs.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(v))}`);
12
+ } else if (val !== "") pairs.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(val))}`);
13
+ }
14
+ return pairs.length ? `?${pairs.join("&")}` : "";
15
+ }
16
+
17
+ //#endregion
18
+ export { toQueryString };
19
+ //# sourceMappingURL=query-string.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-string.mjs","names":[],"sources":["../../src/lib/query-string.ts"],"sourcesContent":["import type { PaginateParamsRaw } from './types';\n\n/**\n * Serialize params to a query string compatible with nestjs-paginate.\n * Repeated keys (e.g. sortBy, searchBy) are emitted as multiple key=value pairs.\n */\nexport function toQueryString(params: PaginateParamsRaw): string {\n const pairs: string[] = [];\n for (const [key, val] of Object.entries(params)) {\n if (val === undefined || val === null) continue;\n if (Array.isArray(val)) {\n for (const v of val) {\n if (v !== undefined && v !== null && v !== '')\n pairs.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(v))}`);\n }\n } else if (val !== '') {\n pairs.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(val))}`);\n }\n }\n return pairs.length ? `?${pairs.join('&')}` : '';\n}\n"],"mappings":";;;;;AAMA,SAAgB,cAAc,QAAmC;CAC/D,MAAM,QAAkB,EAAE;AAC1B,MAAK,MAAM,CAAC,KAAK,QAAQ,OAAO,QAAQ,OAAO,EAAE;AAC/C,MAAI,QAAQ,UAAa,QAAQ,KAAM;AACvC,MAAI,MAAM,QAAQ,IAAI,EACpB;QAAK,MAAM,KAAK,IACd,KAAI,MAAM,UAAa,MAAM,QAAQ,MAAM,GACzC,OAAM,KAAK,GAAG,mBAAmB,IAAI,CAAC,GAAG,mBAAmB,OAAO,EAAE,CAAC,GAAG;aAEpE,QAAQ,GACjB,OAAM,KAAK,GAAG,mBAAmB,IAAI,CAAC,GAAG,mBAAmB,OAAO,IAAI,CAAC,GAAG;;AAG/E,QAAO,MAAM,SAAS,IAAI,MAAM,KAAK,IAAI,KAAK"}
@@ -0,0 +1,103 @@
1
+ //#region src/lib/types.d.ts
2
+ /**
3
+ * Filter operators compatible with nestjs-paginate backend.
4
+ */
5
+ declare enum FilterOperator {
6
+ EQ = "$eq",
7
+ GT = "$gt",
8
+ GTE = "$gte",
9
+ IN = "$in",
10
+ NULL = "$null",
11
+ LT = "$lt",
12
+ LTE = "$lte",
13
+ BTW = "$btw",
14
+ ILIKE = "$ilike",
15
+ SW = "$sw",
16
+ CONTAINS = "$contains"
17
+ }
18
+ declare enum FilterSuffix {
19
+ NOT = "$not"
20
+ }
21
+ declare enum FilterComparator {
22
+ AND = "$and",
23
+ OR = "$or"
24
+ }
25
+ type SortDirection = 'ASC' | 'DESC';
26
+ type Prev = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ...0[]];
27
+ type Join<K, P> = K extends string ? P extends string ? `${K}${'' extends P ? '' : '.'}${P}` : never : never;
28
+ /**
29
+ * Column path for type T up to depth D.
30
+ * Primitives -> key; Arrays -> key + key.nestedPath; Objects -> key + key.nestedPath.
31
+ */
32
+ type Column<T, D extends number = 2> = [D] extends [never] ? never : T extends Record<string, unknown> ? { [K in keyof T]-?: K extends string ? T[K] extends string | number | boolean | Date ? `${K}` : T[K] extends (infer U)[] ? `${K}` | Join<K, Column<U, Prev[D]>> : T[K] extends Record<string, unknown> ? `${K}` | Join<K, Column<T[K], Prev[D]>> : `${K}` : never }[keyof T] : '';
33
+ type ColumnPath<T> = Column<T> extends infer C ? (C extends string ? C : never) : never;
34
+ /**
35
+ * Params shape for serialization (query string / axios params).
36
+ * Keys: page, limit, sortBy[], search, searchBy[], select, filter.<column>, cursor, withDeleted.
37
+ */
38
+ type PaginateParamsRaw = Record<string, string | string[]>;
39
+ /**
40
+ * Input shape for building paginate params, aligned with nestjs-paginate query contract.
41
+ */
42
+ interface PaginateParamsInput<T> {
43
+ /**
44
+ * Page number to retrieve.
45
+ * If you provide an invalid value, the default page number will be applied.
46
+ * @example 1
47
+ * @default 1 (when omitted, backend default applies)
48
+ */
49
+ page?: number;
50
+ /**
51
+ * Number of records per page.
52
+ * If the provided value is greater than the backend’s max limit, the max value will be applied.
53
+ * @example 20
54
+ * @default Backend config (e.g. 20)
55
+ */
56
+ limit?: number;
57
+ /**
58
+ * Sort by one or more columns and direction.
59
+ * To sort by multiple fields, provide multiple entries; the order in the array defines the sort order.
60
+ * Format: `[fieldName, 'ASC' | 'DESC']`.
61
+ * @example [['name', 'ASC'], ['createdAt', 'DESC']]
62
+ * @default Backend default sort (or unspecified order if none configured)
63
+ */
64
+ sortBy?: [ColumnPath<T>, SortDirection][] | [ColumnPath<T>, SortDirection];
65
+ /**
66
+ * Search term to filter result values across searchable columns.
67
+ * @example 'John'
68
+ */
69
+ search?: string;
70
+ /**
71
+ * List of fields to search by the search term.
72
+ * When omitted, the backend uses all configured searchable columns.
73
+ * @example ['name', 'email']
74
+ * @default All searchable fields (backend config)
75
+ */
76
+ searchBy?: ColumnPath<T>[];
77
+ /**
78
+ * List of fields to select (sparse fieldsets).
79
+ * When omitted, all fields are returned.
80
+ * @example ['id', 'name', 'email']
81
+ * @default All fields
82
+ */
83
+ select?: ColumnPath<T>[];
84
+ /**
85
+ * Filter by column. Each key is a column path; each value is a filter token string or array of tokens.
86
+ * Token format: optional `$not`, then operator (e.g. `$eq`, `$gte`, `$in`), then value. Use helpers from this package (e.g. `eq()`, `gte()`) to build tokens.
87
+ * Available operators: `$eq`, `$gt`, `$gte`, `$lt`, `$lte`, `$in`, `$null`, `$btw`, `$ilike`, `$sw`, `$contains`. Comparators: `$and`, `$or`.
88
+ * @example { name: eq('John'), age: gte(18) }
89
+ */
90
+ filter?: Partial<Record<ColumnPath<T>, string | string[]>>;
91
+ /**
92
+ * Cursor for cursor-based pagination.
93
+ * Opaque value returned by the backend in the previous page’s meta (e.g. `meta.cursor`); send it to get the next page.
94
+ */
95
+ cursor?: string;
96
+ /**
97
+ * When true, retrieve records including soft-deleted ones (if the backend supports soft delete).
98
+ */
99
+ withDeleted?: boolean;
100
+ }
101
+ //#endregion
102
+ export { Column, ColumnPath, FilterComparator, FilterOperator, FilterSuffix, PaginateParamsInput, PaginateParamsRaw, SortDirection };
103
+ //# sourceMappingURL=types.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.mts","names":[],"sources":["../../src/lib/types.ts"],"mappings":";;AAGA;;aAAY,cAAA;EACV,EAAA;EACA,EAAA;EACA,GAAA;EACA,EAAA;EACA,IAAA;EACA,EAAA;EACA,GAAA;EACA,GAAA;EACA,KAAA;EACA,EAAA;EACA,QAAA;AAAA;AAAA,aAGU,YAAA;EACV,GAAA;AAAA;AAAA,aAGU,gBAAA;EACV,GAAA;EACA,EAAA;AAAA;AAAA,KAGU,aAAA;AAAA,KAEP,IAAA;AAAA,KAEA,IAAA,SAAa,CAAA,kBACd,CAAA,qBACK,CAAA,cAAe,CAAA,cAAe,CAAA;;;AANvC;;KAcY,MAAA,6BAAmC,CAAA,4BAE3C,CAAA,SAAU,MAAA,kCAEM,CAAA,KAAM,CAAA,kBACd,CAAA,CAAE,CAAA,sCAAuC,IAAA,MACpC,CAAA,KACH,CAAA,CAAE,CAAA,2BACG,CAAA,KAAM,IAAA,CAAK,CAAA,EAAG,MAAA,CAAO,CAAA,EAAG,IAAA,CAAK,CAAA,MAChC,CAAA,CAAE,CAAA,UAAW,MAAA,uBACR,CAAA,KAAM,IAAA,CAAK,CAAA,EAAG,MAAA,CAAO,CAAA,CAAE,CAAA,GAAI,IAAA,CAAK,CAAA,SAChC,CAAA,mBAEP,CAAA;AAAA,KAGF,UAAA,MAAgB,MAAA,CAAO,CAAA,qBAAsB,CAAA,kBAAmB,CAAA;;;;;KAMhE,iBAAA,GAAoB,MAAA;;;;UAKf,mBAAA;EAnCR;;;;;;EA0CP,IAAA;EA5CgB;;;;;;EAoDhB,KAAA;EA1CU;;;;;;;EAmDV,MAAA,IAAU,UAAA,CAAW,CAAA,GAAI,aAAA,OAAoB,UAAA,CAAW,CAAA,GAAI,aAAA;EA9ClD;;;;EAoDV,MAAA;EAlDc;;;;;;EA0Dd,QAAA,GAAW,UAAA,CAAW,CAAA;EAzDC;;;;;;EAiEvB,MAAA,GAAS,UAAA,CAAW,CAAA;EA/DsB;;;;;;EAuE1C,MAAA,GAAS,OAAA,CAAQ,MAAA,CAAO,UAAA,CAAW,CAAA;EApEtB;;;;EA0Eb,MAAA;EArFE;;;EA0FF,WAAA;AAAA"}
@@ -0,0 +1,31 @@
1
+ //#region src/lib/types.ts
2
+ /**
3
+ * Filter operators compatible with nestjs-paginate backend.
4
+ */
5
+ let FilterOperator = /* @__PURE__ */ function(FilterOperator) {
6
+ FilterOperator["EQ"] = "$eq";
7
+ FilterOperator["GT"] = "$gt";
8
+ FilterOperator["GTE"] = "$gte";
9
+ FilterOperator["IN"] = "$in";
10
+ FilterOperator["NULL"] = "$null";
11
+ FilterOperator["LT"] = "$lt";
12
+ FilterOperator["LTE"] = "$lte";
13
+ FilterOperator["BTW"] = "$btw";
14
+ FilterOperator["ILIKE"] = "$ilike";
15
+ FilterOperator["SW"] = "$sw";
16
+ FilterOperator["CONTAINS"] = "$contains";
17
+ return FilterOperator;
18
+ }({});
19
+ let FilterSuffix = /* @__PURE__ */ function(FilterSuffix) {
20
+ FilterSuffix["NOT"] = "$not";
21
+ return FilterSuffix;
22
+ }({});
23
+ let FilterComparator = /* @__PURE__ */ function(FilterComparator) {
24
+ FilterComparator["AND"] = "$and";
25
+ FilterComparator["OR"] = "$or";
26
+ return FilterComparator;
27
+ }({});
28
+
29
+ //#endregion
30
+ export { FilterComparator, FilterOperator, FilterSuffix };
31
+ //# sourceMappingURL=types.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.mjs","names":[],"sources":["../../src/lib/types.ts"],"sourcesContent":["/**\n * Filter operators compatible with nestjs-paginate backend.\n */\nexport enum FilterOperator {\n EQ = '$eq',\n GT = '$gt',\n GTE = '$gte',\n IN = '$in',\n NULL = '$null',\n LT = '$lt',\n LTE = '$lte',\n BTW = '$btw',\n ILIKE = '$ilike',\n SW = '$sw',\n CONTAINS = '$contains',\n}\n\nexport enum FilterSuffix {\n NOT = '$not',\n}\n\nexport enum FilterComparator {\n AND = '$and',\n OR = '$or',\n}\n\nexport type SortDirection = 'ASC' | 'DESC';\n\ntype Prev = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ...0[]];\n\ntype Join<K, P> = K extends string\n ? P extends string\n ? `${K}${'' extends P ? '' : '.'}${P}`\n : never\n : never;\n\n/**\n * Column path for type T up to depth D.\n * Primitives -> key; Arrays -> key + key.nestedPath; Objects -> key + key.nestedPath.\n */\nexport type Column<T, D extends number = 2> = [D] extends [never]\n ? never\n : T extends Record<string, unknown>\n ? {\n [K in keyof T]-?: K extends string\n ? T[K] extends string | number | boolean | Date\n ? `${K}`\n : T[K] extends (infer U)[]\n ? `${K}` | Join<K, Column<U, Prev[D]>>\n : T[K] extends Record<string, unknown>\n ? `${K}` | Join<K, Column<T[K], Prev[D]>>\n : `${K}`\n : never;\n }[keyof T]\n : '';\n\nexport type ColumnPath<T> = Column<T> extends infer C ? (C extends string ? C : never) : never;\n\n/**\n * Params shape for serialization (query string / axios params).\n * Keys: page, limit, sortBy[], search, searchBy[], select, filter.<column>, cursor, withDeleted.\n */\nexport type PaginateParamsRaw = Record<string, string | string[]>;\n\n/**\n * Input shape for building paginate params, aligned with nestjs-paginate query contract.\n */\nexport interface PaginateParamsInput<T> {\n /**\n * Page number to retrieve.\n * If you provide an invalid value, the default page number will be applied.\n * @example 1\n * @default 1 (when omitted, backend default applies)\n */\n page?: number;\n\n /**\n * Number of records per page.\n * If the provided value is greater than the backend’s max limit, the max value will be applied.\n * @example 20\n * @default Backend config (e.g. 20)\n */\n limit?: number;\n\n /**\n * Sort by one or more columns and direction.\n * To sort by multiple fields, provide multiple entries; the order in the array defines the sort order.\n * Format: `[fieldName, 'ASC' | 'DESC']`.\n * @example [['name', 'ASC'], ['createdAt', 'DESC']]\n * @default Backend default sort (or unspecified order if none configured)\n */\n sortBy?: [ColumnPath<T>, SortDirection][] | [ColumnPath<T>, SortDirection];\n\n /**\n * Search term to filter result values across searchable columns.\n * @example 'John'\n */\n search?: string;\n\n /**\n * List of fields to search by the search term.\n * When omitted, the backend uses all configured searchable columns.\n * @example ['name', 'email']\n * @default All searchable fields (backend config)\n */\n searchBy?: ColumnPath<T>[];\n\n /**\n * List of fields to select (sparse fieldsets).\n * When omitted, all fields are returned.\n * @example ['id', 'name', 'email']\n * @default All fields\n */\n select?: ColumnPath<T>[];\n\n /**\n * Filter by column. Each key is a column path; each value is a filter token string or array of tokens.\n * Token format: optional `$not`, then operator (e.g. `$eq`, `$gte`, `$in`), then value. Use helpers from this package (e.g. `eq()`, `gte()`) to build tokens.\n * Available operators: `$eq`, `$gt`, `$gte`, `$lt`, `$lte`, `$in`, `$null`, `$btw`, `$ilike`, `$sw`, `$contains`. Comparators: `$and`, `$or`.\n * @example { name: eq('John'), age: gte(18) }\n */\n filter?: Partial<Record<ColumnPath<T>, string | string[]>>;\n\n /**\n * Cursor for cursor-based pagination.\n * Opaque value returned by the backend in the previous page’s meta (e.g. `meta.cursor`); send it to get the next page.\n */\n cursor?: string;\n\n /**\n * When true, retrieve records including soft-deleted ones (if the backend supports soft delete).\n */\n withDeleted?: boolean;\n}\n"],"mappings":";;;;AAGA,IAAY,0DAAL;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGF,IAAY,sDAAL;AACL;;;AAGF,IAAY,8DAAL;AACL;AACA"}
package/package.json ADDED
@@ -0,0 +1,87 @@
1
+ {
2
+ "name": "nestjs-paginate-client",
3
+ "version": "0.0.1",
4
+ "description": "Type-safe query string builder for nestjs-paginate compatible backends. This package is a client-side library for the nestjs-paginate package.",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.mjs",
8
+ "types": "./dist/index.d.ts",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/M0D1xD/nestjs-paginate-client.git"
12
+ },
13
+ "license": "MIT",
14
+ "author": {
15
+ "name": "Mohammed Zakout",
16
+ "email": "info@zakout.tech"
17
+ },
18
+ "exports": {
19
+ ".": {
20
+ "types": "./dist/index.d.ts",
21
+ "import": "./dist/index.mjs",
22
+ "require": "./dist/index.cjs"
23
+ }
24
+ },
25
+ "files": [
26
+ "dist",
27
+ "CHANGELOG.md",
28
+ "README.md",
29
+ "package.json"
30
+ ],
31
+ "scripts": {
32
+ "build": "tsdown",
33
+ "commit": "cz",
34
+ "prepare": "husky",
35
+ "format": "prettier ./src --write",
36
+ "format:check": "prettier ./src --check",
37
+ "lint": "eslint ./src --max-warnings 0",
38
+ "tsc:check": "tsc --noEmit",
39
+ "test": "vitest run",
40
+ "test:watch": "vitest",
41
+ "release": "release-it"
42
+ },
43
+ "config": {
44
+ "commitizen": {
45
+ "path": "cz-conventional-changelog"
46
+ }
47
+ },
48
+ "lint-staged": {
49
+ "*": "prettier --ignore-unknown --write"
50
+ },
51
+ "devDependencies": {
52
+ "@commitlint/cli": "^19.6.1",
53
+ "@commitlint/config-conventional": "^19.6.0",
54
+ "@eslint/js": "^9.15.0",
55
+ "@release-it/conventional-changelog": "10.0.1",
56
+ "@semantic-release/changelog": "^6.0.3",
57
+ "@semantic-release/git": "^10.0.1",
58
+ "commitizen": "^4.3.1",
59
+ "cz-conventional-changelog": "^3.3.0",
60
+ "eslint": "^9.16.0",
61
+ "globals": "^17.3.0",
62
+ "husky": "^9.1.7",
63
+ "prettier": "^3.8.1",
64
+ "prettier-plugin-packagejson": "^3.0.0",
65
+ "release-it": "^19.2.4",
66
+ "semantic-release": "^25.0.3",
67
+ "tsdown": "^0.20.3",
68
+ "typescript": "^5.9.3",
69
+ "typescript-eslint": "^8.55.0",
70
+ "vitest": "^4.0.18",
71
+ "@vitest/coverage-v8": "^4.0.18"
72
+ },
73
+ "keywords": [
74
+ "@nestjs",
75
+ "nestjs-paginate",
76
+ "pagination",
77
+ "query-string",
78
+ "typescript"
79
+ ],
80
+ "packageManager": "pnpm@10.29.3",
81
+ "engines": {
82
+ "node": ">=20.19.0"
83
+ },
84
+ "publishConfig": {
85
+ "access": "public"
86
+ }
87
+ }