From 754040cf5592365dbdda6346eedaa4a29e7bc0f9 Mon Sep 17 00:00:00 2001 From: Gauthier Roebroeck Date: Fri, 30 Jan 2026 11:13:05 +0800 Subject: [PATCH] use valibot for page coercion --- next-ui/src/composables/pagination.ts | 5 ++-- next-ui/src/types/page.test.ts | 35 +++++++++++++++++++++++++++ next-ui/src/types/page.ts | 4 +++ 3 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 next-ui/src/types/page.test.ts diff --git a/next-ui/src/composables/pagination.ts b/next-ui/src/composables/pagination.ts index 0b526d2b..2c94c9f7 100644 --- a/next-ui/src/composables/pagination.ts +++ b/next-ui/src/composables/pagination.ts @@ -1,6 +1,7 @@ import { syncRef } from '@vueuse/core' -import type { PageSize } from '@/types/page' +import { type PageSize, SchemaStrictlyPositive } from '@/types/page' import { useRouteQuery } from '@vueuse/router' +import * as v from 'valibot' /** * Provide synchronized refs for page tracking in 0-index and 1-index. @@ -12,7 +13,7 @@ import { useRouteQuery } from '@vueuse/router' */ export function usePagination() { const queryPage = useRouteQuery('page', '1', { - transform: (input) => Math.abs(Number(input)) || 1, + transform: (input) => v.parse(SchemaStrictlyPositive, input), }) const page0 = ref(queryPage.value - 1) const page1 = ref(queryPage.value) diff --git a/next-ui/src/types/page.test.ts b/next-ui/src/types/page.test.ts new file mode 100644 index 00000000..922e0f10 --- /dev/null +++ b/next-ui/src/types/page.test.ts @@ -0,0 +1,35 @@ +import { describe, expect, test } from 'vitest' +import * as v from 'valibot' +import { SchemaStrictlyPositive } from '@/types/page' + +describe('pagination composable', () => { + test('page=1', () => { + const result = v.parse(SchemaStrictlyPositive, '1') + + expect(result).toStrictEqual(1) + }) + + test('page=5', () => { + const result = v.parse(SchemaStrictlyPositive, '5') + + expect(result).toStrictEqual(5) + }) + + test('page=0', () => { + const result = v.parse(SchemaStrictlyPositive, '0') + + expect(result).toStrictEqual(1) + }) + + test('page=-25', () => { + const result = v.parse(SchemaStrictlyPositive, '') + + expect(result).toStrictEqual(1) + }) + + test('page=string', () => { + const result = v.parse(SchemaStrictlyPositive, 'some string') + + expect(result).toStrictEqual(1) + }) +}) diff --git a/next-ui/src/types/page.ts b/next-ui/src/types/page.ts index 18f1ec31..d4a32bce 100644 --- a/next-ui/src/types/page.ts +++ b/next-ui/src/types/page.ts @@ -1 +1,5 @@ +import * as v from 'valibot' + export type PageSize = 'unpaged' | number + +export const SchemaStrictlyPositive = v.fallback(v.pipe(v.string(), v.toNumber(), v.minValue(1)), 1)