@m5kdev/frontend 0.21.7 → 0.23.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 (106) hide show
  1. package/dist/_virtual/_rolldown/runtime.js +23 -0
  2. package/dist/src/modules/app/components/AppConfigProvider.d.mts +2 -0
  3. package/dist/src/modules/app/components/AppConfigProvider.d.mts.map +1 -1
  4. package/dist/src/modules/app/components/AppConfigProvider.d.ts +2 -0
  5. package/dist/src/modules/app/components/AppConfigProvider.d.ts.map +1 -1
  6. package/dist/src/modules/app/components/AppConfigProvider.js +1 -0
  7. package/dist/src/modules/app/components/AppConfigProvider.js.map +1 -1
  8. package/dist/src/modules/app/components/AppConfigProvider.mjs.map +1 -1
  9. package/dist/src/modules/app/components/AppTrpcQueryProvider.js +1 -0
  10. package/dist/src/modules/app/components/AppTrpcQueryProvider.js.map +1 -1
  11. package/dist/src/modules/app/hooks/useAppConfig.d.mts +3 -0
  12. package/dist/src/modules/app/hooks/useAppConfig.d.mts.map +1 -1
  13. package/dist/src/modules/app/hooks/useAppConfig.d.ts +3 -0
  14. package/dist/src/modules/app/hooks/useAppConfig.d.ts.map +1 -1
  15. package/dist/src/modules/app/hooks/useAppConfig.js +1 -0
  16. package/dist/src/modules/app/hooks/useAppConfig.js.map +1 -1
  17. package/dist/src/modules/app/utils/locale.d.mts +8 -0
  18. package/dist/src/modules/app/utils/locale.d.mts.map +1 -0
  19. package/dist/src/modules/app/utils/locale.d.ts +8 -0
  20. package/dist/src/modules/app/utils/locale.d.ts.map +1 -0
  21. package/dist/src/modules/app/utils/locale.js +20 -0
  22. package/dist/src/modules/app/utils/locale.js.map +1 -0
  23. package/dist/src/modules/app/utils/locale.mjs +16 -0
  24. package/dist/src/modules/app/utils/locale.mjs.map +1 -0
  25. package/dist/src/modules/auth/auth.client.d.mts +1643 -102
  26. package/dist/src/modules/auth/auth.client.d.mts.map +1 -1
  27. package/dist/src/modules/auth/auth.client.d.ts +1643 -102
  28. package/dist/src/modules/auth/auth.client.d.ts.map +1 -1
  29. package/dist/src/modules/auth/auth.client.js +7 -3
  30. package/dist/src/modules/auth/auth.client.js.map +1 -1
  31. package/dist/src/modules/auth/auth.client.mjs +6 -3
  32. package/dist/src/modules/auth/auth.client.mjs.map +1 -1
  33. package/dist/src/modules/auth/auth.context.js +1 -0
  34. package/dist/src/modules/auth/auth.context.js.map +1 -1
  35. package/dist/src/modules/auth/auth.lib.d.mts +4 -2103
  36. package/dist/src/modules/auth/auth.lib.d.mts.map +1 -1
  37. package/dist/src/modules/auth/auth.lib.d.ts +4 -2103
  38. package/dist/src/modules/auth/auth.lib.d.ts.map +1 -1
  39. package/dist/src/modules/auth/auth.lib.js.map +1 -1
  40. package/dist/src/modules/auth/auth.lib.mjs.map +1 -1
  41. package/dist/src/modules/auth/components/AuthProvider.d.mts +1 -1
  42. package/dist/src/modules/auth/components/AuthProvider.d.mts.map +1 -1
  43. package/dist/src/modules/auth/components/AuthProvider.d.ts +1 -1
  44. package/dist/src/modules/auth/components/AuthProvider.d.ts.map +1 -1
  45. package/dist/src/modules/auth/components/AuthProvider.js +4 -0
  46. package/dist/src/modules/auth/components/AuthProvider.js.map +1 -1
  47. package/dist/src/modules/auth/components/AuthProvider.mjs +3 -0
  48. package/dist/src/modules/auth/components/AuthProvider.mjs.map +1 -1
  49. package/dist/src/modules/auth/hooks/useAuth.js +1 -0
  50. package/dist/src/modules/auth/hooks/useAuth.js.map +1 -1
  51. package/dist/src/modules/auth/hooks/useAuthAdmin.d.mts +10 -1
  52. package/dist/src/modules/auth/hooks/useAuthAdmin.d.mts.map +1 -1
  53. package/dist/src/modules/auth/hooks/useAuthAdmin.d.ts +10 -1
  54. package/dist/src/modules/auth/hooks/useAuthAdmin.d.ts.map +1 -1
  55. package/dist/src/modules/auth/hooks/useAuthAdmin.js +1 -0
  56. package/dist/src/modules/auth/hooks/useAuthAdmin.js.map +1 -1
  57. package/dist/src/modules/auth/hooks/useAuthClient.d.mts +2 -702
  58. package/dist/src/modules/auth/hooks/useAuthClient.d.mts.map +1 -1
  59. package/dist/src/modules/auth/hooks/useAuthClient.d.ts +2 -702
  60. package/dist/src/modules/auth/hooks/useAuthClient.d.ts.map +1 -1
  61. package/dist/src/modules/auth/hooks/useAuthClient.js +1 -0
  62. package/dist/src/modules/auth/hooks/useAuthClient.js.map +1 -1
  63. package/dist/src/modules/auth/hooks/useAuthClient.mjs.map +1 -1
  64. package/dist/src/modules/auth/hooks/useAuthLocale.d.mts +23 -0
  65. package/dist/src/modules/auth/hooks/useAuthLocale.d.mts.map +1 -0
  66. package/dist/src/modules/auth/hooks/useAuthLocale.d.ts +23 -0
  67. package/dist/src/modules/auth/hooks/useAuthLocale.d.ts.map +1 -0
  68. package/dist/src/modules/auth/hooks/useAuthLocale.js +25 -0
  69. package/dist/src/modules/auth/hooks/useAuthLocale.js.map +1 -0
  70. package/dist/src/modules/auth/hooks/useAuthLocale.mjs +23 -0
  71. package/dist/src/modules/auth/hooks/useAuthLocale.mjs.map +1 -0
  72. package/dist/src/modules/auth/hooks/useMemberInvite.js +1 -0
  73. package/dist/src/modules/auth/hooks/useMemberInvite.js.map +1 -1
  74. package/dist/src/modules/auth/hooks/useOrganizationAccess.d.mts +1 -1
  75. package/dist/src/modules/auth/hooks/useOrganizationAccess.d.ts +1 -1
  76. package/dist/src/modules/auth/hooks/useOrganizationAccess.js +1 -0
  77. package/dist/src/modules/auth/hooks/useOrganizationAccess.js.map +1 -1
  78. package/dist/src/modules/auth/hooks/useSession.js +1 -0
  79. package/dist/src/modules/auth/hooks/useSession.js.map +1 -1
  80. package/dist/src/modules/auth/hooks/useUserOrganizations.d.mts +1 -0
  81. package/dist/src/modules/auth/hooks/useUserOrganizations.d.ts +1 -0
  82. package/dist/src/modules/auth/hooks/useUserOrganizations.js +1 -0
  83. package/dist/src/modules/auth/hooks/useUserOrganizations.js.map +1 -1
  84. package/dist/src/modules/billing/components/BillingProvider.d.mts +1 -1
  85. package/dist/src/modules/billing/components/BillingProvider.d.mts.map +1 -1
  86. package/dist/src/modules/billing/components/BillingProvider.d.ts +1 -1
  87. package/dist/src/modules/billing/components/BillingProvider.d.ts.map +1 -1
  88. package/dist/src/modules/billing/components/BillingProvider.js +1 -0
  89. package/dist/src/modules/billing/components/BillingProvider.js.map +1 -1
  90. package/dist/src/modules/billing/hooks/useSubscription.js +1 -0
  91. package/dist/src/modules/billing/hooks/useSubscription.js.map +1 -1
  92. package/dist/src/modules/file/hooks/useS3DownloadUrl.js +1 -0
  93. package/dist/src/modules/file/hooks/useS3DownloadUrl.js.map +1 -1
  94. package/dist/src/modules/file/hooks/useS3Upload.js +1 -0
  95. package/dist/src/modules/file/hooks/useS3Upload.js.map +1 -1
  96. package/dist/src/modules/file/hooks/useUpload.js +1 -0
  97. package/dist/src/modules/file/hooks/useUpload.js.map +1 -1
  98. package/dist/src/modules/table/hooks/useQueryWithParams.js +1 -0
  99. package/dist/src/modules/table/hooks/useQueryWithParams.js.map +1 -1
  100. package/dist/src/modules/table/hooks/useTableQueryParams.js +1 -0
  101. package/dist/src/modules/table/hooks/useTableQueryParams.js.map +1 -1
  102. package/dist/src/modules/table/queryParams.js +1 -0
  103. package/dist/src/modules/table/queryParams.js.map +1 -1
  104. package/dist/src/utils/date.js +1 -0
  105. package/dist/src/utils/date.js.map +1 -1
  106. package/package.json +17 -5
@@ -1 +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
+ {"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,4 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ require("../../_virtual/_rolldown/runtime.js");
2
3
  let _internationalized_date = require("@internationalized/date");
3
4
  let luxon = require("luxon");
4
5
  //#region src/utils/date.ts
@@ -1 +1 @@
1
- {"version":3,"file":"date.js","names":["DateTime","CalendarDate"],"sources":["../../../src/utils/date.ts"],"sourcesContent":["import type { DateValue } from \"@react-types/calendar\";\r\nimport type { RangeValue } from \"@react-types/shared\";\r\nimport { CalendarDate, getLocalTimeZone, parseAbsolute } from \"@internationalized/date\";\r\nimport type { QueryFilter } from \"@m5kdev/commons/modules/schemas/query.schema\";\r\nimport { DateTime } from \"luxon\";\r\n\r\n/**\r\n * Convert CalendarDate to UTC ISO string at midnight UTC\r\n */\r\nexport const calendarDateToUTC = (date: CalendarDate): string => {\r\n return DateTime.utc(date.year, date.month, date.day).toISO() ?? \"\";\r\n};\r\n\r\n/**\r\n * Convert CalendarDate to UTC ISO string at end of day UTC\r\n */\r\nexport const calendarDateToUTCEndOfDay = (date: CalendarDate): string => {\r\n return DateTime.utc(date.year, date.month, date.day).endOf(\"day\").toISO() ?? \"\";\r\n};\r\n\r\n/**\r\n * Convert RangeValue<DateValue> to URL string format \"startISO,endISO\"\r\n */\r\nexport const rangeToUrlString = (range: RangeValue<DateValue> | null): string | null => {\r\n if (!range || !range.start || !range.end) return null;\r\n\r\n const start = range.start as unknown as CalendarDate;\r\n const end = range.end as unknown as CalendarDate;\r\n\r\n if (!start?.year || !end?.year) return null;\r\n\r\n // Format as ISO date strings (YYYY-MM-DD)\r\n const startISO = `${start.year}-${String(start.month).padStart(2, \"0\")}-${String(start.day).padStart(2, \"0\")}`;\r\n const endISO = `${end.year}-${String(end.month).padStart(2, \"0\")}-${String(end.day).padStart(2, \"0\")}`;\r\n\r\n return `${startISO},${endISO}`;\r\n};\r\n\r\n/**\r\n * Convert URL string \"startISO,endISO\" to RangeValue<DateValue>\r\n */\r\nexport const urlStringToRange = (value: string | null): RangeValue<DateValue> | null => {\r\n if (!value) return null;\r\n\r\n const [startISO, endISO] = value.split(\",\");\r\n if (!startISO || !endISO) return null;\r\n\r\n const tz = getLocalTimeZone();\r\n\r\n // Parse ISO date strings using parseAbsolute for proper timezone handling\r\n const startZoned = parseAbsolute(`${startISO}T00:00:00Z`, tz);\r\n const endZoned = parseAbsolute(`${endISO}T00:00:00Z`, tz);\r\n\r\n if (!startZoned || !endZoned) return null;\r\n\r\n const startDate = new CalendarDate(startZoned.year, startZoned.month, startZoned.day);\r\n const endDate = new CalendarDate(endZoned.year, endZoned.month, endZoned.day);\r\n\r\n return {\r\n start: startDate as unknown as DateValue,\r\n end: endDate as unknown as DateValue,\r\n } as RangeValue<DateValue>;\r\n};\r\n\r\n/**\r\n * Convert date range to QueryFilter format\r\n */\r\nexport const dateRangeToFilter = (\r\n dateRange: RangeValue<DateValue> | null,\r\n columnId = \"startedAt\"\r\n): QueryFilter | null => {\r\n if (!dateRange || !dateRange.start || !dateRange.end) return null;\r\n\r\n const start = dateRange.start as unknown as CalendarDate;\r\n const end = dateRange.end as unknown as CalendarDate;\r\n\r\n if (!start?.year || !end?.year) return null;\r\n\r\n const startISO = calendarDateToUTC(start);\r\n const endISO = calendarDateToUTCEndOfDay(end);\r\n\r\n return {\r\n columnId,\r\n type: \"date\",\r\n method: \"between\",\r\n value: startISO,\r\n valueTo: endISO,\r\n };\r\n};\r\n"],"mappings":";;;;;;;AASA,MAAa,qBAAqB,SAA+B;AAC/D,QAAOA,MAAAA,SAAS,IAAI,KAAK,MAAM,KAAK,OAAO,KAAK,IAAI,CAAC,OAAO,IAAI;;;;;AAMlE,MAAa,6BAA6B,SAA+B;AACvE,QAAOA,MAAAA,SAAS,IAAI,KAAK,MAAM,KAAK,OAAO,KAAK,IAAI,CAAC,MAAM,MAAM,CAAC,OAAO,IAAI;;;;;AAM/E,MAAa,oBAAoB,UAAuD;AACtF,KAAI,CAAC,SAAS,CAAC,MAAM,SAAS,CAAC,MAAM,IAAK,QAAO;CAEjD,MAAM,QAAQ,MAAM;CACpB,MAAM,MAAM,MAAM;AAElB,KAAI,CAAC,OAAO,QAAQ,CAAC,KAAK,KAAM,QAAO;AAMvC,QAAO,GAHU,GAAG,MAAM,KAAK,GAAG,OAAO,MAAM,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,OAAO,MAAM,IAAI,CAAC,SAAS,GAAG,IAAI,GAGzF,GAFJ,GAAG,IAAI,KAAK,GAAG,OAAO,IAAI,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,OAAO,IAAI,IAAI,CAAC,SAAS,GAAG,IAAI;;;;;AAQtG,MAAa,oBAAoB,UAAuD;AACtF,KAAI,CAAC,MAAO,QAAO;CAEnB,MAAM,CAAC,UAAU,UAAU,MAAM,MAAM,IAAI;AAC3C,KAAI,CAAC,YAAY,CAAC,OAAQ,QAAO;CAEjC,MAAM,MAAA,GAAA,wBAAA,mBAAuB;CAG7B,MAAM,cAAA,GAAA,wBAAA,eAA2B,GAAG,SAAS,aAAa,GAAG;CAC7D,MAAM,YAAA,GAAA,wBAAA,eAAyB,GAAG,OAAO,aAAa,GAAG;AAEzD,KAAI,CAAC,cAAc,CAAC,SAAU,QAAO;AAKrC,QAAO;EACL,OAJgB,IAAIC,wBAAAA,aAAa,WAAW,MAAM,WAAW,OAAO,WAAW,IAAI;EAKnF,KAJc,IAAIA,wBAAAA,aAAa,SAAS,MAAM,SAAS,OAAO,SAAS,IAAI;EAK5E;;;;;AAMH,MAAa,qBACX,WACA,WAAW,gBACY;AACvB,KAAI,CAAC,aAAa,CAAC,UAAU,SAAS,CAAC,UAAU,IAAK,QAAO;CAE7D,MAAM,QAAQ,UAAU;CACxB,MAAM,MAAM,UAAU;AAEtB,KAAI,CAAC,OAAO,QAAQ,CAAC,KAAK,KAAM,QAAO;AAKvC,QAAO;EACL;EACA,MAAM;EACN,QAAQ;EACR,OAPe,kBAAkB,MAAM;EAQvC,SAPa,0BAA0B,IAAI;EAQ5C"}
1
+ {"version":3,"file":"date.js","names":["DateTime","CalendarDate"],"sources":["../../../src/utils/date.ts"],"sourcesContent":["import type { DateValue } from \"@react-types/calendar\";\r\nimport type { RangeValue } from \"@react-types/shared\";\r\nimport { CalendarDate, getLocalTimeZone, parseAbsolute } from \"@internationalized/date\";\r\nimport type { QueryFilter } from \"@m5kdev/commons/modules/schemas/query.schema\";\r\nimport { DateTime } from \"luxon\";\r\n\r\n/**\r\n * Convert CalendarDate to UTC ISO string at midnight UTC\r\n */\r\nexport const calendarDateToUTC = (date: CalendarDate): string => {\r\n return DateTime.utc(date.year, date.month, date.day).toISO() ?? \"\";\r\n};\r\n\r\n/**\r\n * Convert CalendarDate to UTC ISO string at end of day UTC\r\n */\r\nexport const calendarDateToUTCEndOfDay = (date: CalendarDate): string => {\r\n return DateTime.utc(date.year, date.month, date.day).endOf(\"day\").toISO() ?? \"\";\r\n};\r\n\r\n/**\r\n * Convert RangeValue<DateValue> to URL string format \"startISO,endISO\"\r\n */\r\nexport const rangeToUrlString = (range: RangeValue<DateValue> | null): string | null => {\r\n if (!range || !range.start || !range.end) return null;\r\n\r\n const start = range.start as unknown as CalendarDate;\r\n const end = range.end as unknown as CalendarDate;\r\n\r\n if (!start?.year || !end?.year) return null;\r\n\r\n // Format as ISO date strings (YYYY-MM-DD)\r\n const startISO = `${start.year}-${String(start.month).padStart(2, \"0\")}-${String(start.day).padStart(2, \"0\")}`;\r\n const endISO = `${end.year}-${String(end.month).padStart(2, \"0\")}-${String(end.day).padStart(2, \"0\")}`;\r\n\r\n return `${startISO},${endISO}`;\r\n};\r\n\r\n/**\r\n * Convert URL string \"startISO,endISO\" to RangeValue<DateValue>\r\n */\r\nexport const urlStringToRange = (value: string | null): RangeValue<DateValue> | null => {\r\n if (!value) return null;\r\n\r\n const [startISO, endISO] = value.split(\",\");\r\n if (!startISO || !endISO) return null;\r\n\r\n const tz = getLocalTimeZone();\r\n\r\n // Parse ISO date strings using parseAbsolute for proper timezone handling\r\n const startZoned = parseAbsolute(`${startISO}T00:00:00Z`, tz);\r\n const endZoned = parseAbsolute(`${endISO}T00:00:00Z`, tz);\r\n\r\n if (!startZoned || !endZoned) return null;\r\n\r\n const startDate = new CalendarDate(startZoned.year, startZoned.month, startZoned.day);\r\n const endDate = new CalendarDate(endZoned.year, endZoned.month, endZoned.day);\r\n\r\n return {\r\n start: startDate as unknown as DateValue,\r\n end: endDate as unknown as DateValue,\r\n } as RangeValue<DateValue>;\r\n};\r\n\r\n/**\r\n * Convert date range to QueryFilter format\r\n */\r\nexport const dateRangeToFilter = (\r\n dateRange: RangeValue<DateValue> | null,\r\n columnId = \"startedAt\"\r\n): QueryFilter | null => {\r\n if (!dateRange || !dateRange.start || !dateRange.end) return null;\r\n\r\n const start = dateRange.start as unknown as CalendarDate;\r\n const end = dateRange.end as unknown as CalendarDate;\r\n\r\n if (!start?.year || !end?.year) return null;\r\n\r\n const startISO = calendarDateToUTC(start);\r\n const endISO = calendarDateToUTCEndOfDay(end);\r\n\r\n return {\r\n columnId,\r\n type: \"date\",\r\n method: \"between\",\r\n value: startISO,\r\n valueTo: endISO,\r\n };\r\n};\r\n"],"mappings":";;;;;;;;AASA,MAAa,qBAAqB,SAA+B;AAC/D,QAAOA,MAAAA,SAAS,IAAI,KAAK,MAAM,KAAK,OAAO,KAAK,IAAI,CAAC,OAAO,IAAI;;;;;AAMlE,MAAa,6BAA6B,SAA+B;AACvE,QAAOA,MAAAA,SAAS,IAAI,KAAK,MAAM,KAAK,OAAO,KAAK,IAAI,CAAC,MAAM,MAAM,CAAC,OAAO,IAAI;;;;;AAM/E,MAAa,oBAAoB,UAAuD;AACtF,KAAI,CAAC,SAAS,CAAC,MAAM,SAAS,CAAC,MAAM,IAAK,QAAO;CAEjD,MAAM,QAAQ,MAAM;CACpB,MAAM,MAAM,MAAM;AAElB,KAAI,CAAC,OAAO,QAAQ,CAAC,KAAK,KAAM,QAAO;AAMvC,QAAO,GAHU,GAAG,MAAM,KAAK,GAAG,OAAO,MAAM,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,OAAO,MAAM,IAAI,CAAC,SAAS,GAAG,IAAI,GAGzF,GAFJ,GAAG,IAAI,KAAK,GAAG,OAAO,IAAI,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,OAAO,IAAI,IAAI,CAAC,SAAS,GAAG,IAAI;;;;;AAQtG,MAAa,oBAAoB,UAAuD;AACtF,KAAI,CAAC,MAAO,QAAO;CAEnB,MAAM,CAAC,UAAU,UAAU,MAAM,MAAM,IAAI;AAC3C,KAAI,CAAC,YAAY,CAAC,OAAQ,QAAO;CAEjC,MAAM,MAAA,GAAA,wBAAA,mBAAuB;CAG7B,MAAM,cAAA,GAAA,wBAAA,eAA2B,GAAG,SAAS,aAAa,GAAG;CAC7D,MAAM,YAAA,GAAA,wBAAA,eAAyB,GAAG,OAAO,aAAa,GAAG;AAEzD,KAAI,CAAC,cAAc,CAAC,SAAU,QAAO;AAKrC,QAAO;EACL,OAJgB,IAAIC,wBAAAA,aAAa,WAAW,MAAM,WAAW,OAAO,WAAW,IAAI;EAKnF,KAJc,IAAIA,wBAAAA,aAAa,SAAS,MAAM,SAAS,OAAO,SAAS,IAAI;EAK5E;;;;;AAMH,MAAa,qBACX,WACA,WAAW,gBACY;AACvB,KAAI,CAAC,aAAa,CAAC,UAAU,SAAS,CAAC,UAAU,IAAK,QAAO;CAE7D,MAAM,QAAQ,UAAU;CACxB,MAAM,MAAM,UAAU;AAEtB,KAAI,CAAC,OAAO,QAAQ,CAAC,KAAK,KAAM,QAAO;AAKvC,QAAO;EACL;EACA,MAAM;EACN,QAAQ;EACR,OAPe,kBAAkB,MAAM;EAQvC,SAPa,0BAA0B,IAAI;EAQ5C"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@m5kdev/frontend",
3
- "version": "0.21.7",
3
+ "version": "0.23.0",
4
4
  "license": "GPL-3.0-only",
5
5
  "repository": {
6
6
  "type": "git",
@@ -23,11 +23,13 @@
23
23
  "luxon": "3.7.1",
24
24
  "react": "19.2.1",
25
25
  "react-dom": "19.2.1",
26
+ "i18next": "25.3.2",
26
27
  "zod": "4.2.1",
27
- "@m5kdev/commons": "0.21.7"
28
+ "@m5kdev/commons": "0.23.0"
28
29
  },
29
30
  "peerDependencies": {
30
- "@trpc/server": "11.4.3"
31
+ "@trpc/server": "11.4.3",
32
+ "i18next": "25.3.2"
31
33
  },
32
34
  "devDependencies": {
33
35
  "@tanstack/react-table": "8.21.2",
@@ -39,8 +41,8 @@
39
41
  "tsdown": "0.21.7",
40
42
  "typescript": "6.0.3",
41
43
  "vite": "7.0.4",
42
- "@m5kdev/backend": "0.21.7",
43
- "@m5kdev/config": "0.21.7"
44
+ "@m5kdev/config": "0.23.0",
45
+ "@m5kdev/backend": "0.23.0"
44
46
  },
45
47
  "exports": {
46
48
  ".": {
@@ -73,6 +75,16 @@
73
75
  "default": "./dist/src/modules/app/hooks/*.js"
74
76
  }
75
77
  },
78
+ "./modules/app/utils/*": {
79
+ "import": {
80
+ "types": "./dist/src/modules/app/utils/*.d.mts",
81
+ "default": "./dist/src/modules/app/utils/*.mjs"
82
+ },
83
+ "require": {
84
+ "types": "./dist/src/modules/app/utils/*.d.ts",
85
+ "default": "./dist/src/modules/app/utils/*.js"
86
+ }
87
+ },
76
88
  "./modules/auth/components/*": {
77
89
  "import": {
78
90
  "types": "./dist/src/modules/auth/components/*.d.mts",