UNPKG

advanced-search-params

Version:

[![npm version](https://badge.fury.io/js/%40urlkit%2Fsearch-params.svg)](https://www.npmjs.com/package/advanced-search-params) [![jsDelivr hits](https://data.jsdelivr.com/v1/package/npm/advanced-search-params/badge)](https://www.jsdelivr.com/package/npm/a

1 lines 27.3 kB
{"version":3,"sources":["../../../src/react/context.ts","../../../src/lib/adapters/nextjs/index.ts","../../../src/lib/adapters/react/index.ts","../../../src/lib/utils.ts","../../../src/lib/core/search-params.ts","../../../src/lib/adapters/server/index.ts","../../../src/lib/adapters/react-router/index.ts","../../../src/react/hooks/use-search-params.ts"],"names":["SearchParamsContext","createContext","useSearchParamsConfig","context","useContext","useNextAdapter","router","useRouter","pathname","usePathname","nextSearchParams","useSearchParams","mutableSearchParams","url","queryString","newParams","_","key","value","error","useReactAdapter","searchParams","setSearchParams","useState","useEffect","handleURLChange","navigate","useCallback","toArray","serialize","deserialize","validateParams","values","createUrl","params","search","createSearchParamsCore","adapter","getMutableParams","updateAndNavigate","updater","get","options","parsedValues","v","flattenedValues","set","add","currentValues","updated","remove","valuesToRemove","valueStr","defaultValue","currentValue","oldValue","newValue","result","existing","createServerAdapter","headersList","headers","ReadonlyURLSearchParams","useReactRouterAdapter","useRouterSearchParams","useNavigate","useLocation","config"],"mappings":"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","file":"index.cjs","sourcesContent":["\"use client\";\n\nimport { createContext, useContext } from \"react\";\nimport type { SearchParamsConfig } from \"../lib/types\";\n\nconst SearchParamsContext = createContext<SearchParamsConfig | null>(null);\n\nexport function useSearchParamsConfig() {\n const context = useContext(SearchParamsContext);\n if (!context) {\n throw new Error(\n \"useSearchParams must be used within a SearchParamsProvider\"\n );\n }\n return context;\n}\n\nexport { SearchParamsContext };\n","import { useSearchParams, useRouter, usePathname } from \"next/navigation\";\n\nexport function useNextAdapter() {\n const router = useRouter();\n const pathname = usePathname();\n const nextSearchParams = useSearchParams();\n\n if (!nextSearchParams) {\n console.error('[NextAdapter] searchParams is undefined');\n throw new Error('searchParams is undefined - ensure this is used in a Client Component');\n }\n\n // Create a mutable copy that will be used for all operations\n const mutableSearchParams = new URLSearchParams(nextSearchParams.toString());\n\n const navigate = (url: string) => {\n try {\n const queryString = url.split('?')[1] || '';\n const newParams = new URLSearchParams(queryString);\n \n mutableSearchParams.forEach((_, key) => mutableSearchParams.delete(key));\n newParams.forEach((value, key) => mutableSearchParams.append(key, value));\n \n router.replace(`${pathname}${queryString ? `?${queryString}` : ''}`, {\n scroll: false\n });\n } catch (error) {\n console.error('[NextAdapter] Navigation error:', error);\n throw error;\n }\n };\n\n return {\n pathname,\n searchParams: mutableSearchParams,\n navigate,\n };\n}","import { useState, useCallback, useEffect } from \"react\";\n\nexport function useReactAdapter() {\n const [searchParams, setSearchParams] = useState(\n () =>\n new URLSearchParams(\n typeof window !== \"undefined\" ? window.location.search : \"\"\n )\n );\n\n // Update searchParams when URL changes\n useEffect(() => {\n const handleURLChange = () => {\n setSearchParams(new URLSearchParams(window.location.search));\n };\n\n window.addEventListener(\"popstate\", handleURLChange);\n return () => window.removeEventListener(\"popstate\", handleURLChange);\n }, []);\n\n const navigate = useCallback((url: string) => {\n window.history.pushState({}, \"\", url);\n setSearchParams(new URLSearchParams(url.split(\"?\")[1] || \"\"));\n }, []);\n\n return {\n pathname: typeof window !== \"undefined\" ? window.location.pathname : \"/\",\n searchParams,\n navigate,\n };\n}\n","/**\n * Converts a value to an array if it isn't already one.\n */\nexport function toArray<T>(value: T | T[] | undefined): T[] {\n if (value === undefined) return [];\n return Array.isArray(value) ? value : [value];\n}\n\n/**\n * Serializes a value to a URL-safe string.\n */\nexport function serialize(value: unknown): string {\n if (value === undefined || value === null) return \"\";\n return JSON.stringify(value);\n}\n\n/**\n * Deserializes a URL-safe string to a value.\n */\nexport function deserialize<T>(value: string): T | undefined {\n try {\n return JSON.parse(value) as T;\n } catch (error) {\n return undefined;\n }\n}\n\n/**\n * Creates a new URLSearchParams instance with updated parameters.\n */\nexport function updateSearchParams(\n current: URLSearchParams,\n key: string,\n values: string[]\n): URLSearchParams {\n const newParams = new URLSearchParams(current);\n newParams.delete(key);\n values.forEach((value) => newParams.append(key, value));\n return newParams;\n}\n\n/**\n * Validates search parameter inputs.\n */\nexport function validateParams(key: string, values: unknown | unknown[]): void {\n if (!key) throw new Error(\"Key cannot be empty\");\n if (values === undefined) throw new Error(\"Values cannot be undefined\");\n}\n\n/**\n * Creates a URL string from pathname and search params.\n */\nexport function createUrl(pathname: string, params: URLSearchParams): string {\n const search = params.toString();\n return `${pathname}${search ? `?${search}` : \"\"}`;\n}\n\n/**\n * Processes multiple parameter updates.\n */\nexport function batchUpdateParams(\n current: URLSearchParams,\n updates: Record<string, string[]>\n): URLSearchParams {\n const newParams = new URLSearchParams(current);\n\n Object.entries(updates).forEach(([key, values]) => {\n newParams.delete(key);\n values.forEach((value) => newParams.append(key, value));\n });\n\n return newParams;\n}\n","import {\n serialize,\n deserialize,\n toArray,\n validateParams,\n createUrl,\n} from \"../utils\";\nimport type { ParamOptions } from \"../types\";\nimport { ReadonlyURLSearchParams } from \"next/navigation\";\n\n/**\n * Creates core search parameter functionality that can be used across different adapters.\n * This is the shared implementation used by both React hooks and vanilla JS.\n *\n * @param adapter - An object containing the adapter implementation\n * @param adapter.pathname - The current URL pathname\n * @param adapter.searchParams - The URLSearchParams instance (can be readonly in Next.js)\n * @param adapter.navigate - Function to handle URL navigation\n * @returns An object containing methods for manipulating URL parameters\n */\nexport function createSearchParamsCore(adapter: {\n pathname: string;\n searchParams: URLSearchParams | ReadonlyURLSearchParams;\n navigate: (url: string) => void;\n}) {\n const { pathname, searchParams, navigate } = adapter;\n\n const getMutableParams = () => {\n return new URLSearchParams(searchParams.toString());\n };\n\n const updateAndNavigate = (updater: (params: URLSearchParams) => void) => {\n const newParams = getMutableParams();\n updater(newParams);\n navigate(createUrl(pathname, newParams));\n };\n\n /**\n * Gets values for a key as a structured object containing both key and value(s).\n * If there's only one value, returns it as a string. If multiple values exist,\n * returns them as an array.\n *\n * @param key - The URL parameter key to get values for\n * @param options - Optional configuration for parsing values\n * @returns The value(s) for the key, or undefined if not found\n *\n * @example\n * // URL: ?filter=active\n * get('filter') // Returns: 'active'\n *\n * // URL: ?filter=active&filter=pending\n * get('filter') // Returns: ['active', 'pending']\n *\n * // URL: ?data={\"test\":true}\n * get('data', { parse: true }) // Returns: { test: true }\n */\n const get = <T>(key: string, options?: ParamOptions): T | undefined => {\n const values = searchParams.getAll(key);\n if (values.length === 0) return undefined;\n\n if (options?.parse) {\n try {\n const parsedValues = values.map((v) => deserialize<T>(v));\n return options?.forceArray || values.length > 1\n ? (parsedValues as T) \n : (parsedValues[0] as T);\n } catch (error) {\n return undefined;\n }\n }\n\n const flattenedValues = values.flatMap(v => v.split(','));\n return options?.forceArray || flattenedValues.length > 1\n ? (flattenedValues as T) \n : (flattenedValues[0] as T);\n };\n\n /**\n * Sets/replaces all values for a key.\n *\n * @param key - The URL parameter key to set values for\n * @param values - Single value or array of values to set\n * @param options - Optional configuration for serializing values\n *\n * @example\n * // Set single value\n * set('view', 'grid');\n *\n * // Set multiple values\n * set('filter', ['active', 'pending']);\n *\n * // Set serialized object\n * set('filters', { status: 'active' }, { serialize: true });\n */\n const set = (key: string, values: unknown | unknown[], options?: ParamOptions): void => {\n validateParams(key, values);\n updateAndNavigate((params) => {\n params.delete(key);\n const processedValues = options?.serialize\n ? toArray(values).map((v) => serialize(v))\n : toArray(values).map(String);\n processedValues.forEach((value) => params.append(key, value));\n });\n };\n\n /**\n * Adds new values to existing ones for a key, preventing duplicates.\n * Accepts either a single value or an array of values.\n *\n * @param key - The URL parameter key to add values to\n * @param values - Single value or array of values to add\n * @param options - Optional configuration for serializing values\n *\n * @example\n * // Add single value\n * add('filter', 'completed');\n *\n * // Add multiple values\n * add('filter', ['archived', 'draft']);\n */\n const add = (key: string, values: unknown | unknown[], options?: ParamOptions): void => {\n validateParams(key, values);\n const currentValues = get(key) || [];\n const updated = [...new Set([\n ...toArray(currentValues),\n ...toArray(options?.serialize ? toArray(values).map(serialize) : values)\n ])];\n \n updateAndNavigate((params) => {\n params.delete(key);\n updated.forEach((value) => params.append(key, String(value)));\n });\n };\n\n /**\n * Removes specific values from a key's array.\n * Accepts either a single value or an array of values to remove.\n *\n * @param key - The URL parameter key to remove values from\n * @param values - Single value or array of values to remove\n *\n * @example\n * // Remove single value\n * remove('filter', 'pending');\n *\n * // Remove multiple values\n * remove('filter', ['archived', 'draft']);\n */\n const remove = (key: string, values: unknown | unknown[]): void => {\n const currentValues = toArray(get(key));\n const valuesToRemove = toArray(values);\n const updated = currentValues.filter(\n (value) => !valuesToRemove.includes(value)\n );\n \n updateAndNavigate((params) => {\n params.delete(key);\n updated.forEach((value) => params.append(key, String(value)));\n });\n };\n\n /**\n * Checks if a URL parameter key contains a specific value.\n * For single values, checks for exact match.\n * For array values, checks if value exists in the array.\n *\n * @param key - The URL parameter key to check\n * @param value - The value to look for\n * @param options - Optional configuration for parsing values before comparison\n * @returns True if the key contains the value, false otherwise\n *\n * @example\n * // URL: ?filter=active\n * matches('filter', 'active') // true\n * matches('filter', 'pending') // false\n *\n * // URL: ?filter=active&filter=pending\n * matches('filter', 'active') // true\n * matches('filter', 'completed') // false\n */\n const matches = (key: string, value: unknown, options?: ParamOptions): boolean => {\n const values = get(key, options);\n if (!values) return false;\n\n // For parsed objects, use JSON string comparison\n if (options?.parse) {\n const valueStr = JSON.stringify(value);\n if (Array.isArray(values)) {\n return values.some(v => JSON.stringify(v) === valueStr);\n }\n return JSON.stringify(values) === valueStr;\n }\n\n // For regular values, use direct comparison\n if (Array.isArray(values)) {\n return values.includes(value as never);\n }\n return values === value;\n };\n\n /**\n * Gets a value with a default fallback if the key doesn't exist.\n *\n * @param key - The URL parameter key to get the value for\n * @param defaultValue - The default value to return if the key doesn't exist\n * @param options - Optional configuration for parsing values\n * @returns The value if it exists, otherwise the default value\n */\n const getWithDefault = <T>(\n key: string,\n defaultValue: T,\n options?: ParamOptions\n ): T => {\n const value = get<T>(key, options);\n return value === undefined ? defaultValue : value;\n };\n\n /**\n * Clears a specific key from the URL parameters\n */\n const clear = (key: string): void => {\n updateAndNavigate((params) => params.delete(key));\n };\n\n /**\n * Resets all URL search parameters\n */\n const resetAllParams = (): void => {\n navigate(pathname);\n };\n\n /**\n * Sets multiple URL parameter key/value pairs simultaneously.\n * Preserves any existing parameters not included in the update.\n *\n * @param params - An object where keys are parameter names and values are arrays of values\n * @param options - Optional configuration for serializing values\n *\n * @example\n * // Set multiple parameters at once\n * setMany({\n * filter: ['active', 'pending'],\n * sort: ['date'],\n * view: ['grid']\n * });\n *\n * // Set serialized objects\n * setMany({\n * filters: [{ status: 'active' }],\n * config: [{ view: 'grid' }]\n * }, { serialize: true });\n */\n const setMany = (\n params: Record<string, string | string[]>,\n options?: ParamOptions\n ): void => {\n Object.entries(params).forEach(([key, values]) => {\n validateParams(key, values);\n });\n\n updateAndNavigate((newParams) => {\n Object.entries(params).forEach(([key, values]) => {\n newParams.delete(key);\n const processedValues = options?.serialize\n ? toArray(values).map((v) => serialize(v))\n : toArray(values).map(String);\n processedValues.forEach((value) => newParams.append(key, value));\n });\n });\n };\n\n const toggle = (key: string, value?: string, options?: ParamOptions): void => {\n const currentValue = get(key, options);\n if (currentValue) {\n remove(key, currentValue);\n } else {\n add(key, value || 'true', options);\n }\n };\n\n const update = (key: string, oldValue: string, newValue: string): void => {\n const currentValues = toArray(get(key));\n const updated = currentValues.map((value) => (value === oldValue ? newValue : value));\n set(key, updated);\n };\n\n const getAll = (): Record<string, string | string[]> => {\n const result: Record<string, string | string[]> = {};\n searchParams.forEach((value, key) => {\n const existing = result[key];\n result[key] = existing ? [...toArray(existing), value] : value;\n });\n return result;\n };\n\n return {\n get,\n set,\n add,\n remove,\n matches,\n getWithDefault,\n clear,\n resetAllParams,\n setMany,\n toggle,\n update,\n getAll,\n params: searchParams,\n };\n}\n","import { headers } from \"next/headers\";\nimport { ReadonlyURLSearchParams } from \"next/navigation\";\n\nexport function createServerAdapter(pathname?: string) {\n // Get URL from headers during SSR\n const headersList = headers();\n const url = new URL(\n headersList.get(\"x-url\") || headersList.get(\"referer\") || \"/\"\n );\n\n // Create readonly search params from URL\n const searchParams = new ReadonlyURLSearchParams(new URLSearchParams(url.search));\n\n return {\n pathname: pathname || url.pathname,\n searchParams,\n // No-op navigate function for server\n navigate: (url: string) => {\n console.warn(url, \"Navigation attempted on server side\");\n },\n };\n} ","import {\n useNavigate,\n useLocation,\n useSearchParams as useRouterSearchParams,\n} from \"react-router-dom\";\n\nexport function useReactRouterAdapter() {\n const [searchParams] = useRouterSearchParams();\n const navigate = useNavigate();\n const location = useLocation();\n\n return {\n pathname: location.pathname,\n searchParams,\n navigate,\n };\n}\n","\"use client\";\n\nimport { useSearchParamsConfig } from \"../context\";\nimport { useNextAdapter } from \"../../lib/adapters/nextjs\";\nimport { useReactAdapter } from \"../../lib/adapters/react\";\nimport type { UseParamsReturn } from \"../../lib/types\";\nimport { createSearchParamsCore } from \"../../lib/core/search-params\";\nimport { createServerAdapter } from \"../../lib/adapters/server\";\nimport { useReactRouterAdapter } from \"../../lib/adapters/react-router\";\n\n/**\n * Hook for managing URL search parameters with support for multiple values per key.\n * \n * @returns {UseParamsReturn} Object with methods: \n * get, set, add, remove, getWithDefault, matches, update, clear, resetAllParams, getAll, setMany\n * \n * @example\n * ```tsx\n * function FilterComponent() {\n * const { get, set, add, remove } = useSearchParams();\n * \n * // Get current filters\n * const filters = get('filter');\n * \n * return (\n * <div>\n * <button onClick={() => add('filter', 'active')}>Add Active</button>\n * <button onClick={() => remove('filter', 'active')}>Remove Active</button>\n * </div>\n * );\n * }\n * ```\n */\nexport function useSearchParams(): UseParamsReturn {\n const config = useSearchParamsConfig();\n\n if (!config) {\n throw new Error(\n \"useSearchParams must be used within a SearchParamsProvider\"\n );\n }\n\n const adapterConfig = () => {\n switch(config.provider) {\n case \"next\":\n return useNextAdapter();\n case \"react\":\n return useReactAdapter();\n case 'react-router':\n return useReactRouterAdapter();\n case \"server\":\n return createServerAdapter();\n default:\n return useReactAdapter();\n }\n };\n\n return createSearchParamsCore(adapterConfig());\n}\n"]}