{"version":3,"file":"searchMiddleware.cjs","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,cAAA,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,cAAA,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,cAAA,UAAU,OAAO,MAAM,KAAK,QAAQ,IAAI,SAAS,CAAC,OAGnD,EAAE,OAAO,SACP,OAAO,UACN,KAAK,WAAW,IAAI,SAAS,KAC7B,cAAA,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,cAAA,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"}