From 1a2241c40e10193c5ff7008a7b7b36cc1d855d96 Mon Sep 17 00:00:00 2001 From: joonhoekim <26rote@gmail.com> Date: Tue, 25 Mar 2025 15:55:45 +0900 Subject: initial commit --- lib/parsers.ts | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 lib/parsers.ts (limited to 'lib/parsers.ts') diff --git a/lib/parsers.ts b/lib/parsers.ts new file mode 100644 index 00000000..20f3107b --- /dev/null +++ b/lib/parsers.ts @@ -0,0 +1,94 @@ +import type { ExtendedSortingState, Filter } from "@/types/table" +import { type Row } from "@tanstack/react-table" +import { createParser } from "nuqs/server" +import { z } from "zod" + +import { dataTableConfig } from "@/config/data-table" + +export const sortingItemSchema = z.object({ + id: z.string(), + desc: z.boolean(), +}) + +/** + * Creates a parser for TanStack Table sorting state. + * @param originalRow The original row data to validate sorting keys against. + * @returns A parser for TanStack Table sorting state. + */ +export const getSortingStateParser = ( + originalRow?: Row["original"] +) => { + const validKeys = originalRow ? new Set(Object.keys(originalRow)) : null + + return createParser>({ + parse: (value) => { + try { + const parsed = JSON.parse(value) + const result = z.array(sortingItemSchema).safeParse(parsed) + + if (!result.success) return null + + if (validKeys && result.data.some((item) => !validKeys.has(item.id))) { + return null + } + + return result.data as ExtendedSortingState + } catch { + return null + } + }, + serialize: (value) => JSON.stringify(value), + eq: (a, b) => + a.length === b.length && + a.every( + (item, index) => + item.id === b[index]?.id && item.desc === b[index]?.desc + ), + }) +} + +export const filterSchema = z.object({ + id: z.string(), + value: z.union([z.string(), z.array(z.string())]), + type: z.enum(dataTableConfig.columnTypes), + operator: z.enum(dataTableConfig.globalOperators), + rowId: z.string(), +}) + +/** + * Create a parser for data table filters. + * @param originalRow The original row data to create the parser for. + * @returns A parser for data table filters state. + */ +export const getFiltersStateParser = (originalRow?: Row["original"]) => { + const validKeys = originalRow ? new Set(Object.keys(originalRow)) : null + + return createParser[]>({ + parse: (value) => { + try { + const parsed = JSON.parse(value) + const result = z.array(filterSchema).safeParse(parsed) + + if (!result.success) return null + + if (validKeys && result.data.some((item) => !validKeys.has(item.id))) { + return null + } + + return result.data as Filter[] + } catch { + return null + } + }, + serialize: (value) => JSON.stringify(value), + eq: (a, b) => + a.length === b.length && + a.every( + (filter, index) => + filter.id === b[index]?.id && + filter.value === b[index]?.value && + filter.type === b[index]?.type && + filter.operator === b[index]?.operator + ), + }) +} -- cgit v1.2.3