Files
med-notes/.pnpm-store/v10/files/e1/9514f6ddc6b600b8edc16d13c03b9a9d291484a291ff9ae7b6f39fbb6a2465466bba4083a924813bedf12c26a5e68d978a021bb4280d28fab5763b58a3d8d7
2025-05-09 05:30:08 +02:00

78 lines
1.9 KiB
Plaintext

import { decode, encode } from './qss'
import type { AnySchema } from './validators'
export const defaultParseSearch = parseSearchWith(JSON.parse)
export const defaultStringifySearch = stringifySearchWith(
JSON.stringify,
JSON.parse,
)
export function parseSearchWith(parser: (str: string) => any) {
return (searchStr: string): AnySchema => {
if (searchStr.substring(0, 1) === '?') {
searchStr = searchStr.substring(1)
}
const query: Record<string, unknown> = decode(searchStr)
// Try to parse any query params that might be json
for (const key in query) {
const value = query[key]
if (typeof value === 'string') {
try {
query[key] = parser(value)
} catch (err) {
//
}
}
}
return query
}
}
export function stringifySearchWith(
stringify: (search: any) => string,
parser?: (str: string) => any,
) {
function stringifyValue(val: any) {
if (typeof val === 'object' && val !== null) {
try {
return stringify(val)
} catch (err) {
// silent
}
} else if (typeof val === 'string' && typeof parser === 'function') {
try {
// Check if it's a valid parseable string.
// If it is, then stringify it again.
parser(val)
return stringify(val)
} catch (err) {
// silent
}
}
return val
}
return (search: Record<string, any>) => {
search = { ...search }
Object.keys(search).forEach((key) => {
const val = search[key]
if (typeof val === 'undefined' || val === undefined) {
delete search[key]
} else {
search[key] = stringifyValue(val)
}
})
const searchStr = encode(search as Record<string, string>).toString()
return searchStr ? `?${searchStr}` : ''
}
}
export type SearchSerializer = (searchObj: Record<string, any>) => string
export type SearchParser = (searchStr: string) => Record<string, any>