@mikevar/data-grid 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/dist/index.cjs ADDED
@@ -0,0 +1,293 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ COL_DIRECTION_SEPARATOR: () => COL_DIRECTION_SEPARATOR,
24
+ COL_OPERATOR_SEPARATOR: () => COL_OPERATOR_SEPARATOR,
25
+ DEFAULT_CURSOR: () => DEFAULT_CURSOR,
26
+ DEFAULT_CURSOR_KEY: () => DEFAULT_CURSOR_KEY,
27
+ DEFAULT_FILTER_MODE: () => DEFAULT_FILTER_MODE,
28
+ DEFAULT_FILTER_MODE_KEY: () => DEFAULT_FILTER_MODE_KEY,
29
+ DEFAULT_LIMIT: () => DEFAULT_LIMIT,
30
+ DEFAULT_LIMIT_KEY: () => DEFAULT_LIMIT_KEY,
31
+ DEFAULT_ORDERS_KEY: () => DEFAULT_ORDERS_KEY,
32
+ DEFAULT_PAGE: () => DEFAULT_PAGE,
33
+ DEFAULT_PAGE_KEY: () => DEFAULT_PAGE_KEY,
34
+ DEFAULT_PAGINATION_MODE: () => DEFAULT_PAGINATION_MODE,
35
+ DEFAULT_PAGINATION_MODE_KEY: () => DEFAULT_PAGINATION_MODE_KEY,
36
+ DEFAULT_SEARCH: () => DEFAULT_SEARCH,
37
+ DEFAULT_SEARCH_KEY: () => DEFAULT_SEARCH_KEY,
38
+ FILTER_OPERATORS: () => FILTER_OPERATORS,
39
+ isFilterMode: () => isFilterMode,
40
+ isFilterOperator: () => isFilterOperator,
41
+ isOrderDirection: () => isOrderDirection,
42
+ isPaginationMode: () => isPaginationMode,
43
+ mergeDefaultAndCustomQueryKeys: () => mergeDefaultAndCustomQueryKeys,
44
+ mergeDefaultQueryValues: () => mergeDefaultQueryValues,
45
+ normalizeParsedQueryObject: () => normalizeParsedQueryObject,
46
+ parseAndNormalize: () => parseAndNormalize,
47
+ parseAndNormalizeQueryObject: () => parseAndNormalizeQueryObject,
48
+ parseQueryObject: () => parseQueryObject,
49
+ toPositiveInt: () => toPositiveInt
50
+ });
51
+ module.exports = __toCommonJS(index_exports);
52
+
53
+ // src/consts.ts
54
+ var COL_DIRECTION_SEPARATOR = ":";
55
+ var COL_OPERATOR_SEPARATOR = "__";
56
+ var DEFAULT_FILTER_MODE_KEY = "filterMode";
57
+ var DEFAULT_SEARCH_KEY = "search";
58
+ var DEFAULT_PAGINATION_MODE_KEY = "paginationMode";
59
+ var DEFAULT_PAGE_KEY = "page";
60
+ var DEFAULT_LIMIT_KEY = "limit";
61
+ var DEFAULT_CURSOR_KEY = "cursor";
62
+ var DEFAULT_ORDERS_KEY = "orders";
63
+ var DEFAULT_PAGINATION_MODE = "offset";
64
+ var DEFAULT_PAGE = 1;
65
+ var DEFAULT_LIMIT = 10;
66
+ var DEFAULT_CURSOR = "";
67
+ var DEFAULT_FILTER_MODE = "search";
68
+ var DEFAULT_SEARCH = "";
69
+ var FILTER_OPERATORS = [
70
+ "eq",
71
+ "gt",
72
+ "gte",
73
+ "lt",
74
+ "lte",
75
+ "between",
76
+ "iLike",
77
+ "isNull",
78
+ "inArray"
79
+ ];
80
+
81
+ // src/utils.ts
82
+ function mergeDefaultAndCustomQueryKeys(customQueryKeys) {
83
+ const DEFAULT_QUERY_KEYS = {
84
+ filterMode: DEFAULT_FILTER_MODE_KEY,
85
+ search: DEFAULT_SEARCH_KEY,
86
+ paginationMode: DEFAULT_PAGINATION_MODE_KEY,
87
+ page: DEFAULT_PAGE_KEY,
88
+ limit: DEFAULT_LIMIT_KEY,
89
+ cursor: DEFAULT_CURSOR_KEY,
90
+ orders: DEFAULT_ORDERS_KEY
91
+ };
92
+ return {
93
+ filterMode: customQueryKeys?.filterMode ?? DEFAULT_QUERY_KEYS.filterMode,
94
+ search: customQueryKeys?.search ?? DEFAULT_QUERY_KEYS.search,
95
+ paginationMode: customQueryKeys?.paginationMode ?? DEFAULT_QUERY_KEYS.paginationMode,
96
+ page: customQueryKeys?.page ?? DEFAULT_QUERY_KEYS.page,
97
+ limit: customQueryKeys?.limit ?? DEFAULT_QUERY_KEYS.limit,
98
+ cursor: customQueryKeys?.cursor ?? DEFAULT_QUERY_KEYS.cursor,
99
+ orders: customQueryKeys?.orders ?? DEFAULT_QUERY_KEYS.orders
100
+ };
101
+ }
102
+ function mergeDefaultQueryValues(defaultQueryValues) {
103
+ if (defaultQueryValues === void 0) {
104
+ return {
105
+ pagination: {
106
+ mode: DEFAULT_PAGINATION_MODE,
107
+ page: DEFAULT_PAGE,
108
+ limit: DEFAULT_LIMIT,
109
+ cursor: DEFAULT_CURSOR
110
+ },
111
+ sorting: {
112
+ orders: []
113
+ },
114
+ filtering: {
115
+ mode: DEFAULT_FILTER_MODE,
116
+ search: DEFAULT_SEARCH,
117
+ filters: []
118
+ }
119
+ };
120
+ }
121
+ return {
122
+ pagination: {
123
+ mode: defaultQueryValues.paginationMode ?? DEFAULT_PAGINATION_MODE,
124
+ page: defaultQueryValues.page ?? DEFAULT_PAGE,
125
+ limit: defaultQueryValues.limit ?? DEFAULT_LIMIT,
126
+ cursor: defaultQueryValues.cursor ?? DEFAULT_CURSOR
127
+ },
128
+ sorting: {
129
+ orders: defaultQueryValues.orders ?? []
130
+ },
131
+ filtering: {
132
+ mode: defaultQueryValues.filterMode ?? DEFAULT_FILTER_MODE,
133
+ search: defaultQueryValues.search ?? DEFAULT_SEARCH,
134
+ filters: defaultQueryValues.filters ?? []
135
+ }
136
+ };
137
+ }
138
+
139
+ // src/helpers.ts
140
+ function isPaginationMode(v) {
141
+ return v === "offset" || v === "cursor";
142
+ }
143
+ function isOrderDirection(v) {
144
+ return v === "asc" || v === "desc";
145
+ }
146
+ function isFilterMode(v) {
147
+ return v === "search" || v === "filter";
148
+ }
149
+ function toPositiveInt(value, fallback) {
150
+ const n = Number(value);
151
+ return Number.isFinite(n) && n > 0 ? n : fallback;
152
+ }
153
+ function isFilterOperator(v) {
154
+ return FILTER_OPERATORS.includes(v);
155
+ }
156
+
157
+ // src/parse-query-object.ts
158
+ function parseQueryObject({
159
+ query,
160
+ queryKeys
161
+ }) {
162
+ const keys = mergeDefaultAndCustomQueryKeys(queryKeys);
163
+ const reserved = new Set(Object.values(keys));
164
+ const filters = {};
165
+ for (const [key, value] of Object.entries(query)) {
166
+ if (!reserved.has(key)) {
167
+ filters[key] = value;
168
+ }
169
+ }
170
+ return {
171
+ pagination: {
172
+ mode: query[keys.paginationMode],
173
+ page: query[keys.page],
174
+ limit: query[keys.limit],
175
+ cursor: query[keys.cursor]
176
+ },
177
+ sorting: {
178
+ orders: query[keys.orders]
179
+ },
180
+ filtering: {
181
+ mode: query[keys.filterMode],
182
+ search: query[keys.search],
183
+ filters
184
+ }
185
+ };
186
+ }
187
+
188
+ // src/normalize-parsed-query-object.ts
189
+ function normalizeParsedQueryObject({
190
+ parsedQuery,
191
+ defaultQueryValues
192
+ }) {
193
+ const defaultValues = mergeDefaultQueryValues(defaultQueryValues);
194
+ const paginationMode = isPaginationMode(parsedQuery.pagination.mode) ? parsedQuery.pagination.mode : defaultValues.pagination.mode;
195
+ const page = toPositiveInt(
196
+ parsedQuery.pagination.page,
197
+ defaultValues.pagination.page
198
+ );
199
+ const limit = toPositiveInt(
200
+ parsedQuery.pagination.limit,
201
+ defaultValues.pagination.limit
202
+ );
203
+ const cursor = parsedQuery.pagination.cursor ?? defaultValues.pagination.cursor;
204
+ const pagination = paginationMode === "offset" ? {
205
+ mode: "offset",
206
+ page,
207
+ limit
208
+ } : {
209
+ mode: "cursor",
210
+ cursor,
211
+ limit
212
+ };
213
+ const explodedOrders = parsedQuery.sorting.orders?.split(",") || [];
214
+ const orders = explodedOrders.map((order) => {
215
+ const [column, direction] = order.split(COL_DIRECTION_SEPARATOR).map((s) => s.trim());
216
+ if (!column) return null;
217
+ return {
218
+ column,
219
+ direction: isOrderDirection(direction) ? direction : "asc"
220
+ };
221
+ }).filter((item) => item !== null);
222
+ const filters = Object.entries(parsedQuery.filtering.filters).map(([colOperator, value]) => {
223
+ const [col, operator] = colOperator.split(COL_OPERATOR_SEPARATOR);
224
+ if (!col || !isFilterOperator(operator)) return null;
225
+ const column = col.trim();
226
+ const valueTrimmed = value.trim();
227
+ return {
228
+ column,
229
+ operator,
230
+ value: valueTrimmed
231
+ };
232
+ }).filter((item) => item !== null);
233
+ return {
234
+ pagination,
235
+ sorting: {
236
+ orders
237
+ },
238
+ filtering: {
239
+ mode: isFilterMode(parsedQuery.filtering.mode) ? parsedQuery.filtering.mode : defaultValues.filtering.mode,
240
+ search: parsedQuery.filtering.search ?? defaultValues.filtering.search,
241
+ filters
242
+ }
243
+ };
244
+ }
245
+
246
+ // src/parse-and-normalize-query-object.ts
247
+ function parseAndNormalizeQueryObject(options) {
248
+ const parsed = parseQueryObject({
249
+ query: options.query,
250
+ queryKeys: options.queryKeys
251
+ });
252
+ const normalized = normalizeParsedQueryObject({
253
+ parsedQuery: parsed,
254
+ defaultQueryValues: options.defaultQueryValues
255
+ });
256
+ return {
257
+ parsed,
258
+ normalized
259
+ };
260
+ }
261
+ function parseAndNormalize(options) {
262
+ return parseAndNormalizeQueryObject(options);
263
+ }
264
+ // Annotate the CommonJS export names for ESM import in node:
265
+ 0 && (module.exports = {
266
+ COL_DIRECTION_SEPARATOR,
267
+ COL_OPERATOR_SEPARATOR,
268
+ DEFAULT_CURSOR,
269
+ DEFAULT_CURSOR_KEY,
270
+ DEFAULT_FILTER_MODE,
271
+ DEFAULT_FILTER_MODE_KEY,
272
+ DEFAULT_LIMIT,
273
+ DEFAULT_LIMIT_KEY,
274
+ DEFAULT_ORDERS_KEY,
275
+ DEFAULT_PAGE,
276
+ DEFAULT_PAGE_KEY,
277
+ DEFAULT_PAGINATION_MODE,
278
+ DEFAULT_PAGINATION_MODE_KEY,
279
+ DEFAULT_SEARCH,
280
+ DEFAULT_SEARCH_KEY,
281
+ FILTER_OPERATORS,
282
+ isFilterMode,
283
+ isFilterOperator,
284
+ isOrderDirection,
285
+ isPaginationMode,
286
+ mergeDefaultAndCustomQueryKeys,
287
+ mergeDefaultQueryValues,
288
+ normalizeParsedQueryObject,
289
+ parseAndNormalize,
290
+ parseAndNormalizeQueryObject,
291
+ parseQueryObject,
292
+ toPositiveInt
293
+ });
@@ -0,0 +1,162 @@
1
+ declare const COL_DIRECTION_SEPARATOR = ":";
2
+ declare const COL_OPERATOR_SEPARATOR = "__";
3
+ declare const DEFAULT_FILTER_MODE_KEY = "filterMode";
4
+ declare const DEFAULT_SEARCH_KEY = "search";
5
+ declare const DEFAULT_PAGINATION_MODE_KEY = "paginationMode";
6
+ declare const DEFAULT_PAGE_KEY = "page";
7
+ declare const DEFAULT_LIMIT_KEY = "limit";
8
+ declare const DEFAULT_CURSOR_KEY = "cursor";
9
+ declare const DEFAULT_ORDERS_KEY = "orders";
10
+ declare const DEFAULT_PAGINATION_MODE: PaginationMode;
11
+ declare const DEFAULT_PAGE = 1;
12
+ declare const DEFAULT_LIMIT = 10;
13
+ declare const DEFAULT_CURSOR = "";
14
+ declare const DEFAULT_FILTER_MODE: FilterMode;
15
+ declare const DEFAULT_SEARCH = "";
16
+ declare const FILTER_OPERATORS: readonly ["eq", "gt", "gte", "lt", "lte", "between", "iLike", "isNull", "inArray"];
17
+
18
+ type QueryKeysOptions = {
19
+ filterMode?: string;
20
+ search?: string;
21
+ paginationMode?: string;
22
+ page?: string;
23
+ limit?: string;
24
+ cursor?: string;
25
+ orders?: string;
26
+ };
27
+ type DefaultQueryValuesOptions = {
28
+ filterMode?: FilterMode;
29
+ search?: string;
30
+ paginationMode?: PaginationMode;
31
+ page?: number;
32
+ limit?: number;
33
+ cursor?: string;
34
+ orders?: OrderObject[];
35
+ filters?: FilterObject[];
36
+ };
37
+ type ParsedQueryObject = {
38
+ pagination: {
39
+ mode?: string;
40
+ page?: string;
41
+ limit?: string;
42
+ cursor?: string;
43
+ };
44
+ sorting: {
45
+ orders?: string;
46
+ };
47
+ filtering: {
48
+ mode?: string;
49
+ search?: string;
50
+ filters: Record<string, string>;
51
+ };
52
+ };
53
+ type PaginationMode = "offset" | "cursor";
54
+ type OffsetPaginationObject = {
55
+ mode: "offset";
56
+ page: number;
57
+ limit: number;
58
+ };
59
+ type CursorPaginationObject = {
60
+ mode: "cursor";
61
+ cursor: string;
62
+ limit: number;
63
+ };
64
+ type OrderDirection = "asc" | "desc";
65
+ type OrderObject = {
66
+ column: string;
67
+ direction: OrderDirection;
68
+ };
69
+ type FilterMode = "search" | "filter";
70
+ type FilterOperator = (typeof FILTER_OPERATORS)[number];
71
+ type FilterObject = {
72
+ column: string;
73
+ operator: FilterOperator;
74
+ value: string;
75
+ };
76
+ type NormalizedQueryObject = {
77
+ pagination: OffsetPaginationObject | CursorPaginationObject;
78
+ sorting: {
79
+ orders: OrderObject[];
80
+ };
81
+ filtering: {
82
+ mode: FilterMode;
83
+ search: string;
84
+ filters: FilterObject[];
85
+ };
86
+ };
87
+ type FieldSchemaColumn = any | unknown;
88
+ type FieldSchemaObjectType = "string" | "number" | "boolean" | "date";
89
+ type FieldSchemaObject = {
90
+ column: FieldSchemaColumn;
91
+ type: FieldSchemaObjectType;
92
+ sortable?: boolean;
93
+ searchable?: boolean;
94
+ filterable?: boolean;
95
+ };
96
+ type FieldSchema = Record<string, FieldSchemaObject>;
97
+ type QueryPlanObject = {
98
+ where?: any;
99
+ orderBy?: any;
100
+ limit: number;
101
+ offset?: number;
102
+ };
103
+
104
+ declare function mergeDefaultAndCustomQueryKeys(customQueryKeys: QueryKeysOptions | undefined): {
105
+ filterMode: string;
106
+ search: string;
107
+ paginationMode: string;
108
+ page: string;
109
+ limit: string;
110
+ cursor: string;
111
+ orders: string;
112
+ };
113
+ declare function mergeDefaultQueryValues(defaultQueryValues?: DefaultQueryValuesOptions): {
114
+ pagination: {
115
+ mode: PaginationMode;
116
+ page: number;
117
+ limit: number;
118
+ cursor: string;
119
+ };
120
+ sorting: {
121
+ orders: OrderObject[];
122
+ };
123
+ filtering: {
124
+ mode: FilterMode;
125
+ search: string;
126
+ filters: FilterObject[];
127
+ };
128
+ };
129
+
130
+ declare function isPaginationMode(v: unknown): v is PaginationMode;
131
+ declare function isOrderDirection(v: unknown): v is OrderDirection;
132
+ declare function isFilterMode(v: unknown): v is FilterMode;
133
+ declare function toPositiveInt(value: string | undefined, fallback: number): number;
134
+ declare function isFilterOperator(v: unknown): v is FilterOperator;
135
+
136
+ interface ParseQueryObjectParams {
137
+ query: Record<string, string>;
138
+ queryKeys?: QueryKeysOptions | undefined;
139
+ }
140
+ declare function parseQueryObject({ query, queryKeys, }: ParseQueryObjectParams): ParsedQueryObject;
141
+
142
+ interface NormalizeParsedQueryObjectParams {
143
+ parsedQuery: ParsedQueryObject;
144
+ defaultQueryValues?: DefaultQueryValuesOptions | undefined;
145
+ }
146
+ declare function normalizeParsedQueryObject({ parsedQuery, defaultQueryValues, }: NormalizeParsedQueryObjectParams): NormalizedQueryObject;
147
+
148
+ interface ParseAndNormalizeQueryObjectOptions {
149
+ query: Record<string, string>;
150
+ queryKeys?: QueryKeysOptions | undefined;
151
+ defaultQueryValues?: DefaultQueryValuesOptions | undefined;
152
+ }
153
+ declare function parseAndNormalizeQueryObject(options: ParseAndNormalizeQueryObjectOptions): {
154
+ parsed: ParsedQueryObject;
155
+ normalized: NormalizedQueryObject;
156
+ };
157
+ declare function parseAndNormalize(options: ParseAndNormalizeQueryObjectOptions): {
158
+ parsed: ParsedQueryObject;
159
+ normalized: NormalizedQueryObject;
160
+ };
161
+
162
+ export { COL_DIRECTION_SEPARATOR, COL_OPERATOR_SEPARATOR, type CursorPaginationObject, DEFAULT_CURSOR, DEFAULT_CURSOR_KEY, DEFAULT_FILTER_MODE, DEFAULT_FILTER_MODE_KEY, DEFAULT_LIMIT, DEFAULT_LIMIT_KEY, DEFAULT_ORDERS_KEY, DEFAULT_PAGE, DEFAULT_PAGE_KEY, DEFAULT_PAGINATION_MODE, DEFAULT_PAGINATION_MODE_KEY, DEFAULT_SEARCH, DEFAULT_SEARCH_KEY, type DefaultQueryValuesOptions, FILTER_OPERATORS, type FieldSchema, type FieldSchemaColumn, type FieldSchemaObject, type FieldSchemaObjectType, type FilterMode, type FilterObject, type FilterOperator, type NormalizedQueryObject, type OffsetPaginationObject, type OrderDirection, type OrderObject, type PaginationMode, type ParsedQueryObject, type QueryKeysOptions, type QueryPlanObject, isFilterMode, isFilterOperator, isOrderDirection, isPaginationMode, mergeDefaultAndCustomQueryKeys, mergeDefaultQueryValues, normalizeParsedQueryObject, parseAndNormalize, parseAndNormalizeQueryObject, parseQueryObject, toPositiveInt };
@@ -0,0 +1,162 @@
1
+ declare const COL_DIRECTION_SEPARATOR = ":";
2
+ declare const COL_OPERATOR_SEPARATOR = "__";
3
+ declare const DEFAULT_FILTER_MODE_KEY = "filterMode";
4
+ declare const DEFAULT_SEARCH_KEY = "search";
5
+ declare const DEFAULT_PAGINATION_MODE_KEY = "paginationMode";
6
+ declare const DEFAULT_PAGE_KEY = "page";
7
+ declare const DEFAULT_LIMIT_KEY = "limit";
8
+ declare const DEFAULT_CURSOR_KEY = "cursor";
9
+ declare const DEFAULT_ORDERS_KEY = "orders";
10
+ declare const DEFAULT_PAGINATION_MODE: PaginationMode;
11
+ declare const DEFAULT_PAGE = 1;
12
+ declare const DEFAULT_LIMIT = 10;
13
+ declare const DEFAULT_CURSOR = "";
14
+ declare const DEFAULT_FILTER_MODE: FilterMode;
15
+ declare const DEFAULT_SEARCH = "";
16
+ declare const FILTER_OPERATORS: readonly ["eq", "gt", "gte", "lt", "lte", "between", "iLike", "isNull", "inArray"];
17
+
18
+ type QueryKeysOptions = {
19
+ filterMode?: string;
20
+ search?: string;
21
+ paginationMode?: string;
22
+ page?: string;
23
+ limit?: string;
24
+ cursor?: string;
25
+ orders?: string;
26
+ };
27
+ type DefaultQueryValuesOptions = {
28
+ filterMode?: FilterMode;
29
+ search?: string;
30
+ paginationMode?: PaginationMode;
31
+ page?: number;
32
+ limit?: number;
33
+ cursor?: string;
34
+ orders?: OrderObject[];
35
+ filters?: FilterObject[];
36
+ };
37
+ type ParsedQueryObject = {
38
+ pagination: {
39
+ mode?: string;
40
+ page?: string;
41
+ limit?: string;
42
+ cursor?: string;
43
+ };
44
+ sorting: {
45
+ orders?: string;
46
+ };
47
+ filtering: {
48
+ mode?: string;
49
+ search?: string;
50
+ filters: Record<string, string>;
51
+ };
52
+ };
53
+ type PaginationMode = "offset" | "cursor";
54
+ type OffsetPaginationObject = {
55
+ mode: "offset";
56
+ page: number;
57
+ limit: number;
58
+ };
59
+ type CursorPaginationObject = {
60
+ mode: "cursor";
61
+ cursor: string;
62
+ limit: number;
63
+ };
64
+ type OrderDirection = "asc" | "desc";
65
+ type OrderObject = {
66
+ column: string;
67
+ direction: OrderDirection;
68
+ };
69
+ type FilterMode = "search" | "filter";
70
+ type FilterOperator = (typeof FILTER_OPERATORS)[number];
71
+ type FilterObject = {
72
+ column: string;
73
+ operator: FilterOperator;
74
+ value: string;
75
+ };
76
+ type NormalizedQueryObject = {
77
+ pagination: OffsetPaginationObject | CursorPaginationObject;
78
+ sorting: {
79
+ orders: OrderObject[];
80
+ };
81
+ filtering: {
82
+ mode: FilterMode;
83
+ search: string;
84
+ filters: FilterObject[];
85
+ };
86
+ };
87
+ type FieldSchemaColumn = any | unknown;
88
+ type FieldSchemaObjectType = "string" | "number" | "boolean" | "date";
89
+ type FieldSchemaObject = {
90
+ column: FieldSchemaColumn;
91
+ type: FieldSchemaObjectType;
92
+ sortable?: boolean;
93
+ searchable?: boolean;
94
+ filterable?: boolean;
95
+ };
96
+ type FieldSchema = Record<string, FieldSchemaObject>;
97
+ type QueryPlanObject = {
98
+ where?: any;
99
+ orderBy?: any;
100
+ limit: number;
101
+ offset?: number;
102
+ };
103
+
104
+ declare function mergeDefaultAndCustomQueryKeys(customQueryKeys: QueryKeysOptions | undefined): {
105
+ filterMode: string;
106
+ search: string;
107
+ paginationMode: string;
108
+ page: string;
109
+ limit: string;
110
+ cursor: string;
111
+ orders: string;
112
+ };
113
+ declare function mergeDefaultQueryValues(defaultQueryValues?: DefaultQueryValuesOptions): {
114
+ pagination: {
115
+ mode: PaginationMode;
116
+ page: number;
117
+ limit: number;
118
+ cursor: string;
119
+ };
120
+ sorting: {
121
+ orders: OrderObject[];
122
+ };
123
+ filtering: {
124
+ mode: FilterMode;
125
+ search: string;
126
+ filters: FilterObject[];
127
+ };
128
+ };
129
+
130
+ declare function isPaginationMode(v: unknown): v is PaginationMode;
131
+ declare function isOrderDirection(v: unknown): v is OrderDirection;
132
+ declare function isFilterMode(v: unknown): v is FilterMode;
133
+ declare function toPositiveInt(value: string | undefined, fallback: number): number;
134
+ declare function isFilterOperator(v: unknown): v is FilterOperator;
135
+
136
+ interface ParseQueryObjectParams {
137
+ query: Record<string, string>;
138
+ queryKeys?: QueryKeysOptions | undefined;
139
+ }
140
+ declare function parseQueryObject({ query, queryKeys, }: ParseQueryObjectParams): ParsedQueryObject;
141
+
142
+ interface NormalizeParsedQueryObjectParams {
143
+ parsedQuery: ParsedQueryObject;
144
+ defaultQueryValues?: DefaultQueryValuesOptions | undefined;
145
+ }
146
+ declare function normalizeParsedQueryObject({ parsedQuery, defaultQueryValues, }: NormalizeParsedQueryObjectParams): NormalizedQueryObject;
147
+
148
+ interface ParseAndNormalizeQueryObjectOptions {
149
+ query: Record<string, string>;
150
+ queryKeys?: QueryKeysOptions | undefined;
151
+ defaultQueryValues?: DefaultQueryValuesOptions | undefined;
152
+ }
153
+ declare function parseAndNormalizeQueryObject(options: ParseAndNormalizeQueryObjectOptions): {
154
+ parsed: ParsedQueryObject;
155
+ normalized: NormalizedQueryObject;
156
+ };
157
+ declare function parseAndNormalize(options: ParseAndNormalizeQueryObjectOptions): {
158
+ parsed: ParsedQueryObject;
159
+ normalized: NormalizedQueryObject;
160
+ };
161
+
162
+ export { COL_DIRECTION_SEPARATOR, COL_OPERATOR_SEPARATOR, type CursorPaginationObject, DEFAULT_CURSOR, DEFAULT_CURSOR_KEY, DEFAULT_FILTER_MODE, DEFAULT_FILTER_MODE_KEY, DEFAULT_LIMIT, DEFAULT_LIMIT_KEY, DEFAULT_ORDERS_KEY, DEFAULT_PAGE, DEFAULT_PAGE_KEY, DEFAULT_PAGINATION_MODE, DEFAULT_PAGINATION_MODE_KEY, DEFAULT_SEARCH, DEFAULT_SEARCH_KEY, type DefaultQueryValuesOptions, FILTER_OPERATORS, type FieldSchema, type FieldSchemaColumn, type FieldSchemaObject, type FieldSchemaObjectType, type FilterMode, type FilterObject, type FilterOperator, type NormalizedQueryObject, type OffsetPaginationObject, type OrderDirection, type OrderObject, type PaginationMode, type ParsedQueryObject, type QueryKeysOptions, type QueryPlanObject, isFilterMode, isFilterOperator, isOrderDirection, isPaginationMode, mergeDefaultAndCustomQueryKeys, mergeDefaultQueryValues, normalizeParsedQueryObject, parseAndNormalize, parseAndNormalizeQueryObject, parseQueryObject, toPositiveInt };
package/dist/index.js ADDED
@@ -0,0 +1,240 @@
1
+ // src/consts.ts
2
+ var COL_DIRECTION_SEPARATOR = ":";
3
+ var COL_OPERATOR_SEPARATOR = "__";
4
+ var DEFAULT_FILTER_MODE_KEY = "filterMode";
5
+ var DEFAULT_SEARCH_KEY = "search";
6
+ var DEFAULT_PAGINATION_MODE_KEY = "paginationMode";
7
+ var DEFAULT_PAGE_KEY = "page";
8
+ var DEFAULT_LIMIT_KEY = "limit";
9
+ var DEFAULT_CURSOR_KEY = "cursor";
10
+ var DEFAULT_ORDERS_KEY = "orders";
11
+ var DEFAULT_PAGINATION_MODE = "offset";
12
+ var DEFAULT_PAGE = 1;
13
+ var DEFAULT_LIMIT = 10;
14
+ var DEFAULT_CURSOR = "";
15
+ var DEFAULT_FILTER_MODE = "search";
16
+ var DEFAULT_SEARCH = "";
17
+ var FILTER_OPERATORS = [
18
+ "eq",
19
+ "gt",
20
+ "gte",
21
+ "lt",
22
+ "lte",
23
+ "between",
24
+ "iLike",
25
+ "isNull",
26
+ "inArray"
27
+ ];
28
+
29
+ // src/utils.ts
30
+ function mergeDefaultAndCustomQueryKeys(customQueryKeys) {
31
+ const DEFAULT_QUERY_KEYS = {
32
+ filterMode: DEFAULT_FILTER_MODE_KEY,
33
+ search: DEFAULT_SEARCH_KEY,
34
+ paginationMode: DEFAULT_PAGINATION_MODE_KEY,
35
+ page: DEFAULT_PAGE_KEY,
36
+ limit: DEFAULT_LIMIT_KEY,
37
+ cursor: DEFAULT_CURSOR_KEY,
38
+ orders: DEFAULT_ORDERS_KEY
39
+ };
40
+ return {
41
+ filterMode: customQueryKeys?.filterMode ?? DEFAULT_QUERY_KEYS.filterMode,
42
+ search: customQueryKeys?.search ?? DEFAULT_QUERY_KEYS.search,
43
+ paginationMode: customQueryKeys?.paginationMode ?? DEFAULT_QUERY_KEYS.paginationMode,
44
+ page: customQueryKeys?.page ?? DEFAULT_QUERY_KEYS.page,
45
+ limit: customQueryKeys?.limit ?? DEFAULT_QUERY_KEYS.limit,
46
+ cursor: customQueryKeys?.cursor ?? DEFAULT_QUERY_KEYS.cursor,
47
+ orders: customQueryKeys?.orders ?? DEFAULT_QUERY_KEYS.orders
48
+ };
49
+ }
50
+ function mergeDefaultQueryValues(defaultQueryValues) {
51
+ if (defaultQueryValues === void 0) {
52
+ return {
53
+ pagination: {
54
+ mode: DEFAULT_PAGINATION_MODE,
55
+ page: DEFAULT_PAGE,
56
+ limit: DEFAULT_LIMIT,
57
+ cursor: DEFAULT_CURSOR
58
+ },
59
+ sorting: {
60
+ orders: []
61
+ },
62
+ filtering: {
63
+ mode: DEFAULT_FILTER_MODE,
64
+ search: DEFAULT_SEARCH,
65
+ filters: []
66
+ }
67
+ };
68
+ }
69
+ return {
70
+ pagination: {
71
+ mode: defaultQueryValues.paginationMode ?? DEFAULT_PAGINATION_MODE,
72
+ page: defaultQueryValues.page ?? DEFAULT_PAGE,
73
+ limit: defaultQueryValues.limit ?? DEFAULT_LIMIT,
74
+ cursor: defaultQueryValues.cursor ?? DEFAULT_CURSOR
75
+ },
76
+ sorting: {
77
+ orders: defaultQueryValues.orders ?? []
78
+ },
79
+ filtering: {
80
+ mode: defaultQueryValues.filterMode ?? DEFAULT_FILTER_MODE,
81
+ search: defaultQueryValues.search ?? DEFAULT_SEARCH,
82
+ filters: defaultQueryValues.filters ?? []
83
+ }
84
+ };
85
+ }
86
+
87
+ // src/helpers.ts
88
+ function isPaginationMode(v) {
89
+ return v === "offset" || v === "cursor";
90
+ }
91
+ function isOrderDirection(v) {
92
+ return v === "asc" || v === "desc";
93
+ }
94
+ function isFilterMode(v) {
95
+ return v === "search" || v === "filter";
96
+ }
97
+ function toPositiveInt(value, fallback) {
98
+ const n = Number(value);
99
+ return Number.isFinite(n) && n > 0 ? n : fallback;
100
+ }
101
+ function isFilterOperator(v) {
102
+ return FILTER_OPERATORS.includes(v);
103
+ }
104
+
105
+ // src/parse-query-object.ts
106
+ function parseQueryObject({
107
+ query,
108
+ queryKeys
109
+ }) {
110
+ const keys = mergeDefaultAndCustomQueryKeys(queryKeys);
111
+ const reserved = new Set(Object.values(keys));
112
+ const filters = {};
113
+ for (const [key, value] of Object.entries(query)) {
114
+ if (!reserved.has(key)) {
115
+ filters[key] = value;
116
+ }
117
+ }
118
+ return {
119
+ pagination: {
120
+ mode: query[keys.paginationMode],
121
+ page: query[keys.page],
122
+ limit: query[keys.limit],
123
+ cursor: query[keys.cursor]
124
+ },
125
+ sorting: {
126
+ orders: query[keys.orders]
127
+ },
128
+ filtering: {
129
+ mode: query[keys.filterMode],
130
+ search: query[keys.search],
131
+ filters
132
+ }
133
+ };
134
+ }
135
+
136
+ // src/normalize-parsed-query-object.ts
137
+ function normalizeParsedQueryObject({
138
+ parsedQuery,
139
+ defaultQueryValues
140
+ }) {
141
+ const defaultValues = mergeDefaultQueryValues(defaultQueryValues);
142
+ const paginationMode = isPaginationMode(parsedQuery.pagination.mode) ? parsedQuery.pagination.mode : defaultValues.pagination.mode;
143
+ const page = toPositiveInt(
144
+ parsedQuery.pagination.page,
145
+ defaultValues.pagination.page
146
+ );
147
+ const limit = toPositiveInt(
148
+ parsedQuery.pagination.limit,
149
+ defaultValues.pagination.limit
150
+ );
151
+ const cursor = parsedQuery.pagination.cursor ?? defaultValues.pagination.cursor;
152
+ const pagination = paginationMode === "offset" ? {
153
+ mode: "offset",
154
+ page,
155
+ limit
156
+ } : {
157
+ mode: "cursor",
158
+ cursor,
159
+ limit
160
+ };
161
+ const explodedOrders = parsedQuery.sorting.orders?.split(",") || [];
162
+ const orders = explodedOrders.map((order) => {
163
+ const [column, direction] = order.split(COL_DIRECTION_SEPARATOR).map((s) => s.trim());
164
+ if (!column) return null;
165
+ return {
166
+ column,
167
+ direction: isOrderDirection(direction) ? direction : "asc"
168
+ };
169
+ }).filter((item) => item !== null);
170
+ const filters = Object.entries(parsedQuery.filtering.filters).map(([colOperator, value]) => {
171
+ const [col, operator] = colOperator.split(COL_OPERATOR_SEPARATOR);
172
+ if (!col || !isFilterOperator(operator)) return null;
173
+ const column = col.trim();
174
+ const valueTrimmed = value.trim();
175
+ return {
176
+ column,
177
+ operator,
178
+ value: valueTrimmed
179
+ };
180
+ }).filter((item) => item !== null);
181
+ return {
182
+ pagination,
183
+ sorting: {
184
+ orders
185
+ },
186
+ filtering: {
187
+ mode: isFilterMode(parsedQuery.filtering.mode) ? parsedQuery.filtering.mode : defaultValues.filtering.mode,
188
+ search: parsedQuery.filtering.search ?? defaultValues.filtering.search,
189
+ filters
190
+ }
191
+ };
192
+ }
193
+
194
+ // src/parse-and-normalize-query-object.ts
195
+ function parseAndNormalizeQueryObject(options) {
196
+ const parsed = parseQueryObject({
197
+ query: options.query,
198
+ queryKeys: options.queryKeys
199
+ });
200
+ const normalized = normalizeParsedQueryObject({
201
+ parsedQuery: parsed,
202
+ defaultQueryValues: options.defaultQueryValues
203
+ });
204
+ return {
205
+ parsed,
206
+ normalized
207
+ };
208
+ }
209
+ function parseAndNormalize(options) {
210
+ return parseAndNormalizeQueryObject(options);
211
+ }
212
+ export {
213
+ COL_DIRECTION_SEPARATOR,
214
+ COL_OPERATOR_SEPARATOR,
215
+ DEFAULT_CURSOR,
216
+ DEFAULT_CURSOR_KEY,
217
+ DEFAULT_FILTER_MODE,
218
+ DEFAULT_FILTER_MODE_KEY,
219
+ DEFAULT_LIMIT,
220
+ DEFAULT_LIMIT_KEY,
221
+ DEFAULT_ORDERS_KEY,
222
+ DEFAULT_PAGE,
223
+ DEFAULT_PAGE_KEY,
224
+ DEFAULT_PAGINATION_MODE,
225
+ DEFAULT_PAGINATION_MODE_KEY,
226
+ DEFAULT_SEARCH,
227
+ DEFAULT_SEARCH_KEY,
228
+ FILTER_OPERATORS,
229
+ isFilterMode,
230
+ isFilterOperator,
231
+ isOrderDirection,
232
+ isPaginationMode,
233
+ mergeDefaultAndCustomQueryKeys,
234
+ mergeDefaultQueryValues,
235
+ normalizeParsedQueryObject,
236
+ parseAndNormalize,
237
+ parseAndNormalizeQueryObject,
238
+ parseQueryObject,
239
+ toPositiveInt
240
+ };
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "@mikevar/data-grid",
3
+ "version": "0.0.1",
4
+ "private": false,
5
+ "publishConfig": {
6
+ "access": "public"
7
+ },
8
+ "type": "module",
9
+ "main": "dist/index.cjs",
10
+ "types": "dist/index.d.ts",
11
+ "exports": {
12
+ ".": {
13
+ "require": "./dist/index.cjs",
14
+ "import": "./dist/index.js"
15
+ }
16
+ },
17
+ "files": [
18
+ "dist"
19
+ ],
20
+ "devDependencies": {
21
+ "tsup": "^8.5.0",
22
+ "vitest": "^3.2.4"
23
+ },
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "git+https://github.com/mikevar/ts-mikevar-library.git"
27
+ },
28
+ "scripts": {
29
+ "test": "vitest src",
30
+ "build": "tsup src/index.ts --format esm,cjs --dts --clean",
31
+ "dev": "tsup src/index.ts --format esm,cjs --dts --watch"
32
+ }
33
+ }