@m5kdev/frontend 0.20.51 → 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. package/dist/src/index.d.mts +25 -0
  2. package/dist/src/index.d.ts +25 -0
  3. package/dist/src/index.js +83 -0
  4. package/dist/src/index.mjs +25 -0
  5. package/dist/src/modules/auth/auth.client.d.mts +708 -0
  6. package/dist/src/modules/auth/auth.client.d.mts.map +1 -0
  7. package/dist/src/modules/auth/auth.client.d.ts +708 -0
  8. package/dist/src/modules/auth/auth.client.d.ts.map +1 -0
  9. package/dist/src/modules/auth/auth.client.js +72 -0
  10. package/dist/src/modules/auth/auth.client.js.map +1 -0
  11. package/dist/src/modules/auth/auth.client.mjs +71 -0
  12. package/dist/src/modules/auth/auth.client.mjs.map +1 -0
  13. package/dist/src/modules/auth/auth.context.d.mts +15 -0
  14. package/dist/src/modules/auth/auth.context.d.mts.map +1 -0
  15. package/dist/src/modules/auth/auth.context.d.ts +15 -0
  16. package/dist/src/modules/auth/auth.context.d.ts.map +1 -0
  17. package/dist/src/modules/auth/auth.context.js +13 -0
  18. package/dist/src/modules/auth/auth.context.js.map +1 -0
  19. package/dist/src/modules/auth/auth.context.mjs +13 -0
  20. package/dist/src/modules/auth/auth.context.mjs.map +1 -0
  21. package/dist/src/modules/auth/auth.lib.d.mts +1251 -1380
  22. package/dist/src/modules/auth/auth.lib.d.mts.map +1 -1
  23. package/dist/src/modules/auth/auth.lib.d.ts +1251 -1380
  24. package/dist/src/modules/auth/auth.lib.d.ts.map +1 -1
  25. package/dist/src/modules/auth/auth.lib.js +18 -63
  26. package/dist/src/modules/auth/auth.lib.js.map +1 -1
  27. package/dist/src/modules/auth/auth.lib.mjs +10 -64
  28. package/dist/src/modules/auth/auth.lib.mjs.map +1 -1
  29. package/dist/src/modules/auth/components/AuthProvider.d.mts +9 -10
  30. package/dist/src/modules/auth/components/AuthProvider.d.mts.map +1 -1
  31. package/dist/src/modules/auth/components/AuthProvider.d.ts +9 -10
  32. package/dist/src/modules/auth/components/AuthProvider.d.ts.map +1 -1
  33. package/dist/src/modules/auth/components/AuthProvider.js +20 -42
  34. package/dist/src/modules/auth/components/AuthProvider.js.map +1 -1
  35. package/dist/src/modules/auth/components/AuthProvider.mjs +22 -43
  36. package/dist/src/modules/auth/components/AuthProvider.mjs.map +1 -1
  37. package/dist/src/modules/auth/hooks/useAuth.d.mts.map +1 -1
  38. package/dist/src/modules/auth/hooks/useAuth.d.ts.map +1 -1
  39. package/dist/src/modules/auth/hooks/useAuth.js +5 -3
  40. package/dist/src/modules/auth/hooks/useAuth.js.map +1 -1
  41. package/dist/src/modules/auth/hooks/useAuth.mjs +3 -1
  42. package/dist/src/modules/auth/hooks/useAuth.mjs.map +1 -1
  43. package/dist/src/modules/auth/hooks/useAuthAdmin.d.mts +10 -19
  44. package/dist/src/modules/auth/hooks/useAuthAdmin.d.mts.map +1 -1
  45. package/dist/src/modules/auth/hooks/useAuthAdmin.d.ts +10 -19
  46. package/dist/src/modules/auth/hooks/useAuthAdmin.d.ts.map +1 -1
  47. package/dist/src/modules/auth/hooks/useAuthAdmin.js +20 -12
  48. package/dist/src/modules/auth/hooks/useAuthAdmin.js.map +1 -1
  49. package/dist/src/modules/auth/hooks/useAuthAdmin.mjs +14 -6
  50. package/dist/src/modules/auth/hooks/useAuthAdmin.mjs.map +1 -1
  51. package/dist/src/modules/auth/hooks/useAuthClient.d.mts +707 -0
  52. package/dist/src/modules/auth/hooks/useAuthClient.d.mts.map +1 -0
  53. package/dist/src/modules/auth/hooks/useAuthClient.d.ts +707 -0
  54. package/dist/src/modules/auth/hooks/useAuthClient.d.ts.map +1 -0
  55. package/dist/src/modules/auth/hooks/useAuthClient.js +12 -0
  56. package/dist/src/modules/auth/hooks/useAuthClient.js.map +1 -0
  57. package/dist/src/modules/auth/hooks/useAuthClient.mjs +11 -0
  58. package/dist/src/modules/auth/hooks/useAuthClient.mjs.map +1 -0
  59. package/dist/src/modules/auth/hooks/useMemberInvite.js +3 -2
  60. package/dist/src/modules/auth/hooks/useMemberInvite.js.map +1 -1
  61. package/dist/src/modules/auth/hooks/useMemberInvite.mjs +2 -1
  62. package/dist/src/modules/auth/hooks/useMemberInvite.mjs.map +1 -1
  63. package/dist/src/modules/auth/hooks/useOrganizationAccess.d.mts +1 -1
  64. package/dist/src/modules/auth/hooks/useOrganizationAccess.d.ts +1 -1
  65. package/dist/src/modules/auth/hooks/useSession.d.mts +4 -37
  66. package/dist/src/modules/auth/hooks/useSession.d.mts.map +1 -1
  67. package/dist/src/modules/auth/hooks/useSession.d.ts +4 -37
  68. package/dist/src/modules/auth/hooks/useSession.d.ts.map +1 -1
  69. package/dist/src/modules/auth/hooks/useSession.js +3 -2
  70. package/dist/src/modules/auth/hooks/useSession.js.map +1 -1
  71. package/dist/src/modules/auth/hooks/useSession.mjs +3 -2
  72. package/dist/src/modules/auth/hooks/useSession.mjs.map +1 -1
  73. package/dist/src/modules/billing/components/BillingProvider.d.mts +1 -1
  74. package/dist/src/modules/billing/components/BillingProvider.d.mts.map +1 -1
  75. package/dist/src/modules/billing/components/BillingProvider.d.ts +1 -1
  76. package/dist/src/modules/billing/components/BillingProvider.d.ts.map +1 -1
  77. package/dist/src/modules/file/hooks/useS3Upload.d.mts +15 -2
  78. package/dist/src/modules/file/hooks/useS3Upload.d.mts.map +1 -1
  79. package/dist/src/modules/file/hooks/useS3Upload.d.ts +15 -2
  80. package/dist/src/modules/file/hooks/useS3Upload.d.ts.map +1 -1
  81. package/dist/src/modules/file/hooks/useS3Upload.js +29 -4
  82. package/dist/src/modules/file/hooks/useS3Upload.js.map +1 -1
  83. package/dist/src/modules/file/hooks/useS3Upload.mjs +29 -5
  84. package/dist/src/modules/file/hooks/useS3Upload.mjs.map +1 -1
  85. package/dist/src/modules/file/hooks/useUpload.d.mts +6 -4
  86. package/dist/src/modules/file/hooks/useUpload.d.mts.map +1 -1
  87. package/dist/src/modules/file/hooks/useUpload.d.ts +6 -4
  88. package/dist/src/modules/file/hooks/useUpload.d.ts.map +1 -1
  89. package/dist/src/modules/file/hooks/useUpload.js +10 -7
  90. package/dist/src/modules/file/hooks/useUpload.js.map +1 -1
  91. package/dist/src/modules/file/hooks/useUpload.mjs +10 -7
  92. package/dist/src/modules/file/hooks/useUpload.mjs.map +1 -1
  93. package/dist/src/modules/table/hooks/useQueryWithParams.d.mts +2 -2
  94. package/dist/src/modules/table/hooks/useQueryWithParams.d.mts.map +1 -1
  95. package/dist/src/modules/table/hooks/useQueryWithParams.d.ts +2 -2
  96. package/dist/src/modules/table/hooks/useQueryWithParams.d.ts.map +1 -1
  97. package/dist/src/modules/table/hooks/useQueryWithParams.js.map +1 -1
  98. package/dist/src/modules/table/hooks/useQueryWithParams.mjs.map +1 -1
  99. package/dist/src/modules/table/hooks/useTableQueryParams.d.mts +7 -0
  100. package/dist/src/modules/table/hooks/useTableQueryParams.d.mts.map +1 -0
  101. package/dist/src/modules/table/hooks/useTableQueryParams.d.ts +7 -0
  102. package/dist/src/modules/table/hooks/useTableQueryParams.d.ts.map +1 -0
  103. package/dist/src/modules/table/hooks/useTableQueryParams.js +95 -0
  104. package/dist/src/modules/table/hooks/useTableQueryParams.js.map +1 -0
  105. package/dist/src/modules/table/hooks/useTableQueryParams.mjs +94 -0
  106. package/dist/src/modules/table/hooks/useTableQueryParams.mjs.map +1 -0
  107. package/dist/src/modules/table/queryParams.d.mts +34 -0
  108. package/dist/src/modules/table/queryParams.d.mts.map +1 -0
  109. package/dist/src/modules/table/queryParams.d.ts +34 -0
  110. package/dist/src/modules/table/queryParams.d.ts.map +1 -0
  111. package/dist/src/modules/table/{hooks/useNuqsQueryParams.js → queryParams.js} +14 -130
  112. package/dist/src/modules/table/queryParams.js.map +1 -0
  113. package/dist/src/modules/table/{hooks/useNuqsQueryParams.mjs → queryParams.mjs} +10 -130
  114. package/dist/src/modules/table/queryParams.mjs.map +1 -0
  115. package/dist/src/utils/date.d.mts +1 -1
  116. package/package.json +24 -6
  117. package/dist/src/modules/table/hooks/useDateRangeFilter.d.mts +0 -34
  118. package/dist/src/modules/table/hooks/useDateRangeFilter.d.mts.map +0 -1
  119. package/dist/src/modules/table/hooks/useDateRangeFilter.d.ts +0 -34
  120. package/dist/src/modules/table/hooks/useDateRangeFilter.d.ts.map +0 -1
  121. package/dist/src/modules/table/hooks/useDateRangeFilter.js +0 -30
  122. package/dist/src/modules/table/hooks/useDateRangeFilter.js.map +0 -1
  123. package/dist/src/modules/table/hooks/useDateRangeFilter.mjs +0 -29
  124. package/dist/src/modules/table/hooks/useDateRangeFilter.mjs.map +0 -1
  125. package/dist/src/modules/table/hooks/useNuqsQueryParams.d.mts +0 -34
  126. package/dist/src/modules/table/hooks/useNuqsQueryParams.d.mts.map +0 -1
  127. package/dist/src/modules/table/hooks/useNuqsQueryParams.d.ts +0 -34
  128. package/dist/src/modules/table/hooks/useNuqsQueryParams.d.ts.map +0 -1
  129. package/dist/src/modules/table/hooks/useNuqsQueryParams.js.map +0 -1
  130. package/dist/src/modules/table/hooks/useNuqsQueryParams.mjs.map +0 -1
  131. package/dist/src/modules/table/hooks/useNuqsTable.d.mts +0 -46
  132. package/dist/src/modules/table/hooks/useNuqsTable.d.mts.map +0 -1
  133. package/dist/src/modules/table/hooks/useNuqsTable.d.ts +0 -46
  134. package/dist/src/modules/table/hooks/useNuqsTable.d.ts.map +0 -1
  135. package/dist/src/modules/table/hooks/useNuqsTable.js +0 -58
  136. package/dist/src/modules/table/hooks/useNuqsTable.js.map +0 -1
  137. package/dist/src/modules/table/hooks/useNuqsTable.mjs +0 -58
  138. package/dist/src/modules/table/hooks/useNuqsTable.mjs.map +0 -1
@@ -0,0 +1,34 @@
1
+ import { QueryFilter, QueryFilters } from "@m5kdev/commons/modules/schemas/query.schema";
2
+ import { GroupingState, PaginationState, SortingState, Updater } from "@tanstack/react-table";
3
+
4
+ //#region src/modules/table/queryParams.d.ts
5
+ declare function serializeFiltersParam(rows: string[][]): string;
6
+ declare function parseFiltersParam(value: string): string[][] | null;
7
+ /** Builds URL tuple; omits optional tails when unused (endColumnId requires valueTo slot - may be ""). */
8
+ declare function encodeFilterToTuple(filter: QueryFilter): string[];
9
+ declare function decodeTupleToFilter(parts: readonly string[]): QueryFilter | null;
10
+ declare function decodeFilterTuples(rows: readonly string[][]): QueryFilters;
11
+ type Order = "asc" | "desc";
12
+ type Granularity = "daily" | "weekly" | "monthly" | "yearly";
13
+ interface QueryParamsState {
14
+ /** Global search string; absent when not set. */
15
+ q: string | null;
16
+ setQ: (value: string | null) => void;
17
+ filters?: QueryFilters;
18
+ setFilters?: (filters: QueryFilters) => void;
19
+ granularity?: Granularity;
20
+ setGranularity?: (value: Granularity) => void;
21
+ sort?: string;
22
+ order?: Order | null;
23
+ setSorting?: (updater: Updater<SortingState>) => void;
24
+ sorting?: SortingState;
25
+ page?: number;
26
+ limit?: number;
27
+ setPagination?: (updater: Updater<PaginationState>) => void;
28
+ pagination?: PaginationState;
29
+ grouping: GroupingState;
30
+ setGrouping: (updater: Updater<GroupingState>) => void;
31
+ }
32
+ //#endregion
33
+ export { Granularity, Order, QueryParamsState, decodeFilterTuples, decodeTupleToFilter, encodeFilterToTuple, parseFiltersParam, serializeFiltersParam };
34
+ //# sourceMappingURL=queryParams.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queryParams.d.ts","names":[],"sources":["../../../../src/modules/table/queryParams.ts"],"mappings":";;;;iBAyDgB,qBAAA,CAAsB,IAAA;AAAA,iBAOtB,iBAAA,CAAkB,KAAA;AAPlC;AAAA,iBAoGgB,mBAAA,CAAoB,MAAA,EAAQ,WAAA;AAAA,iBAmB5B,mBAAA,CAAoB,KAAA,sBAA2B,WAAA;AAAA,iBAmC/C,kBAAA,CAAmB,IAAA,wBAA4B,YAAA;AAAA,KAQnD,KAAA;AAAA,KAEA,WAAA;AAAA,UAEK,gBAAA;;EAEf,CAAA;EACA,IAAA,GAAO,KAAA;EACP,OAAA,GAAU,YAAA;EACV,UAAA,IAAc,OAAA,EAAS,YAAA;EACvB,WAAA,GAAc,WAAA;EACd,cAAA,IAAkB,KAAA,EAAO,WAAA;EACzB,IAAA;EACA,KAAA,GAAQ,KAAA;EACR,UAAA,IAAc,OAAA,EAAS,OAAA,CAAQ,YAAA;EAC/B,OAAA,GAAU,YAAA;EACV,IAAA;EACA,KAAA;EACA,aAAA,IAAiB,OAAA,EAAS,OAAA,CAAQ,eAAA;EAClC,UAAA,GAAa,eAAA;EACb,QAAA,EAAU,aAAA;EACV,WAAA,GAAc,OAAA,EAAS,OAAA,CAAQ,aAAA;AAAA"}
@@ -1,10 +1,8 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- let react = require("react");
3
2
  let _m5kdev_commons_modules_schemas_query_schema = require("@m5kdev/commons/modules/schemas/query.schema");
4
- let nuqs = require("nuqs");
5
3
  let zod = require("zod");
6
- //#region src/modules/table/hooks/useNuqsQueryParams.ts
7
- /** Each row: [columnId, type, method, value, valueTo?, endColumnId?] validated after parse */
4
+ //#region src/modules/table/queryParams.ts
5
+ /** Each row: [columnId, type, method, value, valueTo?, endColumnId?] - validated after parse */
8
6
  const filtersRawSchema = zod.z.array(zod.z.array(zod.z.string()).min(4).max(6));
9
7
  /** Escape `\`, `|`, `;` so we can split filters without JSON quotes/brackets. */
10
8
  function escapeFilterField(raw) {
@@ -67,12 +65,6 @@ function parseFiltersParam(value) {
67
65
  const parsed = filtersRawSchema.safeParse(rows);
68
66
  return parsed.success ? parsed.data : null;
69
67
  }
70
- const parseAsFilterTuples = (0, nuqs.createParser)({
71
- parse: (value) => parseFiltersParam(value),
72
- serialize: (rows) => serializeFiltersParam(rows),
73
- eq: (a, b) => JSON.stringify(a) === JSON.stringify(b)
74
- }).withDefault([]);
75
- const parseAsGrouping = (0, nuqs.parseAsArrayOf)(nuqs.parseAsString).withDefault([]);
76
68
  const NULLISH_METHODS = new Set([
77
69
  "isEmpty",
78
70
  "isNotEmpty",
@@ -117,7 +109,7 @@ function decodeFilterValue(type, method, valueStr) {
117
109
  default: return valueStr;
118
110
  }
119
111
  }
120
- /** Builds URL tuple; omits optional tails when unused (endColumnId requires valueTo slot may be ""). */
112
+ /** Builds URL tuple; omits optional tails when unused (endColumnId requires valueTo slot - may be ""). */
121
113
  function encodeFilterToTuple(filter) {
122
114
  const tuple = [
123
115
  filter.columnId,
@@ -153,124 +145,16 @@ function decodeTupleToFilter(parts) {
153
145
  const parsed = _m5kdev_commons_modules_schemas_query_schema.filterSchema.safeParse(candidate);
154
146
  return parsed.success ? parsed.data : null;
155
147
  }
156
- /**
157
- * Hook to manage all query parameters via nuqs (URL query parameters)
158
- * Manages: `f` (filters as tuple arrays), `q`, `s`/`o`, `p`/`l`, `g`, `r`
159
- * Accepts an optional prefix to namespace params when multiple tables share a view.
160
- */
161
- const useNuqsQueryParams = (prefix) => {
162
- const k = (name) => prefix ? `${prefix}_${name}` : name;
163
- const [sort, setSort] = (0, nuqs.useQueryState)(k("s"), nuqs.parseAsString.withDefault(""));
164
- const [order, setOrder] = (0, nuqs.useQueryState)(k("o"), (0, nuqs.parseAsStringLiteral)(["asc", "desc"]));
165
- const [page, setPage] = (0, nuqs.useQueryState)(k("p"), nuqs.parseAsInteger.withDefault(1));
166
- const [limit, setLimit] = (0, nuqs.useQueryState)(k("l"), nuqs.parseAsInteger.withDefault(10));
167
- const [qRaw, setQRaw] = (0, nuqs.useQueryState)(k("q"), nuqs.parseAsString);
168
- const [filtersRaw, setFiltersRaw] = (0, nuqs.useQueryState)(k("f"), parseAsFilterTuples);
169
- const filters = (0, react.useMemo)(() => {
170
- const decoded = filtersRaw.map((row) => decodeTupleToFilter(row)).filter((f) => f != null);
171
- const parsed = _m5kdev_commons_modules_schemas_query_schema.filtersSchema.safeParse(decoded);
172
- return parsed.success ? parsed.data : [];
173
- }, [filtersRaw]);
174
- const setFilters = (0, react.useCallback)((next) => {
175
- setFiltersRaw(next.length === 0 ? null : next.map(encodeFilterToTuple));
176
- }, [setFiltersRaw]);
177
- const setQ = (0, react.useCallback)((value) => {
178
- setQRaw(value === "" || value == null ? null : value);
179
- }, [setQRaw]);
180
- const [granularity, setGranularity] = (0, nuqs.useQueryState)(k("r"), (0, nuqs.parseAsStringLiteral)([
181
- "daily",
182
- "weekly",
183
- "monthly",
184
- "yearly"
185
- ]).withDefault("daily"));
186
- const [groupingRaw, setGroupingRaw] = (0, nuqs.useQueryState)(k("g"), parseAsGrouping);
187
- const grouping = groupingRaw;
188
- const setGrouping = (0, react.useCallback)((updater) => {
189
- const next = typeof updater === "function" ? updater(groupingRaw) : updater;
190
- setGroupingRaw(next.length > 0 ? next : null);
191
- }, [groupingRaw, setGroupingRaw]);
192
- const sorting = (0, react.useMemo)(() => {
193
- if (!sort) return [];
194
- return [{
195
- id: sort,
196
- desc: (order ?? "asc") === "desc"
197
- }];
198
- }, [sort, order]);
199
- const pagination = (0, react.useMemo)(() => ({
200
- pageIndex: page - 1,
201
- pageSize: limit
202
- }), [page, limit]);
203
- const setSorting = (0, react.useCallback)((updater) => {
204
- const first = (typeof updater === "function" ? updater(sort ? [{
205
- id: sort,
206
- desc: (order ?? "asc") === "desc"
207
- }] : []) : updater)[0];
208
- if (!first || !first.id) {
209
- setSort("");
210
- setOrder(null);
211
- return;
212
- }
213
- setSort(first.id);
214
- setOrder(first.desc ? "desc" : "asc");
215
- }, [
216
- sort,
217
- order,
218
- setSort,
219
- setOrder
220
- ]);
221
- (0, react.useEffect)(() => {
222
- if (sort && !order) setOrder("asc");
223
- }, [
224
- sort,
225
- order,
226
- setOrder
227
- ]);
228
- const setPagination = (0, react.useCallback)((updater) => {
229
- const currentState = {
230
- pageIndex: page - 1,
231
- pageSize: limit
232
- };
233
- const next = typeof updater === "function" ? updater(currentState) : updater;
234
- setPage((next.pageIndex ?? 0) + 1);
235
- setLimit(next.pageSize ?? 10);
236
- }, [page, limit]);
237
- return (0, react.useMemo)(() => ({
238
- q: qRaw,
239
- setQ,
240
- filters,
241
- setFilters,
242
- granularity,
243
- setGranularity,
244
- sort,
245
- order,
246
- setSorting,
247
- sorting,
248
- page,
249
- limit,
250
- setPagination,
251
- pagination,
252
- grouping,
253
- setGrouping
254
- }), [
255
- qRaw,
256
- setQ,
257
- filters,
258
- setFilters,
259
- granularity,
260
- setGranularity,
261
- sort,
262
- order,
263
- setSorting,
264
- sorting,
265
- page,
266
- limit,
267
- setPagination,
268
- pagination,
269
- grouping,
270
- setGrouping
271
- ]);
272
- };
148
+ function decodeFilterTuples(rows) {
149
+ const decoded = rows.map((row) => decodeTupleToFilter(row)).filter((filter) => filter != null);
150
+ const parsed = _m5kdev_commons_modules_schemas_query_schema.filtersSchema.safeParse(decoded);
151
+ return parsed.success ? parsed.data : [];
152
+ }
273
153
  //#endregion
274
- exports.useNuqsQueryParams = useNuqsQueryParams;
154
+ exports.decodeFilterTuples = decodeFilterTuples;
155
+ exports.decodeTupleToFilter = decodeTupleToFilter;
156
+ exports.encodeFilterToTuple = encodeFilterToTuple;
157
+ exports.parseFiltersParam = parseFiltersParam;
158
+ exports.serializeFiltersParam = serializeFiltersParam;
275
159
 
276
- //# sourceMappingURL=useNuqsQueryParams.js.map
160
+ //# sourceMappingURL=queryParams.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queryParams.js","names":["z","filterSchema","filtersSchema"],"sources":["../../../../src/modules/table/queryParams.ts"],"sourcesContent":["import type { QueryFilter, QueryFilters } from \"@m5kdev/commons/modules/schemas/query.schema\";\r\nimport { filterSchema, filtersSchema } from \"@m5kdev/commons/modules/schemas/query.schema\";\r\nimport type { GroupingState, PaginationState, SortingState, Updater } from \"@tanstack/react-table\";\r\nimport { z } from \"zod\";\r\n\r\n/** Each row: [columnId, type, method, value, valueTo?, endColumnId?] - validated after parse */\r\nconst filtersRawSchema = z.array(z.array(z.string()).min(4).max(6));\r\n\r\n/** Escape `\\`, `|`, `;` so we can split filters without JSON quotes/brackets. */\r\nfunction escapeFilterField(raw: string): string {\r\n return raw.replace(/\\\\/g, \"\\\\\\\\\").replace(/\\|/g, \"\\\\|\").replace(/;/g, \"\\\\;\");\r\n}\r\n\r\nfunction unescapeFilterField(encoded: string): string {\r\n let out = \"\";\r\n for (let i = 0; i < encoded.length; i++) {\r\n const c = encoded[i];\r\n if (c === \"\\\\\" && i + 1 < encoded.length) {\r\n const next = encoded[i + 1];\r\n if (next === \"\\\\\" || next === \"|\" || next === \";\") {\r\n out += next;\r\n i++;\r\n continue;\r\n }\r\n }\r\n out += c;\r\n }\r\n return out;\r\n}\r\n\r\n/**\r\n * Split on `delimiter` only when not escaped as `\\` + delimiter.\r\n */\r\nfunction splitByEscapedDelimiter(s: string, delimiter: string): string[] {\r\n if (delimiter.length !== 1) {\r\n throw new Error(\"splitByEscapedDelimiter expects a single-character delimiter\");\r\n }\r\n const parts: string[] = [];\r\n let buf = \"\";\r\n for (let i = 0; i < s.length; i++) {\r\n const c = s[i];\r\n if (c === \"\\\\\" && i + 1 < s.length) {\r\n buf += c + s[i + 1];\r\n i++;\r\n continue;\r\n }\r\n if (c === delimiter) {\r\n parts.push(unescapeFilterField(buf));\r\n buf = \"\";\r\n continue;\r\n }\r\n buf += c;\r\n }\r\n parts.push(unescapeFilterField(buf));\r\n return parts;\r\n}\r\n\r\nexport function serializeFiltersParam(rows: string[][]): string {\r\n if (rows.length === 0) {\r\n return \"\";\r\n }\r\n return rows.map((row) => row.map(escapeFilterField).join(\"|\")).join(\";\");\r\n}\r\n\r\nexport function parseFiltersParam(value: string): string[][] | null {\r\n const trimmed = value.trim();\r\n if (trimmed === \"\") {\r\n return [];\r\n }\r\n const rowStrings = splitByEscapedDelimiter(trimmed, \";\");\r\n const rows: string[][] = [];\r\n for (const row of rowStrings) {\r\n if (row === \"\") {\r\n continue;\r\n }\r\n const fields = splitByEscapedDelimiter(row, \"|\");\r\n if (fields.length >= 4 && fields.length <= 6) {\r\n rows.push(fields);\r\n }\r\n }\r\n const parsed = filtersRawSchema.safeParse(rows);\r\n return parsed.success ? parsed.data : null;\r\n}\r\n\r\nconst NULLISH_METHODS: ReadonlySet<QueryFilter[\"method\"]> = new Set([\r\n \"isEmpty\",\r\n \"isNotEmpty\",\r\n \"is_null\",\r\n \"is_not_null\",\r\n]);\r\n\r\nfunction encodeFilterValue(filter: QueryFilter): string {\r\n if (NULLISH_METHODS.has(filter.method)) {\r\n return typeof filter.value === \"string\" ? filter.value : \"\";\r\n }\r\n const { type, method, value } = filter;\r\n switch (type) {\r\n case \"number\":\r\n return String(value as number);\r\n case \"boolean\":\r\n return (value as boolean) ? \"true\" : \"false\";\r\n case \"enum\":\r\n case \"jsonArray\":\r\n if (method === \"oneOf\" && Array.isArray(value)) {\r\n return JSON.stringify(value);\r\n }\r\n if (Array.isArray(value)) {\r\n return JSON.stringify(value);\r\n }\r\n return String(value);\r\n default:\r\n return String(value);\r\n }\r\n}\r\n\r\nfunction decodeFilterValue(\r\n type: QueryFilter[\"type\"],\r\n method: QueryFilter[\"method\"],\r\n valueStr: string\r\n): QueryFilter[\"value\"] {\r\n if (NULLISH_METHODS.has(method)) {\r\n return valueStr;\r\n }\r\n switch (type) {\r\n case \"number\": {\r\n const n = Number.parseFloat(valueStr);\r\n return Number.isNaN(n) ? 0 : n;\r\n }\r\n case \"boolean\":\r\n return valueStr === \"true\";\r\n case \"enum\":\r\n case \"jsonArray\":\r\n if (method === \"oneOf\") {\r\n try {\r\n const parsed = JSON.parse(valueStr) as unknown;\r\n return Array.isArray(parsed) ? parsed.map(String) : [];\r\n } catch {\r\n return [];\r\n }\r\n }\r\n if (valueStr.startsWith(\"[\")) {\r\n try {\r\n const parsed = JSON.parse(valueStr) as unknown;\r\n if (Array.isArray(parsed)) {\r\n return parsed.map(String);\r\n }\r\n } catch {\r\n /* use raw string */\r\n }\r\n }\r\n return valueStr;\r\n default:\r\n return valueStr;\r\n }\r\n}\r\n\r\n/** Builds URL tuple; omits optional tails when unused (endColumnId requires valueTo slot - may be \"\"). */\r\nexport function encodeFilterToTuple(filter: QueryFilter): string[] {\r\n const tuple: string[] = [filter.columnId, filter.type, filter.method, encodeFilterValue(filter)];\r\n const hasValueTo = filter.valueTo != null && filter.valueTo !== \"\";\r\n const hasEndColumnId = filter.endColumnId != null && filter.endColumnId !== \"\";\r\n\r\n if (hasValueTo && filter.valueTo != null) {\r\n tuple.push(filter.valueTo);\r\n }\r\n\r\n if (hasEndColumnId && filter.endColumnId != null) {\r\n if (!hasValueTo) {\r\n tuple.push(\"\");\r\n }\r\n tuple.push(filter.endColumnId);\r\n }\r\n\r\n return tuple;\r\n}\r\n\r\nexport function decodeTupleToFilter(parts: readonly string[]): QueryFilter | null {\r\n if (parts.length < 4 || parts.length > 6) {\r\n return null;\r\n }\r\n\r\n const [columnId, typeStr, methodStr, valueStr, valueToStr, endColumnIdStr] = parts;\r\n\r\n const typeParsed = filterSchema.shape.type.safeParse(typeStr);\r\n const methodParsed = filterSchema.shape.method.safeParse(methodStr);\r\n if (!typeParsed.success || !methodParsed.success) {\r\n return null;\r\n }\r\n\r\n const type = typeParsed.data;\r\n const method = methodParsed.data;\r\n const value = decodeFilterValue(type, method, valueStr);\r\n\r\n const candidate: QueryFilter = {\r\n columnId,\r\n type,\r\n method,\r\n value,\r\n };\r\n\r\n if (valueToStr !== undefined) {\r\n candidate.valueTo = valueToStr;\r\n }\r\n if (endColumnIdStr !== undefined) {\r\n candidate.endColumnId = endColumnIdStr;\r\n }\r\n\r\n const parsed = filterSchema.safeParse(candidate);\r\n return parsed.success ? parsed.data : null;\r\n}\r\n\r\nexport function decodeFilterTuples(rows: readonly string[][]): QueryFilters {\r\n const decoded = rows\r\n .map((row) => decodeTupleToFilter(row))\r\n .filter((filter): filter is QueryFilter => filter != null);\r\n const parsed = filtersSchema.safeParse(decoded);\r\n return parsed.success ? parsed.data : [];\r\n}\r\n\r\nexport type Order = \"asc\" | \"desc\";\r\n\r\nexport type Granularity = \"daily\" | \"weekly\" | \"monthly\" | \"yearly\";\r\n\r\nexport interface QueryParamsState {\r\n /** Global search string; absent when not set. */\r\n q: string | null;\r\n setQ: (value: string | null) => void;\r\n filters?: QueryFilters;\r\n setFilters?: (filters: QueryFilters) => void;\r\n granularity?: Granularity;\r\n setGranularity?: (value: Granularity) => void;\r\n sort?: string;\r\n order?: Order | null;\r\n setSorting?: (updater: Updater<SortingState>) => void;\r\n sorting?: SortingState;\r\n page?: number;\r\n limit?: number;\r\n setPagination?: (updater: Updater<PaginationState>) => void;\r\n pagination?: PaginationState;\r\n grouping: GroupingState;\r\n setGrouping: (updater: Updater<GroupingState>) => void;\r\n}\r\n"],"mappings":"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"}
@@ -1,9 +1,7 @@
1
- import { useCallback, useEffect, useMemo } from "react";
2
1
  import { filterSchema, filtersSchema } from "@m5kdev/commons/modules/schemas/query.schema";
3
- import { createParser, parseAsArrayOf, parseAsInteger, parseAsString, parseAsStringLiteral, useQueryState } from "nuqs";
4
2
  import { z } from "zod";
5
- //#region src/modules/table/hooks/useNuqsQueryParams.ts
6
- /** Each row: [columnId, type, method, value, valueTo?, endColumnId?] validated after parse */
3
+ //#region src/modules/table/queryParams.ts
4
+ /** Each row: [columnId, type, method, value, valueTo?, endColumnId?] - validated after parse */
7
5
  const filtersRawSchema = z.array(z.array(z.string()).min(4).max(6));
8
6
  /** Escape `\`, `|`, `;` so we can split filters without JSON quotes/brackets. */
9
7
  function escapeFilterField(raw) {
@@ -66,12 +64,6 @@ function parseFiltersParam(value) {
66
64
  const parsed = filtersRawSchema.safeParse(rows);
67
65
  return parsed.success ? parsed.data : null;
68
66
  }
69
- const parseAsFilterTuples = createParser({
70
- parse: (value) => parseFiltersParam(value),
71
- serialize: (rows) => serializeFiltersParam(rows),
72
- eq: (a, b) => JSON.stringify(a) === JSON.stringify(b)
73
- }).withDefault([]);
74
- const parseAsGrouping = parseAsArrayOf(parseAsString).withDefault([]);
75
67
  const NULLISH_METHODS = new Set([
76
68
  "isEmpty",
77
69
  "isNotEmpty",
@@ -116,7 +108,7 @@ function decodeFilterValue(type, method, valueStr) {
116
108
  default: return valueStr;
117
109
  }
118
110
  }
119
- /** Builds URL tuple; omits optional tails when unused (endColumnId requires valueTo slot may be ""). */
111
+ /** Builds URL tuple; omits optional tails when unused (endColumnId requires valueTo slot - may be ""). */
120
112
  function encodeFilterToTuple(filter) {
121
113
  const tuple = [
122
114
  filter.columnId,
@@ -152,124 +144,12 @@ function decodeTupleToFilter(parts) {
152
144
  const parsed = filterSchema.safeParse(candidate);
153
145
  return parsed.success ? parsed.data : null;
154
146
  }
155
- /**
156
- * Hook to manage all query parameters via nuqs (URL query parameters)
157
- * Manages: `f` (filters as tuple arrays), `q`, `s`/`o`, `p`/`l`, `g`, `r`
158
- * Accepts an optional prefix to namespace params when multiple tables share a view.
159
- */
160
- const useNuqsQueryParams = (prefix) => {
161
- const k = (name) => prefix ? `${prefix}_${name}` : name;
162
- const [sort, setSort] = useQueryState(k("s"), parseAsString.withDefault(""));
163
- const [order, setOrder] = useQueryState(k("o"), parseAsStringLiteral(["asc", "desc"]));
164
- const [page, setPage] = useQueryState(k("p"), parseAsInteger.withDefault(1));
165
- const [limit, setLimit] = useQueryState(k("l"), parseAsInteger.withDefault(10));
166
- const [qRaw, setQRaw] = useQueryState(k("q"), parseAsString);
167
- const [filtersRaw, setFiltersRaw] = useQueryState(k("f"), parseAsFilterTuples);
168
- const filters = useMemo(() => {
169
- const decoded = filtersRaw.map((row) => decodeTupleToFilter(row)).filter((f) => f != null);
170
- const parsed = filtersSchema.safeParse(decoded);
171
- return parsed.success ? parsed.data : [];
172
- }, [filtersRaw]);
173
- const setFilters = useCallback((next) => {
174
- setFiltersRaw(next.length === 0 ? null : next.map(encodeFilterToTuple));
175
- }, [setFiltersRaw]);
176
- const setQ = useCallback((value) => {
177
- setQRaw(value === "" || value == null ? null : value);
178
- }, [setQRaw]);
179
- const [granularity, setGranularity] = useQueryState(k("r"), parseAsStringLiteral([
180
- "daily",
181
- "weekly",
182
- "monthly",
183
- "yearly"
184
- ]).withDefault("daily"));
185
- const [groupingRaw, setGroupingRaw] = useQueryState(k("g"), parseAsGrouping);
186
- const grouping = groupingRaw;
187
- const setGrouping = useCallback((updater) => {
188
- const next = typeof updater === "function" ? updater(groupingRaw) : updater;
189
- setGroupingRaw(next.length > 0 ? next : null);
190
- }, [groupingRaw, setGroupingRaw]);
191
- const sorting = useMemo(() => {
192
- if (!sort) return [];
193
- return [{
194
- id: sort,
195
- desc: (order ?? "asc") === "desc"
196
- }];
197
- }, [sort, order]);
198
- const pagination = useMemo(() => ({
199
- pageIndex: page - 1,
200
- pageSize: limit
201
- }), [page, limit]);
202
- const setSorting = useCallback((updater) => {
203
- const first = (typeof updater === "function" ? updater(sort ? [{
204
- id: sort,
205
- desc: (order ?? "asc") === "desc"
206
- }] : []) : updater)[0];
207
- if (!first || !first.id) {
208
- setSort("");
209
- setOrder(null);
210
- return;
211
- }
212
- setSort(first.id);
213
- setOrder(first.desc ? "desc" : "asc");
214
- }, [
215
- sort,
216
- order,
217
- setSort,
218
- setOrder
219
- ]);
220
- useEffect(() => {
221
- if (sort && !order) setOrder("asc");
222
- }, [
223
- sort,
224
- order,
225
- setOrder
226
- ]);
227
- const setPagination = useCallback((updater) => {
228
- const currentState = {
229
- pageIndex: page - 1,
230
- pageSize: limit
231
- };
232
- const next = typeof updater === "function" ? updater(currentState) : updater;
233
- setPage((next.pageIndex ?? 0) + 1);
234
- setLimit(next.pageSize ?? 10);
235
- }, [page, limit]);
236
- return useMemo(() => ({
237
- q: qRaw,
238
- setQ,
239
- filters,
240
- setFilters,
241
- granularity,
242
- setGranularity,
243
- sort,
244
- order,
245
- setSorting,
246
- sorting,
247
- page,
248
- limit,
249
- setPagination,
250
- pagination,
251
- grouping,
252
- setGrouping
253
- }), [
254
- qRaw,
255
- setQ,
256
- filters,
257
- setFilters,
258
- granularity,
259
- setGranularity,
260
- sort,
261
- order,
262
- setSorting,
263
- sorting,
264
- page,
265
- limit,
266
- setPagination,
267
- pagination,
268
- grouping,
269
- setGrouping
270
- ]);
271
- };
147
+ function decodeFilterTuples(rows) {
148
+ const decoded = rows.map((row) => decodeTupleToFilter(row)).filter((filter) => filter != null);
149
+ const parsed = filtersSchema.safeParse(decoded);
150
+ return parsed.success ? parsed.data : [];
151
+ }
272
152
  //#endregion
273
- export { useNuqsQueryParams };
153
+ export { decodeFilterTuples, decodeTupleToFilter, encodeFilterToTuple, parseFiltersParam, serializeFiltersParam };
274
154
 
275
- //# sourceMappingURL=useNuqsQueryParams.mjs.map
155
+ //# sourceMappingURL=queryParams.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queryParams.mjs","names":[],"sources":["../../../../src/modules/table/queryParams.ts"],"sourcesContent":["import type { QueryFilter, QueryFilters } from \"@m5kdev/commons/modules/schemas/query.schema\";\r\nimport { filterSchema, filtersSchema } from \"@m5kdev/commons/modules/schemas/query.schema\";\r\nimport type { GroupingState, PaginationState, SortingState, Updater } from \"@tanstack/react-table\";\r\nimport { z } from \"zod\";\r\n\r\n/** Each row: [columnId, type, method, value, valueTo?, endColumnId?] - validated after parse */\r\nconst filtersRawSchema = z.array(z.array(z.string()).min(4).max(6));\r\n\r\n/** Escape `\\`, `|`, `;` so we can split filters without JSON quotes/brackets. */\r\nfunction escapeFilterField(raw: string): string {\r\n return raw.replace(/\\\\/g, \"\\\\\\\\\").replace(/\\|/g, \"\\\\|\").replace(/;/g, \"\\\\;\");\r\n}\r\n\r\nfunction unescapeFilterField(encoded: string): string {\r\n let out = \"\";\r\n for (let i = 0; i < encoded.length; i++) {\r\n const c = encoded[i];\r\n if (c === \"\\\\\" && i + 1 < encoded.length) {\r\n const next = encoded[i + 1];\r\n if (next === \"\\\\\" || next === \"|\" || next === \";\") {\r\n out += next;\r\n i++;\r\n continue;\r\n }\r\n }\r\n out += c;\r\n }\r\n return out;\r\n}\r\n\r\n/**\r\n * Split on `delimiter` only when not escaped as `\\` + delimiter.\r\n */\r\nfunction splitByEscapedDelimiter(s: string, delimiter: string): string[] {\r\n if (delimiter.length !== 1) {\r\n throw new Error(\"splitByEscapedDelimiter expects a single-character delimiter\");\r\n }\r\n const parts: string[] = [];\r\n let buf = \"\";\r\n for (let i = 0; i < s.length; i++) {\r\n const c = s[i];\r\n if (c === \"\\\\\" && i + 1 < s.length) {\r\n buf += c + s[i + 1];\r\n i++;\r\n continue;\r\n }\r\n if (c === delimiter) {\r\n parts.push(unescapeFilterField(buf));\r\n buf = \"\";\r\n continue;\r\n }\r\n buf += c;\r\n }\r\n parts.push(unescapeFilterField(buf));\r\n return parts;\r\n}\r\n\r\nexport function serializeFiltersParam(rows: string[][]): string {\r\n if (rows.length === 0) {\r\n return \"\";\r\n }\r\n return rows.map((row) => row.map(escapeFilterField).join(\"|\")).join(\";\");\r\n}\r\n\r\nexport function parseFiltersParam(value: string): string[][] | null {\r\n const trimmed = value.trim();\r\n if (trimmed === \"\") {\r\n return [];\r\n }\r\n const rowStrings = splitByEscapedDelimiter(trimmed, \";\");\r\n const rows: string[][] = [];\r\n for (const row of rowStrings) {\r\n if (row === \"\") {\r\n continue;\r\n }\r\n const fields = splitByEscapedDelimiter(row, \"|\");\r\n if (fields.length >= 4 && fields.length <= 6) {\r\n rows.push(fields);\r\n }\r\n }\r\n const parsed = filtersRawSchema.safeParse(rows);\r\n return parsed.success ? parsed.data : null;\r\n}\r\n\r\nconst NULLISH_METHODS: ReadonlySet<QueryFilter[\"method\"]> = new Set([\r\n \"isEmpty\",\r\n \"isNotEmpty\",\r\n \"is_null\",\r\n \"is_not_null\",\r\n]);\r\n\r\nfunction encodeFilterValue(filter: QueryFilter): string {\r\n if (NULLISH_METHODS.has(filter.method)) {\r\n return typeof filter.value === \"string\" ? filter.value : \"\";\r\n }\r\n const { type, method, value } = filter;\r\n switch (type) {\r\n case \"number\":\r\n return String(value as number);\r\n case \"boolean\":\r\n return (value as boolean) ? \"true\" : \"false\";\r\n case \"enum\":\r\n case \"jsonArray\":\r\n if (method === \"oneOf\" && Array.isArray(value)) {\r\n return JSON.stringify(value);\r\n }\r\n if (Array.isArray(value)) {\r\n return JSON.stringify(value);\r\n }\r\n return String(value);\r\n default:\r\n return String(value);\r\n }\r\n}\r\n\r\nfunction decodeFilterValue(\r\n type: QueryFilter[\"type\"],\r\n method: QueryFilter[\"method\"],\r\n valueStr: string\r\n): QueryFilter[\"value\"] {\r\n if (NULLISH_METHODS.has(method)) {\r\n return valueStr;\r\n }\r\n switch (type) {\r\n case \"number\": {\r\n const n = Number.parseFloat(valueStr);\r\n return Number.isNaN(n) ? 0 : n;\r\n }\r\n case \"boolean\":\r\n return valueStr === \"true\";\r\n case \"enum\":\r\n case \"jsonArray\":\r\n if (method === \"oneOf\") {\r\n try {\r\n const parsed = JSON.parse(valueStr) as unknown;\r\n return Array.isArray(parsed) ? parsed.map(String) : [];\r\n } catch {\r\n return [];\r\n }\r\n }\r\n if (valueStr.startsWith(\"[\")) {\r\n try {\r\n const parsed = JSON.parse(valueStr) as unknown;\r\n if (Array.isArray(parsed)) {\r\n return parsed.map(String);\r\n }\r\n } catch {\r\n /* use raw string */\r\n }\r\n }\r\n return valueStr;\r\n default:\r\n return valueStr;\r\n }\r\n}\r\n\r\n/** Builds URL tuple; omits optional tails when unused (endColumnId requires valueTo slot - may be \"\"). */\r\nexport function encodeFilterToTuple(filter: QueryFilter): string[] {\r\n const tuple: string[] = [filter.columnId, filter.type, filter.method, encodeFilterValue(filter)];\r\n const hasValueTo = filter.valueTo != null && filter.valueTo !== \"\";\r\n const hasEndColumnId = filter.endColumnId != null && filter.endColumnId !== \"\";\r\n\r\n if (hasValueTo && filter.valueTo != null) {\r\n tuple.push(filter.valueTo);\r\n }\r\n\r\n if (hasEndColumnId && filter.endColumnId != null) {\r\n if (!hasValueTo) {\r\n tuple.push(\"\");\r\n }\r\n tuple.push(filter.endColumnId);\r\n }\r\n\r\n return tuple;\r\n}\r\n\r\nexport function decodeTupleToFilter(parts: readonly string[]): QueryFilter | null {\r\n if (parts.length < 4 || parts.length > 6) {\r\n return null;\r\n }\r\n\r\n const [columnId, typeStr, methodStr, valueStr, valueToStr, endColumnIdStr] = parts;\r\n\r\n const typeParsed = filterSchema.shape.type.safeParse(typeStr);\r\n const methodParsed = filterSchema.shape.method.safeParse(methodStr);\r\n if (!typeParsed.success || !methodParsed.success) {\r\n return null;\r\n }\r\n\r\n const type = typeParsed.data;\r\n const method = methodParsed.data;\r\n const value = decodeFilterValue(type, method, valueStr);\r\n\r\n const candidate: QueryFilter = {\r\n columnId,\r\n type,\r\n method,\r\n value,\r\n };\r\n\r\n if (valueToStr !== undefined) {\r\n candidate.valueTo = valueToStr;\r\n }\r\n if (endColumnIdStr !== undefined) {\r\n candidate.endColumnId = endColumnIdStr;\r\n }\r\n\r\n const parsed = filterSchema.safeParse(candidate);\r\n return parsed.success ? parsed.data : null;\r\n}\r\n\r\nexport function decodeFilterTuples(rows: readonly string[][]): QueryFilters {\r\n const decoded = rows\r\n .map((row) => decodeTupleToFilter(row))\r\n .filter((filter): filter is QueryFilter => filter != null);\r\n const parsed = filtersSchema.safeParse(decoded);\r\n return parsed.success ? parsed.data : [];\r\n}\r\n\r\nexport type Order = \"asc\" | \"desc\";\r\n\r\nexport type Granularity = \"daily\" | \"weekly\" | \"monthly\" | \"yearly\";\r\n\r\nexport interface QueryParamsState {\r\n /** Global search string; absent when not set. */\r\n q: string | null;\r\n setQ: (value: string | null) => void;\r\n filters?: QueryFilters;\r\n setFilters?: (filters: QueryFilters) => void;\r\n granularity?: Granularity;\r\n setGranularity?: (value: Granularity) => void;\r\n sort?: string;\r\n order?: Order | null;\r\n setSorting?: (updater: Updater<SortingState>) => void;\r\n sorting?: SortingState;\r\n page?: number;\r\n limit?: number;\r\n setPagination?: (updater: Updater<PaginationState>) => void;\r\n pagination?: PaginationState;\r\n grouping: GroupingState;\r\n setGrouping: (updater: Updater<GroupingState>) => void;\r\n}\r\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import { CalendarDate } from "@internationalized/date";
2
1
  import { QueryFilter } from "@m5kdev/commons/modules/schemas/query.schema";
2
+ import { CalendarDate } from "@internationalized/date";
3
3
  import { DateValue } from "@react-types/calendar";
4
4
  import { RangeValue } from "@react-types/shared";
5
5
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@m5kdev/frontend",
3
- "version": "0.20.51",
3
+ "version": "0.21.0",
4
4
  "license": "GPL-3.0-only",
5
5
  "repository": {
6
6
  "type": "git",
@@ -21,12 +21,10 @@
21
21
  "@trpc/tanstack-react-query": "11.4.3",
22
22
  "better-auth": "1.4.18",
23
23
  "luxon": "3.7.1",
24
- "nuqs": "2.4.3",
25
- "posthog-js": "1.258.2",
26
24
  "react": "19.2.1",
27
25
  "react-dom": "19.2.1",
28
26
  "zod": "4.2.1",
29
- "@m5kdev/commons": "0.20.51"
27
+ "@m5kdev/commons": "0.21.0"
30
28
  },
31
29
  "peerDependencies": {
32
30
  "@trpc/server": "11.4.3"
@@ -41,10 +39,20 @@
41
39
  "tsdown": "0.21.7",
42
40
  "typescript": "6.0.3",
43
41
  "vite": "7.0.4",
44
- "@m5kdev/backend": "0.20.51",
45
- "@m5kdev/config": "0.20.51"
42
+ "@m5kdev/config": "0.21.0",
43
+ "@m5kdev/backend": "0.21.0"
46
44
  },
47
45
  "exports": {
46
+ ".": {
47
+ "import": {
48
+ "types": "./dist/src/index.d.mts",
49
+ "default": "./dist/src/index.mjs"
50
+ },
51
+ "require": {
52
+ "types": "./dist/src/index.d.ts",
53
+ "default": "./dist/src/index.js"
54
+ }
55
+ },
48
56
  "./modules/app/components/*": {
49
57
  "import": {
50
58
  "types": "./dist/src/modules/app/components/*.d.mts",
@@ -154,6 +162,16 @@
154
162
  "types": "./dist/src/utils/*.d.ts",
155
163
  "default": "./dist/src/utils/*.js"
156
164
  }
165
+ },
166
+ "./modules/table/queryParams": {
167
+ "import": {
168
+ "types": "./dist/src/modules/table/queryParams.d.mts",
169
+ "default": "./dist/src/modules/table/queryParams.mjs"
170
+ },
171
+ "require": {
172
+ "types": "./dist/src/modules/table/queryParams.d.ts",
173
+ "default": "./dist/src/modules/table/queryParams.js"
174
+ }
157
175
  }
158
176
  },
159
177
  "scripts": {
@@ -1,34 +0,0 @@
1
- import { NuqsQueryParams } from "./useNuqsQueryParams.mjs";
2
- import { UseQueryOptions, UseQueryResult } from "@tanstack/react-query";
3
-
4
- //#region src/modules/table/hooks/useDateRangeFilter.d.ts
5
- interface DateRangeFilterReturn<TData> {
6
- params: NuqsQueryParams;
7
- query: UseQueryResult<TData>;
8
- }
9
- /**
10
- * Flexible query options type that accepts both standard TanStack Query options
11
- * and tRPC's queryOptions function return type.
12
- * Uses permissive generics to handle type differences between TanStack Query and tRPC.
13
- */
14
- type QueryOptionsLike<TData> = UseQueryOptions<TData, any, TData, any>;
15
- /**
16
- * Function type that accepts both standard query options functions and tRPC's queryOptions.
17
- * tRPC's queryOptions accepts (input, opts?) while standard functions may only accept (input).
18
- */
19
- type GetQueryOptionsFn<TInput, TData> = (input: TInput, ...args: any[]) => QueryOptionsLike<TData>;
20
- interface DateRangeFilterOptions<TInput, TData> {
21
- getQueryOptions: GetQueryOptionsFn<TInput, TData>;
22
- queryParams?: TInput;
23
- }
24
- /**
25
- * Hook for charts with URL-synced query parameters and data fetching
26
- * Similar to useNuqsTable but without rowSelection (not needed for charts)
27
- */
28
- declare const useDateRangeFilter: <TInput, TData>({
29
- getQueryOptions,
30
- queryParams
31
- }: DateRangeFilterOptions<TInput, TData>) => DateRangeFilterReturn<TData>;
32
- //#endregion
33
- export { DateRangeFilterOptions, DateRangeFilterReturn, useDateRangeFilter };
34
- //# sourceMappingURL=useDateRangeFilter.d.mts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useDateRangeFilter.d.mts","names":[],"sources":["../../../../../src/modules/table/hooks/useDateRangeFilter.ts"],"mappings":";;;;UAIiB,qBAAA;EACf,MAAA,EAAQ,eAAA;EACR,KAAA,EAAO,cAAA,CAAe,KAAA;AAAA;;;;;;KASnB,gBAAA,UAA0B,eAAA,CAAgB,KAAA,OAAY,KAAA;;;;;KAOtD,iBAAA,mBAAoC,KAAA,EAAO,MAAA,KAAW,IAAA,YAAgB,gBAAA,CAAiB,KAAA;AAAA,UAE3E,sBAAA;EACf,eAAA,EAAiB,iBAAA,CAAkB,MAAA,EAAQ,KAAA;EAC3C,WAAA,GAAc,MAAA;AAAA;;;;;cAOH,kBAAA;EAAqC,eAAA;EAAA;AAAA,GAG/C,sBAAA,CAAuB,MAAA,EAAQ,KAAA,MAAS,qBAAA,CAAsB,KAAA"}
@@ -1,34 +0,0 @@
1
- import { NuqsQueryParams } from "./useNuqsQueryParams.js";
2
- import { UseQueryOptions, UseQueryResult } from "@tanstack/react-query";
3
-
4
- //#region src/modules/table/hooks/useDateRangeFilter.d.ts
5
- interface DateRangeFilterReturn<TData> {
6
- params: NuqsQueryParams;
7
- query: UseQueryResult<TData>;
8
- }
9
- /**
10
- * Flexible query options type that accepts both standard TanStack Query options
11
- * and tRPC's queryOptions function return type.
12
- * Uses permissive generics to handle type differences between TanStack Query and tRPC.
13
- */
14
- type QueryOptionsLike<TData> = UseQueryOptions<TData, any, TData, any>;
15
- /**
16
- * Function type that accepts both standard query options functions and tRPC's queryOptions.
17
- * tRPC's queryOptions accepts (input, opts?) while standard functions may only accept (input).
18
- */
19
- type GetQueryOptionsFn<TInput, TData> = (input: TInput, ...args: any[]) => QueryOptionsLike<TData>;
20
- interface DateRangeFilterOptions<TInput, TData> {
21
- getQueryOptions: GetQueryOptionsFn<TInput, TData>;
22
- queryParams?: TInput;
23
- }
24
- /**
25
- * Hook for charts with URL-synced query parameters and data fetching
26
- * Similar to useNuqsTable but without rowSelection (not needed for charts)
27
- */
28
- declare const useDateRangeFilter: <TInput, TData>({
29
- getQueryOptions,
30
- queryParams
31
- }: DateRangeFilterOptions<TInput, TData>) => DateRangeFilterReturn<TData>;
32
- //#endregion
33
- export { DateRangeFilterOptions, DateRangeFilterReturn, useDateRangeFilter };
34
- //# sourceMappingURL=useDateRangeFilter.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useDateRangeFilter.d.ts","names":[],"sources":["../../../../../src/modules/table/hooks/useDateRangeFilter.ts"],"mappings":";;;;UAIiB,qBAAA;EACf,MAAA,EAAQ,eAAA;EACR,KAAA,EAAO,cAAA,CAAe,KAAA;AAAA;;;;;;KASnB,gBAAA,UAA0B,eAAA,CAAgB,KAAA,OAAY,KAAA;;;;;KAOtD,iBAAA,mBAAoC,KAAA,EAAO,MAAA,KAAW,IAAA,YAAgB,gBAAA,CAAiB,KAAA;AAAA,UAE3E,sBAAA;EACf,eAAA,EAAiB,iBAAA,CAAkB,MAAA,EAAQ,KAAA;EAC3C,WAAA,GAAc,MAAA;AAAA;;;;;cAOH,kBAAA;EAAqC,eAAA;EAAA;AAAA,GAG/C,sBAAA,CAAuB,MAAA,EAAQ,KAAA,MAAS,qBAAA,CAAsB,KAAA"}
@@ -1,30 +0,0 @@
1
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_src_modules_table_hooks_useNuqsQueryParams = require("./useNuqsQueryParams.js");
3
- const require_src_modules_table_hooks_useQueryWithParams = require("./useQueryWithParams.js");
4
- //#region src/modules/table/hooks/useDateRangeFilter.ts
5
- /**
6
- * Hook for charts with URL-synced query parameters and data fetching
7
- * Similar to useNuqsTable but without rowSelection (not needed for charts)
8
- */
9
- const useDateRangeFilter = ({ getQueryOptions, queryParams = {} }) => {
10
- const nuqs = require_src_modules_table_hooks_useNuqsQueryParams.useNuqsQueryParams();
11
- return {
12
- params: nuqs,
13
- query: require_src_modules_table_hooks_useQueryWithParams.useQueryWithParams({
14
- getQueryOptions,
15
- queryParams,
16
- queryState: {
17
- filters: nuqs.filters,
18
- q: nuqs.q,
19
- sort: nuqs.sort,
20
- order: nuqs.order,
21
- page: nuqs.page,
22
- limit: nuqs.limit
23
- }
24
- })
25
- };
26
- };
27
- //#endregion
28
- exports.useDateRangeFilter = useDateRangeFilter;
29
-
30
- //# sourceMappingURL=useDateRangeFilter.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useDateRangeFilter.js","names":["useNuqsQueryParams","useQueryWithParams"],"sources":["../../../../../src/modules/table/hooks/useDateRangeFilter.ts"],"sourcesContent":["import type { UseQueryOptions, UseQueryResult } from \"@tanstack/react-query\";\r\nimport { type NuqsQueryParams, useNuqsQueryParams } from \"./useNuqsQueryParams\";\r\nimport { useQueryWithParams } from \"./useQueryWithParams\";\r\n\r\nexport interface DateRangeFilterReturn<TData> {\r\n params: NuqsQueryParams;\r\n query: UseQueryResult<TData>;\r\n}\r\n\r\n/**\r\n * Flexible query options type that accepts both standard TanStack Query options\r\n * and tRPC's queryOptions function return type.\r\n * Uses permissive generics to handle type differences between TanStack Query and tRPC.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\r\ntype QueryOptionsLike<TData> = UseQueryOptions<TData, any, TData, any>;\r\n\r\n/**\r\n * Function type that accepts both standard query options functions and tRPC's queryOptions.\r\n * tRPC's queryOptions accepts (input, opts?) while standard functions may only accept (input).\r\n */\r\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\r\ntype GetQueryOptionsFn<TInput, TData> = (input: TInput, ...args: any[]) => QueryOptionsLike<TData>;\r\n\r\nexport interface DateRangeFilterOptions<TInput, TData> {\r\n getQueryOptions: GetQueryOptionsFn<TInput, TData>;\r\n queryParams?: TInput;\r\n}\r\n\r\n/**\r\n * Hook for charts with URL-synced query parameters and data fetching\r\n * Similar to useNuqsTable but without rowSelection (not needed for charts)\r\n */\r\nexport const useDateRangeFilter = <TInput, TData>({\r\n getQueryOptions,\r\n queryParams = {} as TInput,\r\n}: DateRangeFilterOptions<TInput, TData>): DateRangeFilterReturn<TData> => {\r\n const nuqs = useNuqsQueryParams();\r\n\r\n const queryResult = useQueryWithParams({\r\n getQueryOptions,\r\n queryParams,\r\n queryState: {\r\n filters: nuqs.filters,\r\n q: nuqs.q,\r\n sort: nuqs.sort,\r\n order: nuqs.order,\r\n page: nuqs.page,\r\n limit: nuqs.limit,\r\n },\r\n });\r\n\r\n return {\r\n params: nuqs,\r\n query: queryResult,\r\n };\r\n};\r\n"],"mappings":";;;;;;;;AAiCA,MAAa,sBAAqC,EAChD,iBACA,cAAc,EAAE,OACyD;CACzE,MAAM,OAAOA,mDAAAA,oBAAoB;AAejC,QAAO;EACL,QAAQ;EACR,OAfkBC,mDAAAA,mBAAmB;GACrC;GACA;GACA,YAAY;IACV,SAAS,KAAK;IACd,GAAG,KAAK;IACR,MAAM,KAAK;IACX,OAAO,KAAK;IACZ,MAAM,KAAK;IACX,OAAO,KAAK;IACb;GACF,CAAC;EAKD"}
@@ -1,29 +0,0 @@
1
- import { useNuqsQueryParams } from "./useNuqsQueryParams.mjs";
2
- import { useQueryWithParams } from "./useQueryWithParams.mjs";
3
- //#region src/modules/table/hooks/useDateRangeFilter.ts
4
- /**
5
- * Hook for charts with URL-synced query parameters and data fetching
6
- * Similar to useNuqsTable but without rowSelection (not needed for charts)
7
- */
8
- const useDateRangeFilter = ({ getQueryOptions, queryParams = {} }) => {
9
- const nuqs = useNuqsQueryParams();
10
- return {
11
- params: nuqs,
12
- query: useQueryWithParams({
13
- getQueryOptions,
14
- queryParams,
15
- queryState: {
16
- filters: nuqs.filters,
17
- q: nuqs.q,
18
- sort: nuqs.sort,
19
- order: nuqs.order,
20
- page: nuqs.page,
21
- limit: nuqs.limit
22
- }
23
- })
24
- };
25
- };
26
- //#endregion
27
- export { useDateRangeFilter };
28
-
29
- //# sourceMappingURL=useDateRangeFilter.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useDateRangeFilter.mjs","names":[],"sources":["../../../../../src/modules/table/hooks/useDateRangeFilter.ts"],"sourcesContent":["import type { UseQueryOptions, UseQueryResult } from \"@tanstack/react-query\";\r\nimport { type NuqsQueryParams, useNuqsQueryParams } from \"./useNuqsQueryParams\";\r\nimport { useQueryWithParams } from \"./useQueryWithParams\";\r\n\r\nexport interface DateRangeFilterReturn<TData> {\r\n params: NuqsQueryParams;\r\n query: UseQueryResult<TData>;\r\n}\r\n\r\n/**\r\n * Flexible query options type that accepts both standard TanStack Query options\r\n * and tRPC's queryOptions function return type.\r\n * Uses permissive generics to handle type differences between TanStack Query and tRPC.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\r\ntype QueryOptionsLike<TData> = UseQueryOptions<TData, any, TData, any>;\r\n\r\n/**\r\n * Function type that accepts both standard query options functions and tRPC's queryOptions.\r\n * tRPC's queryOptions accepts (input, opts?) while standard functions may only accept (input).\r\n */\r\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\r\ntype GetQueryOptionsFn<TInput, TData> = (input: TInput, ...args: any[]) => QueryOptionsLike<TData>;\r\n\r\nexport interface DateRangeFilterOptions<TInput, TData> {\r\n getQueryOptions: GetQueryOptionsFn<TInput, TData>;\r\n queryParams?: TInput;\r\n}\r\n\r\n/**\r\n * Hook for charts with URL-synced query parameters and data fetching\r\n * Similar to useNuqsTable but without rowSelection (not needed for charts)\r\n */\r\nexport const useDateRangeFilter = <TInput, TData>({\r\n getQueryOptions,\r\n queryParams = {} as TInput,\r\n}: DateRangeFilterOptions<TInput, TData>): DateRangeFilterReturn<TData> => {\r\n const nuqs = useNuqsQueryParams();\r\n\r\n const queryResult = useQueryWithParams({\r\n getQueryOptions,\r\n queryParams,\r\n queryState: {\r\n filters: nuqs.filters,\r\n q: nuqs.q,\r\n sort: nuqs.sort,\r\n order: nuqs.order,\r\n page: nuqs.page,\r\n limit: nuqs.limit,\r\n },\r\n });\r\n\r\n return {\r\n params: nuqs,\r\n query: queryResult,\r\n };\r\n};\r\n"],"mappings":";;;;;;;AAiCA,MAAa,sBAAqC,EAChD,iBACA,cAAc,EAAE,OACyD;CACzE,MAAM,OAAO,oBAAoB;AAejC,QAAO;EACL,QAAQ;EACR,OAfkB,mBAAmB;GACrC;GACA;GACA,YAAY;IACV,SAAS,KAAK;IACd,GAAG,KAAK;IACR,MAAM,KAAK;IACX,OAAO,KAAK;IACZ,MAAM,KAAK;IACX,OAAO,KAAK;IACb;GACF,CAAC;EAKD"}