From d803dc06cf01a5a3eb3cc332cec9dca178b967c8 Mon Sep 17 00:00:00 2001 From: vigdorov Date: Fri, 25 Dec 2020 13:46:43 +0300 Subject: [PATCH] query parsers --- package-lock.json | 5 ++ package.json | 1 + src/common/hooks/useQuery.ts | 46 ++++++++++++++++++- .../auth-response/components/page/Page.tsx | 16 +++++-- src/utils/parsers.ts | 4 ++ 5 files changed, 67 insertions(+), 5 deletions(-) create mode 100644 src/utils/parsers.ts diff --git a/package-lock.json b/package-lock.json index b66e6ad..f6058bd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4772,6 +4772,11 @@ "whatwg-url": "^8.0.0" } }, + "date-fns": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.16.1.tgz", + "integrity": "sha512-sAJVKx/FqrLYHAQeN7VpJrPhagZc9R4ImZIWYRFZaaohR3KzmuK88touwsSwSVT8Qcbd4zoDsnGfX4GFB4imyQ==" + }, "debug": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", diff --git a/package.json b/package.json index f14de3b..f6adb00 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "@most/types": "^1.1.0", "@types/uuid": "^8.3.0", "axios": "^0.21.0", + "date-fns": "^2.16.1", "file-loader": "^6.2.0", "fp-ts": "^2.8.5", "lodash": "^4.17.20", diff --git a/src/common/hooks/useQuery.ts b/src/common/hooks/useQuery.ts index 21b79ab..ead4bf7 100644 --- a/src/common/hooks/useQuery.ts +++ b/src/common/hooks/useQuery.ts @@ -1,10 +1,54 @@ +import {head} from 'lodash'; import {parse, ParsedUrlQuery} from 'querystring'; import {useMemo} from 'react'; import {useLocation} from 'react-router-dom'; +import {toNumber} from '../../utils/parsers'; -type QueryParser = (value?: string | string[]) => Undefinable; +type QueryParser = (value?: string | string[]) => T; export type QueryParsers = Partial<{[K in keyof T]: QueryParser}>; +export function stringParser(): QueryParser>; +export function stringParser(defaultValue: T): QueryParser; +export function stringParser(defaultValue?: T) { + return (val?: string | string[]) => { + const value = Array.isArray(val) ? head(val) : val; + + return value ?? defaultValue; + }; +} + +export function numberParser(): QueryParser>; +export function numberParser(defaultValue?: number): QueryParser; +export function numberParser(defaultValue?: number) { + return (val?: string | string[]) => { + const value = Array.isArray(val) ? head(val) : val; + + return toNumber(value) ?? defaultValue; + }; +} + +export function booleanParser(): QueryParser>; +export function booleanParser(defaultValue: boolean): QueryParser; +export function booleanParser(defaultValue?: boolean) { + return (val?: string | string[]) => { + const value = Array.isArray(val) ? head(val) : val; + + if (value === 'true') { + return true; + } + + if (value === 'false') { + return false; + } + + return defaultValue; + }; +} + +// Date parser + +// Array parser (должен уметь с enum) + export function useQuery(): ParsedUrlQuery; export function useQuery(queryParsers: QueryParsers): Partial; export function useQuery( diff --git a/src/pages/auth-response/components/page/Page.tsx b/src/pages/auth-response/components/page/Page.tsx index 2aab5a3..1785c02 100644 --- a/src/pages/auth-response/components/page/Page.tsx +++ b/src/pages/auth-response/components/page/Page.tsx @@ -1,16 +1,24 @@ +import {format} from 'date-fns'; import {parse} from 'querystring'; import React, {memo} from 'react'; -import {QueryParsers, useQuery} from '../../../../common/hooks/useQuery'; +import {numberParser, QueryParsers, stringParser, useQuery} from '../../../../common/hooks/useQuery'; import {QueryResponse, QueryResponseError} from '../../types'; +const enum PersonType { + One = 'one', + Two = 'two' +} + type Person = { name: string; - age: number; + age?: number; + type: PersonType; }; const parsers: QueryParsers = { - name: name => name ? name.toString() : '', - age: age => age ? Number(age) : undefined, + name: stringParser(''), + age: numberParser(), + type: stringParser(PersonType.One), }; const AuthResponsePage: React.FC = () => { diff --git a/src/utils/parsers.ts b/src/utils/parsers.ts new file mode 100644 index 0000000..68cf6b5 --- /dev/null +++ b/src/utils/parsers.ts @@ -0,0 +1,4 @@ +export const toNumber = (val: unknown): Undefinable => { + const prepareValue = Number(val); + return Number.isNaN(prepareValue) ? undefined : prepareValue; +};