react-magic-search-params 1.1.5 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +20 -20
- package/README.md +69 -1084
- package/dist/index.cjs +1 -0
- package/dist/index.d.mts +99 -0
- package/dist/index.d.ts +99 -1
- package/dist/index.js +1 -8
- package/package.json +39 -30
- package/dist/constants/defaultParamsPage.d.ts +0 -12
- package/dist/react-magic-search-params.cjs.development.js +0 -496
- package/dist/react-magic-search-params.cjs.development.js.map +0 -1
- package/dist/react-magic-search-params.cjs.production.min.js +0 -2
- package/dist/react-magic-search-params.cjs.production.min.js.map +0 -1
- package/dist/react-magic-search-params.esm.js +0 -492
- package/dist/react-magic-search-params.esm.js.map +0 -1
- package/dist/useMagicSearchParams.d.ts +0 -46
- package/src/constants/defaultParamsPage.ts +0 -16
- package/src/index.d.ts +0 -1
- package/src/index.tsx +0 -1
- package/src/useMagicSearchParams.ts +0 -527
package/dist/index.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var V=Object.defineProperty;var ie=Object.getOwnPropertyDescriptor;var ue=Object.getOwnPropertyNames;var me=Object.prototype.hasOwnProperty;var Pe=(m,y)=>{for(var f in y)V(m,f,{get:y[f],enumerable:!0})},le=(m,y,f,p)=>{if(y&&typeof y=="object"||typeof y=="function")for(let d of ue(y))!me.call(m,d)&&d!==f&&V(m,d,{get:()=>y[d],enumerable:!(p=ie(y,d))||p.enumerable});return m};var pe=m=>le(V({},"__esModule",{value:!0}),m);var fe={};Pe(fe,{useMagicSearchParams:()=>Y});module.exports=pe(fe);var Q=require("react-router-dom"),P=require("react"),Y=({mandatory:m={},optional:y={},defaultParams:f={},arraySerialization:p="csv",forceParams:d={},omitParamsByValues:q=[],codecs:F={},historyMode:E="push",resetOnChange:G={},paginationStrategy:w,unknownParamsPolicy:A="drop"})=>{let[i,L]=(0,Q.useSearchParams)(),j=(0,P.useRef)({}),U=(0,P.useRef)({}),I=(0,P.useCallback)((e,r)=>{L(e,{replace:(r??E)==="replace"})},[L,E]),l=(0,P.useMemo)(()=>({...m,...y}),[m,y]),J=(0,P.useMemo)(()=>Array.from(Object.keys(l)),[l]),v=(0,P.useCallback)(e=>Object.prototype.hasOwnProperty.call(l,e),[l]),X=e=>!Array.isArray(l[e])||p==="csv"?i.get(e):p==="repeat"?i.getAll(e):i.getAll(`${e}[]`),H=(0,P.useCallback)(()=>{if(A==="drop")return[];let e=[];for(let[r,a]of i.entries()){let s=r.endsWith("[]")?r.replace("[]",""):r;v(s)||e.push([r,a])}return e},[A,i,v]),_=(0,P.useCallback)(e=>{if(A==="drop")return e;let r=new URLSearchParams(e.toString()),a=H();for(let[s,t]of a)r.append(s,t);return r},[A,H]),W=(e,r)=>Array.isArray(e)&&Array.isArray(r)?e.length!==r.length?!1:e.every((a,s)=>a===r[s]):e===r,C=(0,P.useMemo)(()=>Object.keys(l).filter(e=>Array.isArray(l[e])),[l]),Z=(e,r)=>{let a={...e};return C.length===0||C.forEach(s=>{let t=[];switch(p){case"csv":{t=(i.get(s)||"").split(",").map(o=>o.trim()).filter(Boolean);break}case"repeat":{let n=i.getAll(s);t=n.length>0?n:[];break}case"brackets":{let n=i.getAll(`${s}[]`);t=n.length>0?n:[];break}default:t=(i.get(s)??"").split(",").map(o=>o.trim()).filter(Boolean)}if(r[s]!==void 0){let n=r[s],o=[];typeof n=="string"?o=t.includes(n)?t.filter(u=>u!==n):[...t,n]:Array.isArray(n)?o=Array.from(new Set([...n.map(String)])):o=t,a[s]=o}}),a},O=e=>{let r=new URLSearchParams,a=Object.keys(e);for(let s of a){let t=F[s];if(t?.serialize){let n=t.serialize(e[s],{key:s});if(n==null)continue;if(Array.isArray(n))if(Array.isArray(l[s]))if(p==="csv")r.set(s,n.join(","));else if(p==="repeat")for(let o of n)r.append(s,String(o));else for(let o of n)r.append(`${s}[]`,String(o));else n.length>0&&r.set(s,String(n[0]));else r.set(s,String(n));continue}if(Array.isArray(l[s])){let n=e[s];switch(p){case"csv":{r.set(s,n.join(","));break}case"repeat":{for(let o of n)r.append(s,String(o));break}case"brackets":{for(let o of n)r.append(`${s}[]`,String(o));break}default:r.set(s,n.join(","))}}else r.set(s,String(e[s]))}return r},h=(e,r)=>Object.prototype.hasOwnProperty.call(m,e)?m[e]:Object.prototype.hasOwnProperty.call(f,e)?f[e]:r,$=({paramsForced:e,compareParams:r})=>Object.entries(e).every(([s,t])=>r[s]===t),T=e=>{let r=X(e),a=F[e];if(a?.parse)return a.parse(r,{key:e,searchParams:i});if(typeof l[e]=="number"){let s=Number.parseInt(String(r??""),10);if(Number.isNaN(s)){let t=h(e,0);return typeof t=="number"?t:0}return s}return typeof l[e]=="boolean"?String(r)==="true":Array.isArray(l[e])?p==="csv"?String(r??"").split(",").filter(Boolean):Array.isArray(r)?r:r?[r]:[]:Array.isArray(r)?r[0]??"":r??""},B=(e,r)=>{if(Array.isArray(l[e])){if(p==="brackets"){let t=i.getAll(`${e}[]`),n=O({[e]:t}).toString();return decodeURIComponent(n)}if(p==="csv"){let t=i.getAll(e),n=O({[e]:t}).toString();return decodeURIComponent(n)}let s=i.getAll(e);return O({[e]:s}).toString()}return r[e]},z=e=>{let r={};for(let[a,s]of e.entries())if(a.endsWith("[]")){let t=a.replace("[]","");r[t]?r[t].push(s):r[t]=[s]}else r[a]?Array.isArray(r[a])?r[a].push(s):r[a]=[r[a],s]:r[a]=s;return r},S=(0,P.useMemo)(()=>p==="brackets"?z(i):Object.fromEntries(i.entries()),[i,p]),b=({convert:e=!0}={})=>Object.keys(S).reduce((a,s)=>{if(Object.prototype.hasOwnProperty.call(l,s)){let t=p==="brackets"?s.replace("[]",""):s;a[t]=e===!0?T(t):B(s,S)}return a},{}),K=(e,r)=>{let a=String(e);return r?.convert!==!1?T(a):B(a,S)},ee=e=>e==null||typeof e!="object"?!1:Object.prototype.hasOwnProperty.call(e,"newParams")||Object.prototype.hasOwnProperty.call(e,"keepParams")||Object.prototype.hasOwnProperty.call(e,"historyMode"),re=e=>{let r=b({convert:!0});if(typeof e=="function"){let a=e(r);return ee(a)?{newParams:typeof a.newParams=="function"?a.newParams(r):a.newParams??{},keepParams:a.keepParams??{},historyMode:a.historyMode}:{newParams:a,keepParams:{},historyMode:void 0}}return e?{newParams:typeof e.newParams=="function"?e.newParams(r):e.newParams??{},keepParams:e.keepParams??{},historyMode:e.historyMode}:{newParams:{},keepParams:{},historyMode:void 0}},se=({currentParams:e,newParams:r,keepParams:a})=>{let s={...r},t={...a};for(let[n,o]of Object.entries(G))if(!(!o||o.length===0||!Object.prototype.hasOwnProperty.call(s,n)||W(s[n],e[n]))){for(let c of o)if(!Object.prototype.hasOwnProperty.call(d,c)){if(Object.prototype.hasOwnProperty.call(m,c)){s[c]=m[c],delete t[c];continue}if(Object.prototype.hasOwnProperty.call(f,c)){s[c]=f[c],delete t[c];continue}delete s[c],t[c]=!1}}return{newParams:s,keepParams:t}},ae=(e,r)=>{let a=b(),s=Object.entries(e).filter(([o])=>!Array.isArray(l[o])),t=Object.assign({...a,...Object.fromEntries(s)},d),n=Object.keys(t).reduce((o,u)=>{if(Object.prototype.hasOwnProperty.call(r,u)&&r[u]===!1)return o;let c=t[u];return c!=null&&c!==""&&!q.includes(c)&&(o[u]=c),o},{});return{...m,...n}},te=e=>J.reduce((a,s)=>(Object.prototype.hasOwnProperty.call(e,s)&&(a[s]=e[s]),a),{}),ne=()=>{let e=C.length>0,r=b({convert:e});return Object.keys(r).reduce((s,t)=>(Object.prototype.hasOwnProperty.call(m,t)&&(s[t]=r[t]),s),{})},D=({keepMandatoryParams:e=!0,historyMode:r}={})=>{let a=O({...m,...e&&{...ne()},...d}),s=_(a);I(s,r)},g=e=>{let r=re(e),a=b({convert:!0}),s=se({currentParams:a,newParams:r.newParams,keepParams:r.keepParams}),t=s.newParams,n=s.keepParams;if(Object.keys(t).length===0&&Object.keys(n).length===0){D({historyMode:r.historyMode});return}let o=ae(t,n),u=Z(o,t),c=te(u),R=O(c),x=_(R);I(x,r.historyMode)},M=w?.mode==="page"?w:void 0,k=w?.mode==="offset"?w:void 0,N=w?.mode==="cursor"?w:void 0,oe={mode:w?.mode??"page",next:e=>{let r=w?.mode??"page";if(r==="cursor"){let n=N?.cursorKey??"cursor";typeof e=="string"&&g({newParams:{[n]:e}});return}if(r==="offset"){let n=k?.offsetKey??"offset",o=k?.limitKey??"limit",u=Number(K(n,{convert:!0})??0),c=Number(K(o,{convert:!0})??h(String(o),10)),R=Number.isFinite(u)?u:0,x=Number.isFinite(c)&&c>0?c:10;g({newParams:{[n]:R+x}});return}let a=M?M.pageKey??"page":"page",s=Number(K(a,{convert:!0})??h(String(a),1)),t=Number.isFinite(s)&&s>0?s:1;g({newParams:{[a]:t+1}})},prev:()=>{let e=w?.mode??"page";if(e==="cursor"){let t=N?.cursorKey??"cursor";g({keepParams:{[t]:!1}});return}if(e==="offset"){let t=k?.offsetKey??"offset",n=k?.limitKey??"limit",o=Number(K(t,{convert:!0})??0),u=Number(K(n,{convert:!0})??h(String(n),10)),c=Number.isFinite(o)?o:0,R=Number.isFinite(u)&&u>0?u:10;g({newParams:{[t]:Math.max(0,c-R)}});return}let r=M?M.pageKey??"page":"page",a=Number(K(r,{convert:!0})??h(String(r),1)),s=Number.isFinite(a)&&a>0?a:1;g({newParams:{[r]:Math.max(1,s-1)}})},reset:()=>{let e=w?.mode??"page";if(e==="cursor"){let s=N?.cursorKey??"cursor";g({keepParams:{[s]:!1}});return}if(e==="offset"){let s=k?.offsetKey??"offset",t=Number(h(String(s),0));g({newParams:{[s]:Number.isFinite(t)?t:0}});return}let r=M?M.pageKey??"page":"page",a=Number(h(String(r),1));g({newParams:{[r]:Number.isFinite(a)&&a>0?a:1}})},setCursor:e=>{let a=(w?.mode??"page")==="cursor"?N?.cursorKey??"cursor":"cursor";if(e==null||e===""){g({keepParams:{[a]:!1}});return}g({newParams:{[a]:e}})}},ce=(0,P.useCallback)((e,r)=>{let a=String(e);return j.current[a]=r,()=>{delete j.current[a],delete U.current[a]}},[]);return(0,P.useEffect)(()=>{for(let[e,r]of Object.entries(j.current)){let a=v(e)?T(e):i.get(e),s=U.current[e]??null;if(!W(a,s))for(let t of r)t({key:e,previousValue:s,currentValue:a});U.current[e]=a}},[S,v,i]),(0,P.useEffect)(()=>{let e=Object.keys(f),r=Object.keys(d);if(e.length===0&&r.length===0)return;function a(){let s=O(f).toString(),t=b(),n=O(t).toString();if(!$({paramsForced:d,compareParams:t})){g({newParams:{...f,...d}});return}let u=$({paramsForced:d,compareParams:f});if(e.length>0&&u){if(s===n)return;g({newParams:f})}}a()},[]),{searchParams:i,updateParams:g,clearParams:D,getParams:b,getParam:K,onChange:ce,pagination:oe}};0&&(module.exports={useMagicSearchParams});
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
type CommonParams = {
|
|
2
|
+
page?: number;
|
|
3
|
+
page_size?: number;
|
|
4
|
+
};
|
|
5
|
+
type MergeParams<M, O> = {
|
|
6
|
+
[K in keyof M]: M[K];
|
|
7
|
+
} & {
|
|
8
|
+
[K in keyof O]?: O[K];
|
|
9
|
+
};
|
|
10
|
+
type ParamCodec<TValue> = {
|
|
11
|
+
parse?: (value: string | string[] | null, context: {
|
|
12
|
+
key: string;
|
|
13
|
+
searchParams: URLSearchParams;
|
|
14
|
+
}) => TValue;
|
|
15
|
+
serialize?: (value: TValue, context: {
|
|
16
|
+
key: string;
|
|
17
|
+
}) => string | string[] | null | undefined;
|
|
18
|
+
};
|
|
19
|
+
type ParamCodecs<TParams extends Record<string, unknown>> = Partial<{
|
|
20
|
+
[K in keyof TParams]: ParamCodec<TParams[K]>;
|
|
21
|
+
}>;
|
|
22
|
+
type ParamKey<TParams extends Record<string, unknown>> = Extract<keyof TParams, string>;
|
|
23
|
+
type PaginationStrategy<TParams extends Record<string, unknown>> = {
|
|
24
|
+
mode: 'page';
|
|
25
|
+
pageKey?: ParamKey<TParams>;
|
|
26
|
+
pageSizeKey?: ParamKey<TParams>;
|
|
27
|
+
} | {
|
|
28
|
+
mode: 'offset';
|
|
29
|
+
offsetKey?: ParamKey<TParams>;
|
|
30
|
+
limitKey?: ParamKey<TParams>;
|
|
31
|
+
} | {
|
|
32
|
+
mode: 'cursor';
|
|
33
|
+
cursorKey?: ParamKey<TParams>;
|
|
34
|
+
};
|
|
35
|
+
type ResetOnChangeRules<TParams extends Record<string, unknown>> = Partial<Record<ParamKey<TParams>, Array<ParamKey<TParams>>>>;
|
|
36
|
+
type UnknownParamsPolicy = 'drop' | 'preserve';
|
|
37
|
+
type HistoryMode = 'push' | 'replace';
|
|
38
|
+
type OnChangeEvent<TParams extends Record<string, unknown>> = {
|
|
39
|
+
key: keyof TParams;
|
|
40
|
+
previousValue: unknown;
|
|
41
|
+
currentValue: unknown;
|
|
42
|
+
};
|
|
43
|
+
type OnChangeCallback<TParams extends Record<string, unknown>> = ((event: OnChangeEvent<TParams>) => void) | (() => void);
|
|
44
|
+
/**
|
|
45
|
+
* Interface for the configuration object that the hook receives
|
|
46
|
+
*/
|
|
47
|
+
interface UseMagicSearchParamsOptions<M extends Record<string, unknown>, O extends Record<string, unknown>> {
|
|
48
|
+
mandatory: M;
|
|
49
|
+
optional?: O;
|
|
50
|
+
defaultParams?: Partial<MergeParams<M, O>>;
|
|
51
|
+
forceParams?: Partial<MergeParams<M, O>>;
|
|
52
|
+
arraySerialization?: 'csv' | 'repeat' | 'brackets';
|
|
53
|
+
omitParamsByValues?: Array<'all' | 'default' | 'unknown' | 'none' | 'void'>;
|
|
54
|
+
codecs?: ParamCodecs<MergeParams<M, O>>;
|
|
55
|
+
historyMode?: HistoryMode;
|
|
56
|
+
resetOnChange?: ResetOnChangeRules<MergeParams<M, O>>;
|
|
57
|
+
paginationStrategy?: PaginationStrategy<MergeParams<M, O>>;
|
|
58
|
+
unknownParamsPolicy?: UnknownParamsPolicy;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
Generic hook to handle search parameters in the URL
|
|
62
|
+
@param mandatory - Mandatory parameters (e.g., page=1, page_size=10, etc.)
|
|
63
|
+
@param optional - Optional parameters (e.g., order, search, etc.)
|
|
64
|
+
@param defaultParams - Default parameters sent in the URL on initialization
|
|
65
|
+
@param forceParams - Parameters forced into the URL regardless of user input
|
|
66
|
+
@param omitParamsByValues - Parameters omitted if they have specific values
|
|
67
|
+
*/
|
|
68
|
+
declare const useMagicSearchParams: <M extends Record<string, unknown> & CommonParams, O extends Record<string, unknown>>({ mandatory, optional, defaultParams, arraySerialization, forceParams, omitParamsByValues, codecs, historyMode, resetOnChange, paginationStrategy, unknownParamsPolicy }: UseMagicSearchParamsOptions<M, O>) => {
|
|
69
|
+
searchParams: URLSearchParams;
|
|
70
|
+
updateParams: (input?: {
|
|
71
|
+
newParams?: Partial<MergeParams<M, O>> | ((current: MergeParams<M, O>) => Partial<MergeParams<M, O>>);
|
|
72
|
+
keepParams?: Partial<Record<Extract<keyof M, string> | Extract<keyof O, string>, boolean>>;
|
|
73
|
+
historyMode?: HistoryMode;
|
|
74
|
+
} | ((current: MergeParams<M, O>) => {
|
|
75
|
+
newParams?: Partial<MergeParams<M, O>> | ((current: MergeParams<M, O>) => Partial<MergeParams<M, O>>);
|
|
76
|
+
keepParams?: Partial<Record<Extract<keyof M, string> | Extract<keyof O, string>, boolean>>;
|
|
77
|
+
historyMode?: HistoryMode;
|
|
78
|
+
} | Partial<MergeParams<M, O>>)) => void;
|
|
79
|
+
clearParams: ({ keepMandatoryParams, historyMode: historyModeOverride }?: {
|
|
80
|
+
keepMandatoryParams?: boolean;
|
|
81
|
+
historyMode?: HistoryMode;
|
|
82
|
+
}) => void;
|
|
83
|
+
getParams: ({ convert }?: {
|
|
84
|
+
convert?: boolean | undefined;
|
|
85
|
+
}) => MergeParams<M, O>;
|
|
86
|
+
getParam: <K extends Extract<keyof M, string> | Extract<keyof O, string>, T extends boolean = true>(key: K, options?: {
|
|
87
|
+
convert: T;
|
|
88
|
+
}) => T extends true ? MergeParams<M, O>[K] : string;
|
|
89
|
+
onChange: (paramName: Extract<keyof M, string> | Extract<keyof O, string>, callbacks: Array<OnChangeCallback<MergeParams<M, O>>>) => () => void;
|
|
90
|
+
pagination: {
|
|
91
|
+
mode: "page" | "offset" | "cursor";
|
|
92
|
+
next: (cursor?: string) => void;
|
|
93
|
+
prev: () => void;
|
|
94
|
+
reset: () => void;
|
|
95
|
+
setCursor: (cursor: string | null | undefined) => void;
|
|
96
|
+
};
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
export { type HistoryMode, type OnChangeEvent, type PaginationStrategy, type ParamCodec, type ResetOnChangeRules, type UnknownParamsPolicy, type UseMagicSearchParamsOptions, useMagicSearchParams };
|
package/dist/index.d.ts
CHANGED
|
@@ -1 +1,99 @@
|
|
|
1
|
-
|
|
1
|
+
type CommonParams = {
|
|
2
|
+
page?: number;
|
|
3
|
+
page_size?: number;
|
|
4
|
+
};
|
|
5
|
+
type MergeParams<M, O> = {
|
|
6
|
+
[K in keyof M]: M[K];
|
|
7
|
+
} & {
|
|
8
|
+
[K in keyof O]?: O[K];
|
|
9
|
+
};
|
|
10
|
+
type ParamCodec<TValue> = {
|
|
11
|
+
parse?: (value: string | string[] | null, context: {
|
|
12
|
+
key: string;
|
|
13
|
+
searchParams: URLSearchParams;
|
|
14
|
+
}) => TValue;
|
|
15
|
+
serialize?: (value: TValue, context: {
|
|
16
|
+
key: string;
|
|
17
|
+
}) => string | string[] | null | undefined;
|
|
18
|
+
};
|
|
19
|
+
type ParamCodecs<TParams extends Record<string, unknown>> = Partial<{
|
|
20
|
+
[K in keyof TParams]: ParamCodec<TParams[K]>;
|
|
21
|
+
}>;
|
|
22
|
+
type ParamKey<TParams extends Record<string, unknown>> = Extract<keyof TParams, string>;
|
|
23
|
+
type PaginationStrategy<TParams extends Record<string, unknown>> = {
|
|
24
|
+
mode: 'page';
|
|
25
|
+
pageKey?: ParamKey<TParams>;
|
|
26
|
+
pageSizeKey?: ParamKey<TParams>;
|
|
27
|
+
} | {
|
|
28
|
+
mode: 'offset';
|
|
29
|
+
offsetKey?: ParamKey<TParams>;
|
|
30
|
+
limitKey?: ParamKey<TParams>;
|
|
31
|
+
} | {
|
|
32
|
+
mode: 'cursor';
|
|
33
|
+
cursorKey?: ParamKey<TParams>;
|
|
34
|
+
};
|
|
35
|
+
type ResetOnChangeRules<TParams extends Record<string, unknown>> = Partial<Record<ParamKey<TParams>, Array<ParamKey<TParams>>>>;
|
|
36
|
+
type UnknownParamsPolicy = 'drop' | 'preserve';
|
|
37
|
+
type HistoryMode = 'push' | 'replace';
|
|
38
|
+
type OnChangeEvent<TParams extends Record<string, unknown>> = {
|
|
39
|
+
key: keyof TParams;
|
|
40
|
+
previousValue: unknown;
|
|
41
|
+
currentValue: unknown;
|
|
42
|
+
};
|
|
43
|
+
type OnChangeCallback<TParams extends Record<string, unknown>> = ((event: OnChangeEvent<TParams>) => void) | (() => void);
|
|
44
|
+
/**
|
|
45
|
+
* Interface for the configuration object that the hook receives
|
|
46
|
+
*/
|
|
47
|
+
interface UseMagicSearchParamsOptions<M extends Record<string, unknown>, O extends Record<string, unknown>> {
|
|
48
|
+
mandatory: M;
|
|
49
|
+
optional?: O;
|
|
50
|
+
defaultParams?: Partial<MergeParams<M, O>>;
|
|
51
|
+
forceParams?: Partial<MergeParams<M, O>>;
|
|
52
|
+
arraySerialization?: 'csv' | 'repeat' | 'brackets';
|
|
53
|
+
omitParamsByValues?: Array<'all' | 'default' | 'unknown' | 'none' | 'void'>;
|
|
54
|
+
codecs?: ParamCodecs<MergeParams<M, O>>;
|
|
55
|
+
historyMode?: HistoryMode;
|
|
56
|
+
resetOnChange?: ResetOnChangeRules<MergeParams<M, O>>;
|
|
57
|
+
paginationStrategy?: PaginationStrategy<MergeParams<M, O>>;
|
|
58
|
+
unknownParamsPolicy?: UnknownParamsPolicy;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
Generic hook to handle search parameters in the URL
|
|
62
|
+
@param mandatory - Mandatory parameters (e.g., page=1, page_size=10, etc.)
|
|
63
|
+
@param optional - Optional parameters (e.g., order, search, etc.)
|
|
64
|
+
@param defaultParams - Default parameters sent in the URL on initialization
|
|
65
|
+
@param forceParams - Parameters forced into the URL regardless of user input
|
|
66
|
+
@param omitParamsByValues - Parameters omitted if they have specific values
|
|
67
|
+
*/
|
|
68
|
+
declare const useMagicSearchParams: <M extends Record<string, unknown> & CommonParams, O extends Record<string, unknown>>({ mandatory, optional, defaultParams, arraySerialization, forceParams, omitParamsByValues, codecs, historyMode, resetOnChange, paginationStrategy, unknownParamsPolicy }: UseMagicSearchParamsOptions<M, O>) => {
|
|
69
|
+
searchParams: URLSearchParams;
|
|
70
|
+
updateParams: (input?: {
|
|
71
|
+
newParams?: Partial<MergeParams<M, O>> | ((current: MergeParams<M, O>) => Partial<MergeParams<M, O>>);
|
|
72
|
+
keepParams?: Partial<Record<Extract<keyof M, string> | Extract<keyof O, string>, boolean>>;
|
|
73
|
+
historyMode?: HistoryMode;
|
|
74
|
+
} | ((current: MergeParams<M, O>) => {
|
|
75
|
+
newParams?: Partial<MergeParams<M, O>> | ((current: MergeParams<M, O>) => Partial<MergeParams<M, O>>);
|
|
76
|
+
keepParams?: Partial<Record<Extract<keyof M, string> | Extract<keyof O, string>, boolean>>;
|
|
77
|
+
historyMode?: HistoryMode;
|
|
78
|
+
} | Partial<MergeParams<M, O>>)) => void;
|
|
79
|
+
clearParams: ({ keepMandatoryParams, historyMode: historyModeOverride }?: {
|
|
80
|
+
keepMandatoryParams?: boolean;
|
|
81
|
+
historyMode?: HistoryMode;
|
|
82
|
+
}) => void;
|
|
83
|
+
getParams: ({ convert }?: {
|
|
84
|
+
convert?: boolean | undefined;
|
|
85
|
+
}) => MergeParams<M, O>;
|
|
86
|
+
getParam: <K extends Extract<keyof M, string> | Extract<keyof O, string>, T extends boolean = true>(key: K, options?: {
|
|
87
|
+
convert: T;
|
|
88
|
+
}) => T extends true ? MergeParams<M, O>[K] : string;
|
|
89
|
+
onChange: (paramName: Extract<keyof M, string> | Extract<keyof O, string>, callbacks: Array<OnChangeCallback<MergeParams<M, O>>>) => () => void;
|
|
90
|
+
pagination: {
|
|
91
|
+
mode: "page" | "offset" | "cursor";
|
|
92
|
+
next: (cursor?: string) => void;
|
|
93
|
+
prev: () => void;
|
|
94
|
+
reset: () => void;
|
|
95
|
+
setCursor: (cursor: string | null | undefined) => void;
|
|
96
|
+
};
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
export { type HistoryMode, type OnChangeEvent, type PaginationStrategy, type ParamCodec, type ResetOnChangeRules, type UnknownParamsPolicy, type UseMagicSearchParamsOptions, useMagicSearchParams };
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1 @@
|
|
|
1
|
-
|
|
2
|
-
'use strict'
|
|
3
|
-
|
|
4
|
-
if (process.env.NODE_ENV === 'production') {
|
|
5
|
-
module.exports = require('./react-magic-search-params.cjs.production.min.js')
|
|
6
|
-
} else {
|
|
7
|
-
module.exports = require('./react-magic-search-params.cjs.development.js')
|
|
8
|
-
}
|
|
1
|
+
import{useSearchParams as ie}from"react-router-dom";import{useMemo as N,useEffect as Q,useRef as Y,useCallback as k}from"react";var ue=({mandatory:f={},optional:V={},defaultParams:g={},arraySerialization:l="csv",forceParams:d={},omitParamsByValues:q=[],codecs:F={},historyMode:E="push",resetOnChange:G={},paginationStrategy:p,unknownParamsPolicy:R="drop"})=>{let[i,L]=ie(),j=Y({}),U=Y({}),I=k((e,r)=>{L(e,{replace:(r??E)==="replace"})},[L,E]),m=N(()=>({...f,...V}),[f,V]),J=N(()=>Array.from(Object.keys(m)),[m]),A=k(e=>Object.prototype.hasOwnProperty.call(m,e),[m]),X=e=>!Array.isArray(m[e])||l==="csv"?i.get(e):l==="repeat"?i.getAll(e):i.getAll(`${e}[]`),H=k(()=>{if(R==="drop")return[];let e=[];for(let[r,a]of i.entries()){let s=r.endsWith("[]")?r.replace("[]",""):r;A(s)||e.push([r,a])}return e},[R,i,A]),_=k(e=>{if(R==="drop")return e;let r=new URLSearchParams(e.toString()),a=H();for(let[s,t]of a)r.append(s,t);return r},[R,H]),W=(e,r)=>Array.isArray(e)&&Array.isArray(r)?e.length!==r.length?!1:e.every((a,s)=>a===r[s]):e===r,C=N(()=>Object.keys(m).filter(e=>Array.isArray(m[e])),[m]),Z=(e,r)=>{let a={...e};return C.length===0||C.forEach(s=>{let t=[];switch(l){case"csv":{t=(i.get(s)||"").split(",").map(o=>o.trim()).filter(Boolean);break}case"repeat":{let n=i.getAll(s);t=n.length>0?n:[];break}case"brackets":{let n=i.getAll(`${s}[]`);t=n.length>0?n:[];break}default:t=(i.get(s)??"").split(",").map(o=>o.trim()).filter(Boolean)}if(r[s]!==void 0){let n=r[s],o=[];typeof n=="string"?o=t.includes(n)?t.filter(u=>u!==n):[...t,n]:Array.isArray(n)?o=Array.from(new Set([...n.map(String)])):o=t,a[s]=o}}),a},y=e=>{let r=new URLSearchParams,a=Object.keys(e);for(let s of a){let t=F[s];if(t?.serialize){let n=t.serialize(e[s],{key:s});if(n==null)continue;if(Array.isArray(n))if(Array.isArray(m[s]))if(l==="csv")r.set(s,n.join(","));else if(l==="repeat")for(let o of n)r.append(s,String(o));else for(let o of n)r.append(`${s}[]`,String(o));else n.length>0&&r.set(s,String(n[0]));else r.set(s,String(n));continue}if(Array.isArray(m[s])){let n=e[s];switch(l){case"csv":{r.set(s,n.join(","));break}case"repeat":{for(let o of n)r.append(s,String(o));break}case"brackets":{for(let o of n)r.append(`${s}[]`,String(o));break}default:r.set(s,n.join(","))}}else r.set(s,String(e[s]))}return r},w=(e,r)=>Object.prototype.hasOwnProperty.call(f,e)?f[e]:Object.prototype.hasOwnProperty.call(g,e)?g[e]:r,$=({paramsForced:e,compareParams:r})=>Object.entries(e).every(([s,t])=>r[s]===t),T=e=>{let r=X(e),a=F[e];if(a?.parse)return a.parse(r,{key:e,searchParams:i});if(typeof m[e]=="number"){let s=Number.parseInt(String(r??""),10);if(Number.isNaN(s)){let t=w(e,0);return typeof t=="number"?t:0}return s}return typeof m[e]=="boolean"?String(r)==="true":Array.isArray(m[e])?l==="csv"?String(r??"").split(",").filter(Boolean):Array.isArray(r)?r:r?[r]:[]:Array.isArray(r)?r[0]??"":r??""},B=(e,r)=>{if(Array.isArray(m[e])){if(l==="brackets"){let t=i.getAll(`${e}[]`),n=y({[e]:t}).toString();return decodeURIComponent(n)}if(l==="csv"){let t=i.getAll(e),n=y({[e]:t}).toString();return decodeURIComponent(n)}let s=i.getAll(e);return y({[e]:s}).toString()}return r[e]},z=e=>{let r={};for(let[a,s]of e.entries())if(a.endsWith("[]")){let t=a.replace("[]","");r[t]?r[t].push(s):r[t]=[s]}else r[a]?Array.isArray(r[a])?r[a].push(s):r[a]=[r[a],s]:r[a]=s;return r},v=N(()=>l==="brackets"?z(i):Object.fromEntries(i.entries()),[i,l]),h=({convert:e=!0}={})=>Object.keys(v).reduce((a,s)=>{if(Object.prototype.hasOwnProperty.call(m,s)){let t=l==="brackets"?s.replace("[]",""):s;a[t]=e===!0?T(t):B(s,v)}return a},{}),O=(e,r)=>{let a=String(e);return r?.convert!==!1?T(a):B(a,v)},ee=e=>e==null||typeof e!="object"?!1:Object.prototype.hasOwnProperty.call(e,"newParams")||Object.prototype.hasOwnProperty.call(e,"keepParams")||Object.prototype.hasOwnProperty.call(e,"historyMode"),re=e=>{let r=h({convert:!0});if(typeof e=="function"){let a=e(r);return ee(a)?{newParams:typeof a.newParams=="function"?a.newParams(r):a.newParams??{},keepParams:a.keepParams??{},historyMode:a.historyMode}:{newParams:a,keepParams:{},historyMode:void 0}}return e?{newParams:typeof e.newParams=="function"?e.newParams(r):e.newParams??{},keepParams:e.keepParams??{},historyMode:e.historyMode}:{newParams:{},keepParams:{},historyMode:void 0}},se=({currentParams:e,newParams:r,keepParams:a})=>{let s={...r},t={...a};for(let[n,o]of Object.entries(G))if(!(!o||o.length===0||!Object.prototype.hasOwnProperty.call(s,n)||W(s[n],e[n]))){for(let c of o)if(!Object.prototype.hasOwnProperty.call(d,c)){if(Object.prototype.hasOwnProperty.call(f,c)){s[c]=f[c],delete t[c];continue}if(Object.prototype.hasOwnProperty.call(g,c)){s[c]=g[c],delete t[c];continue}delete s[c],t[c]=!1}}return{newParams:s,keepParams:t}},ae=(e,r)=>{let a=h(),s=Object.entries(e).filter(([o])=>!Array.isArray(m[o])),t=Object.assign({...a,...Object.fromEntries(s)},d),n=Object.keys(t).reduce((o,u)=>{if(Object.prototype.hasOwnProperty.call(r,u)&&r[u]===!1)return o;let c=t[u];return c!=null&&c!==""&&!q.includes(c)&&(o[u]=c),o},{});return{...f,...n}},te=e=>J.reduce((a,s)=>(Object.prototype.hasOwnProperty.call(e,s)&&(a[s]=e[s]),a),{}),ne=()=>{let e=C.length>0,r=h({convert:e});return Object.keys(r).reduce((s,t)=>(Object.prototype.hasOwnProperty.call(f,t)&&(s[t]=r[t]),s),{})},D=({keepMandatoryParams:e=!0,historyMode:r}={})=>{let a=y({...f,...e&&{...ne()},...d}),s=_(a);I(s,r)},P=e=>{let r=re(e),a=h({convert:!0}),s=se({currentParams:a,newParams:r.newParams,keepParams:r.keepParams}),t=s.newParams,n=s.keepParams;if(Object.keys(t).length===0&&Object.keys(n).length===0){D({historyMode:r.historyMode});return}let o=ae(t,n),u=Z(o,t),c=te(u),M=y(c),x=_(M);I(x,r.historyMode)},K=p?.mode==="page"?p:void 0,b=p?.mode==="offset"?p:void 0,S=p?.mode==="cursor"?p:void 0,oe={mode:p?.mode??"page",next:e=>{let r=p?.mode??"page";if(r==="cursor"){let n=S?.cursorKey??"cursor";typeof e=="string"&&P({newParams:{[n]:e}});return}if(r==="offset"){let n=b?.offsetKey??"offset",o=b?.limitKey??"limit",u=Number(O(n,{convert:!0})??0),c=Number(O(o,{convert:!0})??w(String(o),10)),M=Number.isFinite(u)?u:0,x=Number.isFinite(c)&&c>0?c:10;P({newParams:{[n]:M+x}});return}let a=K?K.pageKey??"page":"page",s=Number(O(a,{convert:!0})??w(String(a),1)),t=Number.isFinite(s)&&s>0?s:1;P({newParams:{[a]:t+1}})},prev:()=>{let e=p?.mode??"page";if(e==="cursor"){let t=S?.cursorKey??"cursor";P({keepParams:{[t]:!1}});return}if(e==="offset"){let t=b?.offsetKey??"offset",n=b?.limitKey??"limit",o=Number(O(t,{convert:!0})??0),u=Number(O(n,{convert:!0})??w(String(n),10)),c=Number.isFinite(o)?o:0,M=Number.isFinite(u)&&u>0?u:10;P({newParams:{[t]:Math.max(0,c-M)}});return}let r=K?K.pageKey??"page":"page",a=Number(O(r,{convert:!0})??w(String(r),1)),s=Number.isFinite(a)&&a>0?a:1;P({newParams:{[r]:Math.max(1,s-1)}})},reset:()=>{let e=p?.mode??"page";if(e==="cursor"){let s=S?.cursorKey??"cursor";P({keepParams:{[s]:!1}});return}if(e==="offset"){let s=b?.offsetKey??"offset",t=Number(w(String(s),0));P({newParams:{[s]:Number.isFinite(t)?t:0}});return}let r=K?K.pageKey??"page":"page",a=Number(w(String(r),1));P({newParams:{[r]:Number.isFinite(a)&&a>0?a:1}})},setCursor:e=>{let a=(p?.mode??"page")==="cursor"?S?.cursorKey??"cursor":"cursor";if(e==null||e===""){P({keepParams:{[a]:!1}});return}P({newParams:{[a]:e}})}},ce=k((e,r)=>{let a=String(e);return j.current[a]=r,()=>{delete j.current[a],delete U.current[a]}},[]);return Q(()=>{for(let[e,r]of Object.entries(j.current)){let a=A(e)?T(e):i.get(e),s=U.current[e]??null;if(!W(a,s))for(let t of r)t({key:e,previousValue:s,currentValue:a});U.current[e]=a}},[v,A,i]),Q(()=>{let e=Object.keys(g),r=Object.keys(d);if(e.length===0&&r.length===0)return;function a(){let s=y(g).toString(),t=h(),n=y(t).toString();if(!$({paramsForced:d,compareParams:t})){P({newParams:{...g,...d}});return}let u=$({paramsForced:d,compareParams:g});if(e.length>0&&u){if(s===n)return;P({newParams:g})}}a()},[]),{searchParams:i,updateParams:P,clearParams:D,getParams:h,getParam:O,onChange:ce,pagination:oe}};export{ue as useMagicSearchParams};
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"repository": {
|
|
4
4
|
"type": "git",
|
|
5
5
|
"url": "https://github.com/Gabriel117343/react-magic-search-params"
|
|
6
|
-
|
|
6
|
+
},
|
|
7
7
|
"homepage": "https://react-magic-search-params.netlify.app",
|
|
8
8
|
"keywords": [
|
|
9
9
|
"react",
|
|
@@ -14,31 +14,39 @@
|
|
|
14
14
|
"autocomplete",
|
|
15
15
|
"use-url-search-params",
|
|
16
16
|
"use-search-params",
|
|
17
|
-
"use-query-parameters"
|
|
18
|
-
|
|
17
|
+
"use-query-parameters",
|
|
18
|
+
"query-parameters"
|
|
19
19
|
],
|
|
20
|
-
"version": "
|
|
20
|
+
"version": "2.0.1",
|
|
21
|
+
"private": false,
|
|
21
22
|
"license": "MIT",
|
|
22
|
-
"main": "dist/index.
|
|
23
|
+
"main": "dist/index.cjs",
|
|
24
|
+
"module": "dist/index.js",
|
|
25
|
+
"types": "dist/index.d.ts",
|
|
23
26
|
"typings": "dist/index.d.ts",
|
|
27
|
+
"sideEffects": false,
|
|
24
28
|
"files": [
|
|
25
|
-
"dist"
|
|
26
|
-
"src"
|
|
29
|
+
"dist"
|
|
27
30
|
],
|
|
28
31
|
"engines": {
|
|
29
|
-
"node": ">=
|
|
32
|
+
"node": ">=18"
|
|
30
33
|
},
|
|
31
34
|
"scripts": {
|
|
32
|
-
"start": "
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
35
|
+
"start": "tsup --watch",
|
|
36
|
+
"dev": "tsup --watch",
|
|
37
|
+
"typecheck": "tsc --noEmit",
|
|
38
|
+
"build": "tsup",
|
|
39
|
+
"test": "vitest run --environment jsdom",
|
|
40
|
+
"test:watch": "vitest --environment jsdom",
|
|
41
|
+
"lint": "tsc --noEmit",
|
|
42
|
+
"prepare": "tsup",
|
|
37
43
|
"size": "size-limit",
|
|
38
|
-
"analyze": "size-limit --why"
|
|
44
|
+
"analyze": "size-limit --why",
|
|
45
|
+
"prepack": "node -e \"const fs=require('fs');fs.copyFileSync('README.md','.README.repo.md');fs.copyFileSync('README_NPM.md','README.md');\"",
|
|
46
|
+
"postpack": "node -e \"const fs=require('fs');if(fs.existsSync('.README.repo.md')){fs.copyFileSync('.README.repo.md','README.md');fs.unlinkSync('.README.repo.md');}\""
|
|
39
47
|
},
|
|
40
48
|
"peerDependencies": {
|
|
41
|
-
"react": ">=
|
|
49
|
+
"react": ">=18 <20",
|
|
42
50
|
"react-router-dom": ">=6"
|
|
43
51
|
},
|
|
44
52
|
"husky": {
|
|
@@ -54,36 +62,37 @@
|
|
|
54
62
|
},
|
|
55
63
|
"name": "react-magic-search-params",
|
|
56
64
|
"author": "Gabriel S.",
|
|
57
|
-
"module": "dist/react-magic-search-params.esm.js",
|
|
58
65
|
"size-limit": [
|
|
59
66
|
{
|
|
60
|
-
"path": "dist/
|
|
67
|
+
"path": "dist/index.cjs",
|
|
61
68
|
"limit": "10 KB"
|
|
62
69
|
},
|
|
63
70
|
{
|
|
64
|
-
"path": "dist/
|
|
71
|
+
"path": "dist/index.js",
|
|
65
72
|
"limit": "10 KB"
|
|
66
73
|
}
|
|
67
74
|
],
|
|
68
75
|
"devDependencies": {
|
|
69
76
|
"@size-limit/preset-small-lib": "^11.2.0",
|
|
70
|
-
"@types/react": "^19.
|
|
71
|
-
"@types/react-dom": "^19.
|
|
77
|
+
"@types/react": "^19.2.2",
|
|
78
|
+
"@types/react-dom": "^19.2.2",
|
|
79
|
+
"@testing-library/react": "^16.3.0",
|
|
72
80
|
"husky": "^9.1.7",
|
|
73
|
-
"
|
|
74
|
-
"react
|
|
81
|
+
"jsdom": "^26.1.0",
|
|
82
|
+
"react": "^19.2.0",
|
|
83
|
+
"react-dom": "^19.2.0",
|
|
84
|
+
"react-router-dom": "^7.0.0",
|
|
75
85
|
"size-limit": "^11.2.0",
|
|
76
|
-
"
|
|
86
|
+
"tsup": "^8.5.0",
|
|
77
87
|
"tslib": "^2.8.1",
|
|
78
|
-
"typescript": "^
|
|
79
|
-
"vitest": "^3.
|
|
80
|
-
"@testing-library/react": "^16.2.0"
|
|
88
|
+
"typescript": "^5.8.3",
|
|
89
|
+
"vitest": "^3.2.4"
|
|
81
90
|
},
|
|
82
91
|
"exports": {
|
|
83
92
|
".": {
|
|
84
|
-
"
|
|
85
|
-
"
|
|
86
|
-
"
|
|
93
|
+
"types": "./dist/index.d.ts",
|
|
94
|
+
"import": "./dist/index.js",
|
|
95
|
+
"require": "./dist/index.cjs"
|
|
87
96
|
}
|
|
88
97
|
}
|
|
89
|
-
}
|
|
98
|
+
}
|