@tanstack/router-core 1.171.10 → 1.171.11
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/dist/cjs/route.cjs.map +1 -1
- package/dist/cjs/route.d.cts +6 -0
- package/dist/cjs/router.cjs +16 -10
- package/dist/cjs/router.cjs.map +1 -1
- package/dist/cjs/searchMiddleware.cjs +22 -20
- package/dist/cjs/searchMiddleware.cjs.map +1 -1
- package/dist/cjs/utils.cjs +0 -1
- package/dist/esm/route.d.ts +6 -0
- package/dist/esm/route.js.map +1 -1
- package/dist/esm/router.js +16 -10
- package/dist/esm/router.js.map +1 -1
- package/dist/esm/searchMiddleware.js +23 -21
- package/dist/esm/searchMiddleware.js.map +1 -1
- package/dist/esm/utils.js +1 -1
- package/package.json +1 -1
- package/src/route.ts +7 -0
- package/src/router.ts +18 -21
- package/src/searchMiddleware.ts +60 -39
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { deepEqual } from "./utils.js";
|
|
2
2
|
//#region src/searchMiddleware.ts
|
|
3
3
|
/**
|
|
4
4
|
* Retain specified search params across navigations.
|
|
@@ -12,33 +12,26 @@ import { createNull, deepEqual } from "./utils.js";
|
|
|
12
12
|
*/
|
|
13
13
|
function retainSearchParams(keys) {
|
|
14
14
|
return ({ search, next }) => {
|
|
15
|
-
const
|
|
16
|
-
const defaultKeys = validations.length ? getValidationDefaultKeys(search, resultSearch, validations) : void 0;
|
|
15
|
+
const { search: resultSearch, meta } = next(search, true);
|
|
17
16
|
if (keys === true) {
|
|
18
17
|
const copy = {
|
|
19
18
|
...search,
|
|
20
19
|
...resultSearch
|
|
21
20
|
};
|
|
22
|
-
|
|
21
|
+
const removed = meta.removed;
|
|
22
|
+
for (const key of removed?.keys() || []) if (deepEqual(search[key], removed.get(key))) delete copy[key];
|
|
23
|
+
for (const key of meta.removedAny || []) delete copy[key];
|
|
24
|
+
for (const key of meta.defaulted?.keys() || []) if (key in search && !meta.removedAny?.has(key) && !(meta.removed?.has(key) && deepEqual(search[key], meta.removed.get(key)))) copy[key] = search[key];
|
|
23
25
|
return copy;
|
|
24
26
|
}
|
|
25
27
|
const copy = { ...resultSearch };
|
|
26
|
-
for (const key of keys)
|
|
28
|
+
for (const key of keys) {
|
|
29
|
+
const stringKey = key;
|
|
30
|
+
if (!(meta.removedAny?.has(stringKey) || meta.removed?.has(stringKey) && deepEqual(search[key], meta.removed.get(stringKey))) && (!(key in copy) || key in search && meta.defaulted?.has(stringKey) && deepEqual(copy[key], meta.defaulted.get(stringKey)))) copy[key] = search[key];
|
|
31
|
+
}
|
|
27
32
|
return copy;
|
|
28
33
|
};
|
|
29
34
|
}
|
|
30
|
-
function getValidationDefaultKeys(search, resultSearch, validations) {
|
|
31
|
-
let defaultKeys;
|
|
32
|
-
for (let i = 0; i < validations.length; i += 2) {
|
|
33
|
-
const baseSearch = validations[i];
|
|
34
|
-
const validatedSearch = validations[i + 1];
|
|
35
|
-
for (const key in validatedSearch) if (key in search && !(key in baseSearch) && resultSearch[key] === validatedSearch[key]) {
|
|
36
|
-
const target = defaultKeys || (defaultKeys = createNull());
|
|
37
|
-
target[key] = true;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
return defaultKeys;
|
|
41
|
-
}
|
|
42
35
|
/**
|
|
43
36
|
* Remove optional or default-valued search params from navigations.
|
|
44
37
|
*
|
|
@@ -50,17 +43,26 @@ function getValidationDefaultKeys(search, resultSearch, validations) {
|
|
|
50
43
|
* @link https://tanstack.com/router/latest/docs/framework/react/api/router/stripSearchParamsFunction
|
|
51
44
|
*/
|
|
52
45
|
function stripSearchParams(input) {
|
|
53
|
-
return ({ search, next }) => {
|
|
54
|
-
if (input === true)
|
|
46
|
+
return (({ search, next, meta }) => {
|
|
47
|
+
if (input === true) {
|
|
48
|
+
Object.keys(search).forEach((key) => {
|
|
49
|
+
if (meta) (meta.removedAny ||= /* @__PURE__ */ new Set()).add(key);
|
|
50
|
+
});
|
|
51
|
+
return {};
|
|
52
|
+
}
|
|
55
53
|
const result = { ...next(search) };
|
|
56
54
|
if (Array.isArray(input)) input.forEach((key) => {
|
|
57
55
|
delete result[key];
|
|
56
|
+
if (meta) (meta.removedAny ||= /* @__PURE__ */ new Set()).add(key);
|
|
58
57
|
});
|
|
59
58
|
else Object.entries(input).forEach(([key, value]) => {
|
|
60
|
-
if (deepEqual(result[key], value))
|
|
59
|
+
if (deepEqual(result[key], value)) {
|
|
60
|
+
delete result[key];
|
|
61
|
+
if (meta) (meta.removed ||= /* @__PURE__ */ new Map()).set(key, value);
|
|
62
|
+
}
|
|
61
63
|
});
|
|
62
64
|
return result;
|
|
63
|
-
};
|
|
65
|
+
});
|
|
64
66
|
}
|
|
65
67
|
//#endregion
|
|
66
68
|
export { retainSearchParams, stripSearchParams };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"searchMiddleware.js","names":[],"sources":["../../src/searchMiddleware.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"searchMiddleware.js","names":[],"sources":["../../src/searchMiddleware.ts"],"sourcesContent":["import { deepEqual } from './utils'\nimport type { NoInfer, PickOptional } from './utils'\nimport type {\n SearchMiddleware,\n SearchMiddlewareContext,\n SearchMiddlewareMeta,\n} from './route'\nimport type { IsRequiredParams } from './link'\n\ntype SearchMiddlewareNextWithMeta<TSearchSchema> = (\n newSearch: TSearchSchema,\n collectMeta: true,\n) => { search: TSearchSchema; meta: SearchMiddlewareMeta }\n\n/**\n * Retain specified search params across navigations.\n *\n * If `keys` is `true`, retain all current params. Otherwise, copy only the\n * listed keys from the current search into the next search.\n *\n * @param keys `true` to retain all, or a list of keys to retain.\n * @returns A search middleware suitable for route `search.middlewares`.\n * @link https://tanstack.com/router/latest/docs/framework/react/api/router/retainSearchParamsFunction\n */\nexport function retainSearchParams<TSearchSchema extends object>(\n keys: Array<keyof TSearchSchema> | true,\n): SearchMiddleware<TSearchSchema> {\n return ({ search, next }) => {\n const { search: resultSearch, meta } = (\n next as unknown as SearchMiddlewareNextWithMeta<TSearchSchema>\n )(search, true)\n\n if (keys === true) {\n const copy = { ...search, ...resultSearch }\n const removed = meta.removed\n for (const key of removed?.keys() || []) {\n if (deepEqual(search[key as keyof TSearchSchema], removed!.get(key))) {\n delete copy[key as keyof TSearchSchema]\n }\n }\n for (const key of meta.removedAny || []) {\n delete copy[key as keyof TSearchSchema]\n }\n for (const key of meta.defaulted?.keys() || []) {\n if (\n key in search &&\n !meta.removedAny?.has(key) &&\n !(\n meta.removed?.has(key) &&\n deepEqual(search[key as keyof TSearchSchema], meta.removed.get(key))\n )\n ) {\n copy[key as keyof TSearchSchema] = search[key as keyof TSearchSchema]\n }\n }\n return copy\n }\n\n const copy = { ...resultSearch }\n // add missing keys from search to copy\n for (const key of keys) {\n const stringKey = key as string\n const removed =\n meta.removedAny?.has(stringKey) ||\n (meta.removed?.has(stringKey) &&\n deepEqual(search[key], meta.removed.get(stringKey)))\n if (\n !removed &&\n (!(key in copy) ||\n (key in search &&\n meta.defaulted?.has(stringKey) &&\n deepEqual(copy[key], meta.defaulted.get(stringKey))))\n ) {\n copy[key] = search[key]\n }\n }\n return copy\n }\n}\n\n/**\n * Remove optional or default-valued search params from navigations.\n *\n * - Pass `true` (only if there are no required search params) to strip all.\n * - Pass an array to always remove those optional keys.\n * - Pass an object of default values; keys equal (deeply) to the defaults are removed.\n *\n * @returns A search middleware suitable for route `search.middlewares`.\n * @link https://tanstack.com/router/latest/docs/framework/react/api/router/stripSearchParamsFunction\n */\nexport function stripSearchParams<\n TSearchSchema,\n TOptionalProps = PickOptional<NoInfer<TSearchSchema>>,\n const TValues = Partial<NoInfer<TSearchSchema>> | Array<keyof TOptionalProps>,\n const TInput = IsRequiredParams<TSearchSchema> extends never\n ? TValues | true\n : TValues,\n>(input: NoInfer<TInput>): SearchMiddleware<TSearchSchema> {\n return (({ search, next, meta }: SearchMiddlewareContext<TSearchSchema>) => {\n if (input === true) {\n Object.keys(search as object).forEach((key) => {\n if (meta) {\n ;(meta.removedAny ||= new Set()).add(key)\n }\n })\n return {}\n }\n const nextResult = next(search)\n const result = { ...nextResult } as Record<string, unknown>\n if (Array.isArray(input)) {\n input.forEach((key) => {\n delete result[key as string]\n if (meta) {\n ;(meta.removedAny ||= new Set()).add(key as string)\n }\n })\n } else {\n Object.entries(input as Record<string, unknown>).forEach(\n ([key, value]) => {\n if (deepEqual(result[key], value)) {\n delete result[key]\n if (meta) {\n ;(meta.removed ||= new Map()).set(key, value)\n }\n }\n },\n )\n }\n return result as any\n }) as SearchMiddleware<TSearchSchema>\n}\n"],"mappings":";;;;;;;;;;;;AAwBA,SAAgB,mBACd,MACiC;CACjC,QAAQ,EAAE,QAAQ,WAAW;EAC3B,MAAM,EAAE,QAAQ,cAAc,SAC5B,KACA,QAAQ,IAAI;EAEd,IAAI,SAAS,MAAM;GACjB,MAAM,OAAO;IAAE,GAAG;IAAQ,GAAG;GAAa;GAC1C,MAAM,UAAU,KAAK;GACrB,KAAK,MAAM,OAAO,SAAS,KAAK,KAAK,CAAC,GACpC,IAAI,UAAU,OAAO,MAA6B,QAAS,IAAI,GAAG,CAAC,GACjE,OAAO,KAAK;GAGhB,KAAK,MAAM,OAAO,KAAK,cAAc,CAAC,GACpC,OAAO,KAAK;GAEd,KAAK,MAAM,OAAO,KAAK,WAAW,KAAK,KAAK,CAAC,GAC3C,IACE,OAAO,UACP,CAAC,KAAK,YAAY,IAAI,GAAG,KACzB,EACE,KAAK,SAAS,IAAI,GAAG,KACrB,UAAU,OAAO,MAA6B,KAAK,QAAQ,IAAI,GAAG,CAAC,IAGrE,KAAK,OAA8B,OAAO;GAG9C,OAAO;EACT;EAEA,MAAM,OAAO,EAAE,GAAG,aAAa;EAE/B,KAAK,MAAM,OAAO,MAAM;GACtB,MAAM,YAAY;GAKlB,IACE,EAJA,KAAK,YAAY,IAAI,SAAS,KAC7B,KAAK,SAAS,IAAI,SAAS,KAC1B,UAAU,OAAO,MAAM,KAAK,QAAQ,IAAI,SAAS,CAAC,OAGnD,EAAE,OAAO,SACP,OAAO,UACN,KAAK,WAAW,IAAI,SAAS,KAC7B,UAAU,KAAK,MAAM,KAAK,UAAU,IAAI,SAAS,CAAC,IAEtD,KAAK,OAAO,OAAO;EAEvB;EACA,OAAO;CACT;AACF;;;;;;;;;;;AAYA,SAAgB,kBAOd,OAAyD;CACzD,SAAS,EAAE,QAAQ,MAAM,WAAmD;EAC1E,IAAI,UAAU,MAAM;GAClB,OAAO,KAAK,MAAgB,EAAE,SAAS,QAAQ;IAC7C,IAAI,MACD,CAAC,KAAK,+BAAe,IAAI,IAAI,GAAG,IAAI,GAAG;GAE5C,CAAC;GACD,OAAO,CAAC;EACV;EAEA,MAAM,SAAS,EAAE,GADE,KAAK,MACJ,EAAW;EAC/B,IAAI,MAAM,QAAQ,KAAK,GACrB,MAAM,SAAS,QAAQ;GACrB,OAAO,OAAO;GACd,IAAI,MACD,CAAC,KAAK,+BAAe,IAAI,IAAI,GAAG,IAAI,GAAa;EAEtD,CAAC;OAED,OAAO,QAAQ,KAAgC,EAAE,SAC9C,CAAC,KAAK,WAAW;GAChB,IAAI,UAAU,OAAO,MAAM,KAAK,GAAG;IACjC,OAAO,OAAO;IACd,IAAI,MACD,CAAC,KAAK,4BAAY,IAAI,IAAI,GAAG,IAAI,KAAK,KAAK;GAEhD;EACF,CACF;EAEF,OAAO;CACT;AACF"}
|
package/dist/esm/utils.js
CHANGED
|
@@ -321,6 +321,6 @@ function arraysEqual(a, b) {
|
|
|
321
321
|
return true;
|
|
322
322
|
}
|
|
323
323
|
//#endregion
|
|
324
|
-
export { DEFAULT_PROTOCOL_ALLOWLIST, arraysEqual, buildDevStylesUrl, createControlledPromise,
|
|
324
|
+
export { DEFAULT_PROTOCOL_ALLOWLIST, arraysEqual, buildDevStylesUrl, createControlledPromise, decodePath, deepEqual, encodePathLikeUrl, escapeHtml, findLast, functionalUpdate, hasKeys, isDangerousProtocol, isModuleNotFoundError, isPlainArray, isPlainObject, isPromise, last, nullReplaceEqualDeep, replaceEqualDeep };
|
|
325
325
|
|
|
326
326
|
//# sourceMappingURL=utils.js.map
|
package/package.json
CHANGED
package/src/route.ts
CHANGED
|
@@ -74,9 +74,16 @@ export type RoutePathOptionsIntersection<TCustomId, TPath> = {
|
|
|
74
74
|
|
|
75
75
|
export type SearchFilter<TInput, TResult = TInput> = (prev: TInput) => TResult
|
|
76
76
|
|
|
77
|
+
export type SearchMiddlewareMeta = {
|
|
78
|
+
removed?: Map<string, unknown>
|
|
79
|
+
removedAny?: Set<string>
|
|
80
|
+
defaulted?: Map<string, unknown>
|
|
81
|
+
}
|
|
82
|
+
|
|
77
83
|
export type SearchMiddlewareContext<TSearchSchema> = {
|
|
78
84
|
search: TSearchSchema
|
|
79
85
|
next: (newSearch: TSearchSchema) => TSearchSchema
|
|
86
|
+
meta?: SearchMiddlewareMeta
|
|
80
87
|
}
|
|
81
88
|
|
|
82
89
|
export type SearchMiddleware<TSearchSchema> = (
|
package/src/router.ts
CHANGED
|
@@ -79,6 +79,7 @@ import type {
|
|
|
79
79
|
RouteLike,
|
|
80
80
|
RouteMask,
|
|
81
81
|
SearchMiddleware,
|
|
82
|
+
SearchMiddlewareMeta,
|
|
82
83
|
} from './route'
|
|
83
84
|
import type {
|
|
84
85
|
FullSearchSchema,
|
|
@@ -3123,8 +3124,6 @@ function buildMiddlewareChain(destRoutes: ReadonlyArray<AnyRoute>) {
|
|
|
3123
3124
|
let dest: BuildNextOptions
|
|
3124
3125
|
let includeValidateSearch: boolean | undefined
|
|
3125
3126
|
const middlewares = [] as Array<SearchMiddleware<any>>
|
|
3126
|
-
// Flat pairs: [searchBeforeValidation, validatedSearch, ...]
|
|
3127
|
-
type ValidatedSearches = Array<Record<PropertyKey, unknown>>
|
|
3128
3127
|
|
|
3129
3128
|
for (const route of destRoutes) {
|
|
3130
3129
|
const routeOptions = route.options
|
|
@@ -3157,17 +3156,18 @@ function buildMiddlewareChain(destRoutes: ReadonlyArray<AnyRoute>) {
|
|
|
3157
3156
|
|
|
3158
3157
|
const routeValidateSearch = routeOptions.validateSearch
|
|
3159
3158
|
if (routeValidateSearch) {
|
|
3160
|
-
const validate: SearchMiddleware<any> = (
|
|
3161
|
-
{ search, next },
|
|
3162
|
-
validations?: ValidatedSearches,
|
|
3163
|
-
) => {
|
|
3159
|
+
const validate: SearchMiddleware<any> = ({ search, next, meta }) => {
|
|
3164
3160
|
const result = next(search)
|
|
3165
3161
|
if (includeValidateSearch) {
|
|
3166
3162
|
try {
|
|
3167
3163
|
const validated = validateSearch(routeValidateSearch, result) as any
|
|
3168
3164
|
|
|
3169
|
-
if (
|
|
3170
|
-
|
|
3165
|
+
if (meta && validated) {
|
|
3166
|
+
for (const key in validated) {
|
|
3167
|
+
if (!(key in result)) {
|
|
3168
|
+
;(meta.defaulted ||= new Map()).set(key, validated[key])
|
|
3169
|
+
}
|
|
3170
|
+
}
|
|
3171
3171
|
}
|
|
3172
3172
|
return { ...result, ...validated }
|
|
3173
3173
|
} catch {
|
|
@@ -3184,7 +3184,7 @@ function buildMiddlewareChain(destRoutes: ReadonlyArray<AnyRoute>) {
|
|
|
3184
3184
|
const applyNext = (
|
|
3185
3185
|
index: number,
|
|
3186
3186
|
currentSearch: any,
|
|
3187
|
-
|
|
3187
|
+
meta?: SearchMiddlewareMeta,
|
|
3188
3188
|
): any => {
|
|
3189
3189
|
// no more middlewares left, return the current search
|
|
3190
3190
|
if (index >= middlewares.length) {
|
|
@@ -3197,21 +3197,18 @@ function buildMiddlewareChain(destRoutes: ReadonlyArray<AnyRoute>) {
|
|
|
3197
3197
|
return functionalUpdate(dest.search, currentSearch)
|
|
3198
3198
|
}
|
|
3199
3199
|
|
|
3200
|
-
const next = (newSearch: any,
|
|
3201
|
-
if (
|
|
3202
|
-
const
|
|
3203
|
-
return
|
|
3204
|
-
applyNext(index + 1, newSearch,
|
|
3205
|
-
|
|
3206
|
-
|
|
3200
|
+
const next = (newSearch: any, collectMeta?: true): any => {
|
|
3201
|
+
if (collectMeta) {
|
|
3202
|
+
const nextMeta = meta || ({} as SearchMiddlewareMeta)
|
|
3203
|
+
return {
|
|
3204
|
+
search: applyNext(index + 1, newSearch, nextMeta),
|
|
3205
|
+
meta: nextMeta,
|
|
3206
|
+
}
|
|
3207
3207
|
}
|
|
3208
|
-
return applyNext(index + 1, newSearch,
|
|
3208
|
+
return applyNext(index + 1, newSearch, meta)
|
|
3209
3209
|
}
|
|
3210
3210
|
|
|
3211
|
-
return (middlewares[index]! as any)(
|
|
3212
|
-
{ search: currentSearch, next },
|
|
3213
|
-
validations,
|
|
3214
|
-
)
|
|
3211
|
+
return (middlewares[index]! as any)({ search: currentSearch, next, meta })
|
|
3215
3212
|
}
|
|
3216
3213
|
|
|
3217
3214
|
return function middleware(
|
package/src/searchMiddleware.ts
CHANGED
|
@@ -1,8 +1,17 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { deepEqual } from './utils'
|
|
2
2
|
import type { NoInfer, PickOptional } from './utils'
|
|
3
|
-
import type {
|
|
3
|
+
import type {
|
|
4
|
+
SearchMiddleware,
|
|
5
|
+
SearchMiddlewareContext,
|
|
6
|
+
SearchMiddlewareMeta,
|
|
7
|
+
} from './route'
|
|
4
8
|
import type { IsRequiredParams } from './link'
|
|
5
9
|
|
|
10
|
+
type SearchMiddlewareNextWithMeta<TSearchSchema> = (
|
|
11
|
+
newSearch: TSearchSchema,
|
|
12
|
+
collectMeta: true,
|
|
13
|
+
) => { search: TSearchSchema; meta: SearchMiddlewareMeta }
|
|
14
|
+
|
|
6
15
|
/**
|
|
7
16
|
* Retain specified search params across navigations.
|
|
8
17
|
*
|
|
@@ -17,18 +26,30 @@ export function retainSearchParams<TSearchSchema extends object>(
|
|
|
17
26
|
keys: Array<keyof TSearchSchema> | true,
|
|
18
27
|
): SearchMiddleware<TSearchSchema> {
|
|
19
28
|
return ({ search, next }) => {
|
|
20
|
-
const
|
|
21
|
-
TSearchSchema
|
|
22
|
-
|
|
23
|
-
]
|
|
24
|
-
const defaultKeys = validations.length
|
|
25
|
-
? getValidationDefaultKeys(search, resultSearch, validations)
|
|
26
|
-
: undefined
|
|
29
|
+
const { search: resultSearch, meta } = (
|
|
30
|
+
next as unknown as SearchMiddlewareNextWithMeta<TSearchSchema>
|
|
31
|
+
)(search, true)
|
|
27
32
|
|
|
28
33
|
if (keys === true) {
|
|
29
34
|
const copy = { ...search, ...resultSearch }
|
|
30
|
-
|
|
31
|
-
|
|
35
|
+
const removed = meta.removed
|
|
36
|
+
for (const key of removed?.keys() || []) {
|
|
37
|
+
if (deepEqual(search[key as keyof TSearchSchema], removed!.get(key))) {
|
|
38
|
+
delete copy[key as keyof TSearchSchema]
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
for (const key of meta.removedAny || []) {
|
|
42
|
+
delete copy[key as keyof TSearchSchema]
|
|
43
|
+
}
|
|
44
|
+
for (const key of meta.defaulted?.keys() || []) {
|
|
45
|
+
if (
|
|
46
|
+
key in search &&
|
|
47
|
+
!meta.removedAny?.has(key) &&
|
|
48
|
+
!(
|
|
49
|
+
meta.removed?.has(key) &&
|
|
50
|
+
deepEqual(search[key as keyof TSearchSchema], meta.removed.get(key))
|
|
51
|
+
)
|
|
52
|
+
) {
|
|
32
53
|
copy[key as keyof TSearchSchema] = search[key as keyof TSearchSchema]
|
|
33
54
|
}
|
|
34
55
|
}
|
|
@@ -38,35 +59,23 @@ export function retainSearchParams<TSearchSchema extends object>(
|
|
|
38
59
|
const copy = { ...resultSearch }
|
|
39
60
|
// add missing keys from search to copy
|
|
40
61
|
for (const key of keys) {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function getValidationDefaultKeys(
|
|
50
|
-
search: any,
|
|
51
|
-
resultSearch: any,
|
|
52
|
-
validations: Array<Record<PropertyKey, unknown>>,
|
|
53
|
-
) {
|
|
54
|
-
let defaultKeys: Record<PropertyKey, true> | undefined
|
|
55
|
-
for (let i = 0; i < validations.length; i += 2) {
|
|
56
|
-
const baseSearch = validations[i]!
|
|
57
|
-
const validatedSearch = validations[i + 1]!
|
|
58
|
-
for (const key in validatedSearch) {
|
|
62
|
+
const stringKey = key as string
|
|
63
|
+
const removed =
|
|
64
|
+
meta.removedAny?.has(stringKey) ||
|
|
65
|
+
(meta.removed?.has(stringKey) &&
|
|
66
|
+
deepEqual(search[key], meta.removed.get(stringKey)))
|
|
59
67
|
if (
|
|
60
|
-
|
|
61
|
-
!(key in
|
|
62
|
-
|
|
68
|
+
!removed &&
|
|
69
|
+
(!(key in copy) ||
|
|
70
|
+
(key in search &&
|
|
71
|
+
meta.defaulted?.has(stringKey) &&
|
|
72
|
+
deepEqual(copy[key], meta.defaulted.get(stringKey))))
|
|
63
73
|
) {
|
|
64
|
-
|
|
65
|
-
target[key] = true
|
|
74
|
+
copy[key] = search[key]
|
|
66
75
|
}
|
|
67
76
|
}
|
|
77
|
+
return copy
|
|
68
78
|
}
|
|
69
|
-
return defaultKeys
|
|
70
79
|
}
|
|
71
80
|
|
|
72
81
|
/**
|
|
@@ -87,24 +96,36 @@ export function stripSearchParams<
|
|
|
87
96
|
? TValues | true
|
|
88
97
|
: TValues,
|
|
89
98
|
>(input: NoInfer<TInput>): SearchMiddleware<TSearchSchema> {
|
|
90
|
-
return ({ search, next }) => {
|
|
99
|
+
return (({ search, next, meta }: SearchMiddlewareContext<TSearchSchema>) => {
|
|
91
100
|
if (input === true) {
|
|
101
|
+
Object.keys(search as object).forEach((key) => {
|
|
102
|
+
if (meta) {
|
|
103
|
+
;(meta.removedAny ||= new Set()).add(key)
|
|
104
|
+
}
|
|
105
|
+
})
|
|
92
106
|
return {}
|
|
93
107
|
}
|
|
94
|
-
const
|
|
108
|
+
const nextResult = next(search)
|
|
109
|
+
const result = { ...nextResult } as Record<string, unknown>
|
|
95
110
|
if (Array.isArray(input)) {
|
|
96
111
|
input.forEach((key) => {
|
|
97
|
-
delete result[key]
|
|
112
|
+
delete result[key as string]
|
|
113
|
+
if (meta) {
|
|
114
|
+
;(meta.removedAny ||= new Set()).add(key as string)
|
|
115
|
+
}
|
|
98
116
|
})
|
|
99
117
|
} else {
|
|
100
118
|
Object.entries(input as Record<string, unknown>).forEach(
|
|
101
119
|
([key, value]) => {
|
|
102
120
|
if (deepEqual(result[key], value)) {
|
|
103
121
|
delete result[key]
|
|
122
|
+
if (meta) {
|
|
123
|
+
;(meta.removed ||= new Map()).set(key, value)
|
|
124
|
+
}
|
|
104
125
|
}
|
|
105
126
|
},
|
|
106
127
|
)
|
|
107
128
|
}
|
|
108
129
|
return result as any
|
|
109
|
-
}
|
|
130
|
+
}) as SearchMiddleware<TSearchSchema>
|
|
110
131
|
}
|