{"version":3,"sources":["jsdelivr-header.js","/npm/src/index.ts","/npm/src/withDefault.ts","/npm/src/serialize.ts","/npm/src/params.ts","/npm/src/objectToSearchString.ts","/npm/src/updateLocation.ts","/npm/src/encodeQueryParams.ts","/npm/src/decodeQueryParams.ts","/npm/src/searchStringToObject.ts"],"names":[],"mappings":"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","file":"/npm/serialize-query-params@2.0.4/dist/index.cjs.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/serialize-query-params@2.0.4/dist/index.cjs.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","export { withDefault } from './withDefault';\n\nexport {\n  encodeDate,\n  decodeDate,\n  encodeDateTime,\n  decodeDateTime,\n  encodeBoolean,\n  decodeBoolean,\n  encodeNumber,\n  decodeNumber,\n  encodeString,\n  decodeString,\n  decodeEnum,\n  decodeArrayEnum,\n  decodeDelimitedArrayEnum,\n  encodeJson,\n  decodeJson,\n  encodeArray,\n  decodeArray,\n  encodeNumericArray,\n  decodeNumericArray,\n  encodeDelimitedArray,\n  decodeDelimitedArray,\n  encodeDelimitedNumericArray,\n  decodeDelimitedNumericArray,\n  encodeObject,\n  decodeObject,\n  encodeNumericObject,\n  decodeNumericObject,\n} from './serialize';\n\nexport {\n  StringParam,\n  NumberParam,\n  ObjectParam,\n  ArrayParam,\n  NumericArrayParam,\n  JsonParam,\n  DateParam,\n  DateTimeParam,\n  BooleanParam,\n  NumericObjectParam,\n  DelimitedArrayParam,\n  DelimitedNumericArrayParam,\n  createEnumParam,\n  createEnumArrayParam,\n  createEnumDelimitedArrayParam,\n} from './params';\n\nexport type {\n  EncodedQuery,\n  QueryParamConfig,\n  QueryParamConfigMap,\n  DecodedValueMap,\n  EncodedValueMap,\n  ToBeEncodedValueMap\n} from './types';\n\nexport {\n  updateLocation,\n  updateInLocation,\n  transformSearchStringJsonSafe,\n} from './updateLocation';\n\nexport { encodeQueryParams } from './encodeQueryParams';\nexport { decodeQueryParams } from './decodeQueryParams';\n\nexport { searchStringToObject } from './searchStringToObject';\nexport { objectToSearchString } from './objectToSearchString';\n","import { QueryParamConfig } from './types';\n\n/**\n * Wrap a given parameter with a default value when undefined or null (optionally, default includes null)\n * @param param QueryParamConfig - { encode, decode} to serialize a parameter\n * @param defaultValue A default value\n * @param includeNull\n */\nexport function withDefault<D, DefaultType extends D2, D2 = D>(\n  param: QueryParamConfig<D, D2>,\n  defaultValue: DefaultType,\n  includeNull?: false | undefined\n): QueryParamConfig<D, Exclude<D2, undefined> | DefaultType>;\nexport function withDefault<D, DefaultType extends D2, D2 = D>(\n  param: QueryParamConfig<D, D2>,\n  defaultValue: DefaultType,\n  includeNull?: true\n): QueryParamConfig<D, Exclude<D2, null | undefined> | DefaultType>;\nexport function withDefault<D, DefaultType extends D2, D2 = D>(\n  param: QueryParamConfig<D, D2>,\n  defaultValue: DefaultType,\n  includeNull: boolean = true\n): QueryParamConfig<D, any | DefaultType> {\n  const decodeWithDefault = (\n    ...args: Parameters<typeof param.decode>\n  ): Exclude<D2, null | undefined> | Exclude<D2, undefined> | DefaultType => {\n    const decodedValue = param.decode(...args);\n\n    if (decodedValue === undefined) {\n      return defaultValue;\n    }\n    if (includeNull) {\n      if (decodedValue === null) {\n        return defaultValue;\n      } else {\n        return decodedValue as Exclude<D2, undefined>;\n      }\n    }\n\n    return decodedValue as Exclude<D2, undefined | null>;\n  };\n\n  // note we add `default` into the param for other tools to introspect\n  return { ...param, default: defaultValue, decode: decodeWithDefault };\n}\nexport default withDefault;\n","import {EncodedValue} from \"./types\";\n\n/**\n * Interprets an encoded string and returns either the string or null/undefined if not available.\n * Ignores array inputs (takes just first element in array)\n * @param input encoded string\n */\nfunction getEncodedValue(\n  input: EncodedValue,\n  allowEmptyString?: boolean\n): string | null | undefined {\n  if (input == null) {\n    return input;\n  }\n  // '' or []\n  if (\n    input.length === 0 &&\n    (!allowEmptyString || (allowEmptyString && input !== ''))\n  ) {\n    return null;\n  }\n\n  const str = input instanceof Array ? input[0] : input;\n  if (str == null) {\n    return str;\n  }\n  if (!allowEmptyString && str === '') {\n    return null;\n  }\n\n  return str;\n}\n\n/**\n * Interprets an encoded string and return null/undefined or an array with\n * the encoded string contents\n * @param input encoded string\n */\nfunction getEncodedValueArray(\n  input: EncodedValue\n): (string | null)[] | null | undefined {\n  if (input == null) {\n    return input;\n  }\n\n  return input instanceof Array ? input : input === '' ? [] : [input];\n}\n\n/**\n * Encodes a date as a string in YYYY-MM-DD format.\n *\n * @param {Date} date\n * @return {String} the encoded date\n */\nexport function encodeDate(\n  date: Date | null | undefined\n): string | null | undefined {\n  if (date == null) {\n    return date;\n  }\n\n  const year = date.getFullYear();\n  const month = date.getMonth() + 1;\n  const day = date.getDate();\n\n  return `${year}-${month < 10 ? `0${month}` : month}-${\n    day < 10 ? `0${day}` : day\n  }`;\n}\n\n/**\n * Converts a date in the format 'YYYY-mm-dd...' into a proper date, because\n * new Date() does not do that correctly. The date can be as complete or incomplete\n * as necessary (aka, '2015', '2015-10', '2015-10-01').\n * It will not work for dates that have times included in them.\n *\n * If an array is provided, only the first entry is used.\n *\n * @param  {String} input String date form like '2015-10-01'\n * @return {Date} parsed date\n */\nexport function decodeDate(\n  input: EncodedValue\n): Date | null | undefined {\n  const dateString = getEncodedValue(input);\n  if (dateString == null) return dateString;\n\n  const parts = dateString.split('-') as any;\n  // may only be a year so won't even have a month\n  if (parts[1] != null) {\n    parts[1] -= 1; // Note: months are 0-based\n  } else {\n    // just a year, set the month and day to the first\n    parts[1] = 0;\n    parts[2] = 1;\n  }\n\n  const decoded = new Date(...(parts as [number, number, number]));\n\n  if (isNaN(decoded.getTime())) {\n    return null;\n  }\n\n  return decoded;\n}\n\n/**\n * Encodes a date as a string in ISO 8601 (\"2019-05-28T10:58:40Z\") format.\n *\n * @param {Date} date\n * @return {String} the encoded date\n */\nexport function encodeDateTime(\n  date: Date | null | undefined\n): string | null | undefined {\n  if (date == null) {\n    return date;\n  }\n\n  return date.toISOString();\n}\n\n/**\n * Converts a date in the https://en.wikipedia.org/wiki/ISO_8601 format.\n * For allowed inputs see specs:\n *  - https://tools.ietf.org/html/rfc2822#page-14\n *  - http://www.ecma-international.org/ecma-262/5.1/#sec-15.9.1.15\n *\n * If an array is provided, only the first entry is used.\n *\n * @param  {String} input String date form like '1995-12-17T03:24:00'\n * @return {Date} parsed date\n */\nexport function decodeDateTime(\n  input: EncodedValue\n): Date | null | undefined {\n  const dateString = getEncodedValue(input);\n  if (dateString == null) return dateString;\n\n  const decoded = new Date(dateString);\n\n  if (isNaN(decoded.getTime())) {\n    return null;\n  }\n\n  return decoded;\n}\n\n/**\n * Encodes a boolean as a string. true -> \"1\", false -> \"0\".\n *\n * @param {Boolean} bool\n * @return {String} the encoded boolean\n */\nexport function encodeBoolean(\n  bool: boolean | null | undefined\n): string | null | undefined {\n  if (bool == null) {\n    return bool;\n  }\n\n  return bool ? '1' : '0';\n}\n\n/**\n * Decodes a boolean from a string. \"1\" -> true, \"0\" -> false.\n * Everything else maps to undefined.\n *\n * If an array is provided, only the first entry is used.\n *\n * @param {String} input the encoded boolean string\n * @return {Boolean} the boolean value\n */\nexport function decodeBoolean(\n  input: EncodedValue\n): boolean | null | undefined {\n  const boolStr = getEncodedValue(input);\n  if (boolStr == null) return boolStr;\n\n  if (boolStr === '1') {\n    return true;\n  } else if (boolStr === '0') {\n    return false;\n  }\n\n  return null;\n}\n\n/**\n * Encodes a number as a string.\n *\n * @param {Number} num\n * @return {String} the encoded number\n */\nexport function encodeNumber(\n  num: number | null | undefined\n): string | null | undefined {\n  if (num == null) {\n    return num;\n  }\n\n  return String(num);\n}\n\n/**\n * Decodes a number from a string. If the number is invalid,\n * it returns undefined.\n *\n * If an array is provided, only the first entry is used.\n *\n * @param {String} input the encoded number string\n * @return {Number} the number value\n */\nexport function decodeNumber(\n  input: EncodedValue\n): number | null | undefined {\n  const numStr = getEncodedValue(input);\n  if (numStr == null) return numStr;\n  if (numStr === '') return null;\n\n  const result = +numStr;\n  return result;\n}\n\n/**\n * Encodes a string while safely handling null and undefined values.\n *\n * @param {String} str a string to encode\n * @return {String} the encoded string\n */\nexport function encodeString(\n  str: EncodedValue\n): string | null | undefined {\n  if (str == null) {\n    return str;\n  }\n\n  return String(str);\n}\n\n/**\n * Decodes a string while safely handling null and undefined values.\n *\n * If an array is provided, only the first entry is used.\n *\n * @param {String} input the encoded string\n * @return {String} the string value\n */\nexport function decodeString(\n  input: EncodedValue\n): string | null | undefined {\n  const str = getEncodedValue(input, true);\n  if (str == null) return str;\n\n  return String(str);\n}\n\n/**\n * Decodes an enum value while safely handling null and undefined values.\n *\n * If an array is provided, only the first entry is used.\n *\n * @param {String} input the encoded string\n * @param {String[]} enumValues allowed enum values\n * @return {String} the string value from enumValues\n */\nexport function decodeEnum<T extends string>(\n  input: EncodedValue,\n  enumValues: T[]\n): T | null | undefined {\n  const str = decodeString(input);\n  if (str == null) return str;\n  return enumValues.includes(str as any) ? (str as T) : undefined;\n}\n\n/**\n * Decodes an enum value from arrays while safely handling null and undefined values.\n *\n * @template T\n * @param {String} input the encoded string\n * @param {T[]} enumValues allowed enum values\n * @return {T[]} the string value from enumValues\n */\nexport function decodeArrayEnum<T extends string>(\n  input: EncodedValue,\n  enumValues: T[]\n): T[] | null | undefined {\n  const arr = decodeArray(input);\n  if (arr == null) return arr;\n  if (!arr.length) return undefined;\n  return arr.every((str) => str != null && enumValues.includes(str as T))\n    ? (arr as T[])\n    : undefined;\n}\n\n/**\n * Decodes an enum value from arrays while safely handling null and undefined values.\n *\n * @template T\n * @param {String} input the encoded string\n * @param {T[]} enumValues allowed enum values\n * @param entrySeparator The array as a string with elements joined by the\n * entry separator\n * @return {T[]} the string value from enumValues\n */\nexport function decodeDelimitedArrayEnum<T extends string>(\n  input: EncodedValue,\n  enumValues: T[],\n  entrySeparator = '_'\n): T[] | null | undefined {\n  if (input != null && Array.isArray(input) && !input.length) return undefined;\n  const arr = decodeDelimitedArray(input, entrySeparator);\n  return decodeArrayEnum(arr, enumValues);\n}\n\n/**\n * Encodes anything as a JSON string.\n *\n * @param {Any} any The thing to be encoded\n * @return {String} The JSON string representation of any\n */\nexport function encodeJson(\n  any: any | null | undefined\n): string | null | undefined {\n  if (any == null) {\n    return any;\n  }\n\n  return JSON.stringify(any);\n}\n\n/**\n * Decodes a JSON string into javascript\n *\n * If an array is provided, only the first entry is used.\n *\n * @param {String} input The JSON string representation\n * @return {Any} The javascript representation\n */\nexport function decodeJson(\n  input: EncodedValue\n): any | null | undefined {\n  const jsonStr = getEncodedValue(input);\n  if (jsonStr == null) return jsonStr;\n\n  let result = null;\n  try {\n    result = JSON.parse(jsonStr);\n  } catch (e) {\n    /* ignore errors, returning undefined */\n  }\n\n  return result;\n}\n\n/**\n * Encodes an array as a JSON string.\n *\n * @param {Array} array The array to be encoded\n * @return {String[]} The array of strings to be put in the URL\n * as repeated query parameters\n */\nexport function encodeArray(\n  array: (string | null)[] | null | undefined\n): (string | null)[] | null | undefined {\n  if (array == null) {\n    return array;\n  }\n\n  return array;\n}\n\n/**\n * Decodes an array or singular value and returns it as an array\n * or undefined if falsy. Filters out undefined values.\n *\n * @param {String | Array} input The input value\n * @return {Array} The javascript representation\n */\nexport function decodeArray(\n  input: EncodedValue\n): (string | null)[] | null | undefined {\n  const arr = getEncodedValueArray(input);\n  if (arr == null) return arr;\n\n  return arr;\n}\n\n/**\n * Encodes a numeric array as a JSON string.\n *\n * @param {Array} array The array to be encoded\n * @return {String[]} The array of strings to be put in the URL\n * as repeated query parameters\n */\nexport function encodeNumericArray(\n  array: (number | null)[] | null | undefined\n): (string | null)[] | null | undefined {\n  if (array == null) {\n    return array;\n  }\n\n  return array.map(String);\n}\n\n/**\n * Decodes an array or singular value and returns it as an array\n * or undefined if falsy. Filters out undefined and NaN values.\n *\n * @param {String | Array} input The input value\n * @return {Array} The javascript representation\n */\nexport function decodeNumericArray(\n  input: EncodedValue\n): (number | null)[] | null | undefined {\n  const arr = decodeArray(input);\n  if (arr == null) return arr;\n\n  return arr.map((d) => (d === '' || d == null ? null : +d));\n}\n\n/**\n * Encodes an array as a delimited string. For example,\n * ['a', 'b'] -> 'a_b' with entrySeparator='_'\n *\n * @param array The array to be encoded\n * @param entrySeparator The string used to delimit entries\n * @return The array as a string with elements joined by the\n * entry separator\n */\nexport function encodeDelimitedArray(\n  array: (string | null)[] | null | undefined,\n  entrySeparator = '_'\n): string | null | undefined {\n  if (array == null) {\n    return array;\n  }\n\n  return array.join(entrySeparator);\n}\n\n/**\n * Decodes a delimited string into javascript array. For example,\n * 'a_b' -> ['a', 'b'] with entrySeparator='_'\n *\n * If an array is provided as input, only the first entry is used.\n *\n * @param {String} input The JSON string representation\n * @param entrySeparator The array as a string with elements joined by the\n * entry separator\n * @return {Array} The javascript representation\n */\nexport function decodeDelimitedArray(\n  input: EncodedValue,\n  entrySeparator = '_'\n): (string | null)[] | null | undefined {\n  const arrayStr = getEncodedValue(input, true);\n  if (arrayStr == null) return arrayStr;\n  if (arrayStr === '') return [];\n\n  return arrayStr.split(entrySeparator);\n}\n\n/**\n * Encodes a numeric array as a delimited string. (alias of encodeDelimitedArray)\n * For example, [1, 2] -> '1_2' with entrySeparator='_'\n *\n * @param {Array} array The array to be encoded\n * @return {String} The JSON string representation of array\n */\nexport const encodeDelimitedNumericArray = encodeDelimitedArray as (\n  array: (number | null)[] | null | undefined,\n  entrySeparator?: string\n) => string | null | undefined;\n\n/**\n * Decodes a delimited string into javascript array where all entries are numbers\n * For example, '1_2' -> [1, 2] with entrySeparator='_'\n *\n * If an array is provided as input, only the first entry is used.\n *\n * @param {String} jsonStr The JSON string representation\n * @return {Array} The javascript representation\n */\nexport function decodeDelimitedNumericArray(\n  arrayStr: EncodedValue,\n  entrySeparator = '_'\n): (number | null)[] | null | undefined {\n  const decoded = decodeDelimitedArray(arrayStr, entrySeparator);\n  if (decoded == null) return decoded;\n\n  return decoded.map((d) => (d === '' || d == null ? null : +d));\n}\n\n/**\n * Encode simple objects as readable strings. Works only for simple,\n * flat objects where values are numbers, strings.\n *\n * For example { foo: bar, boo: baz } -> \"foo-bar_boo-baz\"\n *\n * @param {Object} object The object to encode\n * @param {String} keyValSeparator=\"-\" The separator between keys and values\n * @param {String} entrySeparator=\"_\" The separator between entries\n * @return {String} The encoded object\n */\nexport function encodeObject(\n  obj: { [key: string]: string | null | number | undefined } | null | undefined,\n  keyValSeparator = '-',\n  entrySeparator = '_'\n): string | null | undefined {\n  if (obj == null) return obj; // null or undefined\n  if (!Object.keys(obj).length) return ''; // {} case\n\n  return Object.keys(obj)\n    .map((key) => `${key}${keyValSeparator}${obj[key]}`)\n    .join(entrySeparator);\n}\n\n/**\n * Decodes a simple object to javascript. Currently works only for simple,\n * flat objects where values are strings.\n *\n * For example \"foo-bar_boo-baz\" -> { foo: bar, boo: baz }\n *\n * If an array is provided as input, only the first entry is used.\n *\n * @param {String} input The object string to decode\n * @param {String} keyValSeparator=\"-\" The separator between keys and values\n * @param {String} entrySeparator=\"_\" The separator between entries\n * @return {Object} The javascript object\n */\nexport function decodeObject(\n  input: EncodedValue,\n  keyValSeparator = '-',\n  entrySeparator = '_'\n): { [key: string]: string } | null | undefined {\n  const objStr = getEncodedValue(input, true);\n  if (objStr == null) return objStr;\n  if (objStr === '') return {};\n\n  const obj: { [key: string]: string } = {};\n\n  const keyValSeparatorRegExp = new RegExp(`${keyValSeparator}(.*)`);\n  objStr.split(entrySeparator).forEach((entryStr) => {\n    const [key, value] = entryStr.split(keyValSeparatorRegExp);\n    obj[key] = value;\n  });\n\n  return obj;\n}\n\n/**\n * Encode simple objects as readable strings. Alias of encodeObject.\n *\n * For example { foo: 123, boo: 521 } -> \"foo-123_boo-521\"\n *\n * @param {Object} object The object to encode\n * @param {String} keyValSeparator=\"-\" The separator between keys and values\n * @param {String} entrySeparator=\"_\" The separator between entries\n * @return {String} The encoded object\n */\nexport const encodeNumericObject = encodeObject as (\n  obj: { [key: string]: number | null | undefined } | null | undefined,\n  keyValSeparator?: string,\n  entrySeparator?: string\n) => string | null | undefined;\n\n/**\n * Decodes a simple object to javascript where all values are numbers.\n * Currently works only for simple, flat objects.\n *\n * For example \"foo-123_boo-521\" -> { foo: 123, boo: 521 }\n *\n * If an array is provided as input, only the first entry is used.\n *\n * @param {String} input The object string to decode\n * @param {String} keyValSeparator=\"-\" The separator between keys and values\n * @param {String} entrySeparator=\"_\" The separator between entries\n * @return {Object} The javascript object\n */\nexport function decodeNumericObject(\n  input: EncodedValue,\n  keyValSeparator = '-',\n  entrySeparator = '_'\n): { [key: string]: number | null | undefined } | null | undefined {\n  const decoded: { [key: string]: string } | null | undefined = decodeObject(\n    input,\n    keyValSeparator,\n    entrySeparator\n  );\n\n  if (decoded == null) return decoded;\n\n  // convert to numbers\n  const decodedNumberObj: { [key: string]: number | null | undefined } = {};\n  for (const key of Object.keys(decoded)) {\n    decodedNumberObj[key] = decodeNumber(decoded[key]);\n  }\n\n  return decodedNumberObj;\n}\n","import * as Serialize from './serialize';\nimport { QueryParamConfig } from './types';\n\n/**\n * String values\n */\nexport const StringParam: QueryParamConfig<\n  string | null | undefined,\n  string | null | undefined\n> = {\n  encode: Serialize.encodeString,\n  decode: Serialize.decodeString,\n};\n\n/**\n * String enum\n */\nexport const createEnumParam = <T extends string>(\n  enumValues: T[]\n): QueryParamConfig<T | null | undefined, T | null | undefined> => ({\n  encode: Serialize.encodeString,\n  decode: (input) => Serialize.decodeEnum(input, enumValues),\n});\n\n/**\n * Array enum\n */\nexport const createEnumArrayParam = <T extends string>(\n  enumValues: T[]\n): QueryParamConfig<T[] | null | undefined, T[] | null | undefined> => ({\n  encode: (text) =>\n    Serialize.encodeArray(text == null || Array.isArray(text) ? text : [text]),\n  decode: (input) => Serialize.decodeArrayEnum(input, enumValues),\n});\n\n/**\n * Array delimited enum\n */\nexport const createEnumDelimitedArrayParam = <T extends string>(\n  enumValues: T[],\n  entrySeparator = '_'\n): QueryParamConfig<T[] | null | undefined, T[] | null | undefined> => ({\n  encode: (text) =>\n    Serialize.encodeDelimitedArray(\n      text == null || Array.isArray(text) ? text : [text],\n      entrySeparator\n    ),\n  decode: (input) =>\n    Serialize.decodeDelimitedArrayEnum(input, enumValues, entrySeparator),\n});\n\n/**\n * Numbers (integers or floats)\n */\nexport const NumberParam: QueryParamConfig<\n  number | null | undefined,\n  number | null | undefined\n> = {\n  encode: Serialize.encodeNumber,\n  decode: Serialize.decodeNumber,\n};\n\n/**\n * For flat objects where values are strings\n */\nexport const ObjectParam: QueryParamConfig<\n  { [key: string]: string | undefined } | null | undefined,\n  { [key: string]: string | undefined } | null | undefined\n> = {\n  encode: Serialize.encodeObject,\n  decode: Serialize.decodeObject,\n};\n\n/**\n * For flat arrays of strings, filters out undefined values during decode\n */\nexport const ArrayParam: QueryParamConfig<\n  (string | null)[] | null | undefined,\n  (string | null)[] | null | undefined\n> = {\n  encode: Serialize.encodeArray,\n  decode: Serialize.decodeArray,\n};\n\n/**\n * For flat arrays of strings, filters out undefined values during decode\n */\nexport const NumericArrayParam: QueryParamConfig<\n  (number | null)[] | null | undefined,\n  (number | null)[] | null | undefined\n> = {\n  encode: Serialize.encodeNumericArray,\n  decode: Serialize.decodeNumericArray,\n};\n\n/**\n * For any type of data, encoded via JSON.stringify\n */\nexport const JsonParam: QueryParamConfig<any, any> = {\n  encode: Serialize.encodeJson,\n  decode: Serialize.decodeJson,\n};\n\n/**\n * For simple dates (YYYY-MM-DD)\n */\nexport const DateParam: QueryParamConfig<\n  Date | null | undefined,\n  Date | null | undefined\n> = {\n  encode: Serialize.encodeDate,\n  decode: Serialize.decodeDate,\n  equals: (\n    valueA: Date | null | undefined,\n    valueB: Date | null | undefined\n  ) => {\n    if (valueA === valueB) return true;\n    if (valueA == null || valueB == null) return valueA === valueB;\n\n    // ignore time of day\n    return (\n      valueA.getFullYear() === valueB.getFullYear() &&\n      valueA.getMonth() === valueB.getMonth() &&\n      valueA.getDate() === valueB.getDate()\n    );\n  },\n};\n\n/**\n * For dates in simplified extended ISO format (YYYY-MM-DDTHH:mm:ss.sssZ or ±YYYYYY-MM-DDTHH:mm:ss.sssZ)\n */\nexport const DateTimeParam: QueryParamConfig<\n  Date | null | undefined,\n  Date | null | undefined\n> = {\n  encode: Serialize.encodeDateTime,\n  decode: Serialize.decodeDateTime,\n  equals: (\n    valueA: Date | null | undefined,\n    valueB: Date | null | undefined\n  ) => {\n    if (valueA === valueB) return true;\n    if (valueA == null || valueB == null) return valueA === valueB;\n\n    return valueA.valueOf() === valueB.valueOf();\n  },\n};\n\n/**\n * For boolean values: 1 = true, 0 = false\n */\nexport const BooleanParam: QueryParamConfig<\n  boolean | null | undefined,\n  boolean | null | undefined\n> = {\n  encode: Serialize.encodeBoolean,\n  decode: Serialize.decodeBoolean,\n};\n\n/**\n * For flat objects where the values are numbers\n */\nexport const NumericObjectParam: QueryParamConfig<\n  { [key: string]: number | null | undefined } | null | undefined,\n  { [key: string]: number | null | undefined } | null | undefined\n> = {\n  encode: Serialize.encodeNumericObject,\n  decode: Serialize.decodeNumericObject,\n};\n\n/**\n * For flat arrays of strings, filters out undefined values during decode\n */\nexport const DelimitedArrayParam: QueryParamConfig<\n  (string | null)[] | null | undefined,\n  (string | null)[] | null | undefined\n> = {\n  encode: Serialize.encodeDelimitedArray,\n  decode: Serialize.decodeDelimitedArray,\n};\n\n/**\n * For flat arrays where the values are numbers, filters out undefined values during decode\n */\nexport const DelimitedNumericArrayParam: QueryParamConfig<\n  (number | null)[] | null | undefined,\n  (number | null)[] | null | undefined\n> = {\n  encode: Serialize.encodeDelimitedNumericArray,\n  decode: Serialize.decodeDelimitedNumericArray,\n};\n","import { EncodedQuery } from './types';\n\n/**\n * Default implementation of objectToSearchString powered by URLSearchParams.\n * Does not support null values. Does not prefix with \"?\"\n * This converts an object { foo: '123', bar: 'x' } to a search string `?foo=123&bar=x`\n * This is only a very basic version, you may prefer the advanced versions offered\n * by third party libraries like query-string (\"stringify\") or qs.\n */\nexport function objectToSearchString(encodedParams: EncodedQuery): string {\n  const params = new URLSearchParams();\n  const entries = Object.entries(encodedParams);\n\n  for (const [key, value] of entries) {\n    if (value === undefined) continue;\n    if (value === null) continue;\n\n    if (Array.isArray(value)) {\n      for (const item of value) {\n        params.append(key, item ?? '');\n      }\n    } else {\n      params.append(key, value);\n    }\n  }\n\n  return params.toString();\n}\n","import { EncodedQuery } from './types';\nimport { objectToSearchString } from './objectToSearchString';\nimport { searchStringToObject } from '.';\n\n/**\n * An example of a transformSearchString function that undoes encoding of\n * common JSON characters that are technically allowed in URLs.\n */\nconst JSON_SAFE_CHARS = `{}[],\":`\n  .split('')\n  .map((d) => [d, encodeURIComponent(d)]);\n\nfunction getHrefFromLocation(location: Location, search: string): string {\n  // https://developer.mozilla.org/en-US/docs/Web/API/URL/URL\n  let href: string = search;\n\n  if (location.href) {\n      // TODO - implement base option if location.href is relative\n      //  see https://developer.mozilla.org/en-US/docs/Web/API/URL/URL#syntax\n    try {\n      const url = new URL(location.href);\n      href = `${url.origin}${url.pathname}${search}`;\n    } catch (e) {\n      href = '';\n    }\n  }\n\n  return href;\n}\n\nexport function transformSearchStringJsonSafe(searchString: string): string {\n  let str = searchString;\n  for (let [char, code] of JSON_SAFE_CHARS) {\n    str = str.replace(new RegExp('\\\\' + code, 'g'), char);\n  }\n  return str;\n}\n\n/**\n * Update a location, wiping out parameters not included in encodedQuery\n * If a param is set to undefined it will be removed from the URL.\n */\nexport function updateLocation(\n  encodedQuery: EncodedQuery,\n  location: Location,\n  objectToSearchStringFn = objectToSearchString\n): Location {\n  let encodedSearchString = objectToSearchStringFn(encodedQuery);\n\n  const search = encodedSearchString.length ? `?${encodedSearchString}` : '';\n\n  const newLocation: Location & {\n    key: string;\n    query: EncodedQuery;\n  } = {\n    ...location,\n    key: `${Date.now()}`, // needed for some routers (e.g. react-router)\n    href: getHrefFromLocation(location, search),\n    search,\n    query: encodedQuery, // needed for some routers (e.g. found)\n  };\n\n  return newLocation;\n}\n\n/**\n * Update a location while retaining existing parameters.\n * If a param is set to undefined it will be removed from the URL.\n */\nexport function updateInLocation(\n  encodedQueryReplacements: EncodedQuery,\n  location: Location,\n  objectToSearchStringFn = objectToSearchString,\n  searchStringToObjectFn = searchStringToObject\n): Location {\n  // explicitly avoid parsing numbers to ensure the\n  // return type has the same shape as EncodeQuery\n  const currQuery = searchStringToObjectFn(location.search);\n\n  const newQuery = {\n    ...currQuery,\n    ...encodedQueryReplacements,\n  };\n\n  return updateLocation(newQuery, location, objectToSearchStringFn);\n}\n","import {QueryParamConfigMap, EncodedValueMap, ToBeEncodedValueMap} from './types';\n\n/**\n * Convert the values in query to strings via the encode functions configured\n * in paramConfigMap\n *\n * @param paramConfigMap Map from query name to { encode, decode } config\n * @param query Map from query name to value to be encoded\n */\nexport function encodeQueryParams<QPCMap extends QueryParamConfigMap>(\n  paramConfigMap: QPCMap,\n  query: Partial<ToBeEncodedValueMap<QPCMap>>\n): Partial<EncodedValueMap<QPCMap>> {\n  const encodedQuery: Partial<EncodedValueMap<QPCMap>> = {};\n\n  const paramNames = Object.keys(query);\n  for (const paramName of paramNames) {\n    const valueToBeEncoded = query[paramName];\n\n    if (!paramConfigMap[paramName]) {\n      // NOTE: we could just not encode it, but it is probably convenient to have\n      // it be included by default as a string type.\n      (encodedQuery as any)[paramName] =\n          valueToBeEncoded == null ? valueToBeEncoded : String(valueToBeEncoded);\n    } else {\n      encodedQuery[paramName as keyof QPCMap] = paramConfigMap[\n        paramName\n      ].encode(query[paramName]);\n    }\n  }\n\n  return encodedQuery;\n}\nexport default encodeQueryParams;\n","import { DecodedValueMap, QueryParamConfigMap, EncodedValueMap } from './types';\n\n/**\n * Convert the values in query to strings via the encode functions configured\n * in paramConfigMap\n *\n * @param paramConfigMap Map from query name to { encode, decode } config\n * @param encodedQuery Query updates mapping param name to decoded value\n */\nexport function decodeQueryParams<QPCMap extends QueryParamConfigMap>(\n  paramConfigMap: QPCMap,\n  encodedQuery: Partial<EncodedValueMap<QPCMap>>\n): DecodedValueMap<QPCMap> {\n  const decodedQuery: Partial<DecodedValueMap<QPCMap>> = {};\n\n  // iterate over all keys in the config (#30)\n  const paramNames = Object.keys(paramConfigMap);\n\n  // ensure any non configured keys that are in the URL are also included\n  for (const encodedKey of Object.keys(encodedQuery)) {\n    if (paramConfigMap[encodedKey] == null) {\n      paramNames.push(encodedKey);\n    }\n  }\n\n  for (const paramName of paramNames) {\n    const encodedValue = encodedQuery[paramName];\n\n    if (!paramConfigMap[paramName]) {\n      if (process.env.NODE_ENV === 'development') {\n        console.warn(\n          `Passing through parameter ${paramName} during decoding since it was not configured.`\n        );\n      }\n\n      // NOTE: we could just not include it, but it is probably convenient to have\n      // it default to be a string type.\n      (decodedQuery as any)[paramName] = encodedValue;\n    } else {\n      decodedQuery[paramName as keyof QPCMap] = paramConfigMap[\n        paramName\n      ].decode(encodedValue);\n    }\n  }\n\n  return decodedQuery as DecodedValueMap<QPCMap>;\n}\n","import { EncodedQuery } from './types';\n\n/**\n * Default implementation of searchStringToObject powered by URLSearchParams\n * This converts a search string like `?foo=123&bar=x` to { foo: '123', bar: 'x' }\n * This is only a very basic version, you may prefer the advanced versions offered\n * by third party libraries like query-string (\"parse\") or qs.\n */\nexport function searchStringToObject(searchString: string): EncodedQuery {\n  const params = new URLSearchParams(searchString);\n  const parsed: EncodedQuery = {};\n  for (let [key, value] of params) {\n    if (Object.prototype.hasOwnProperty.call(parsed, key)) {\n      if (Array.isArray(parsed[key])) {\n        (parsed[key] as string[]).push(value);\n      } else {\n        parsed[key] = [parsed[key] as string, value];\n      }\n    } else {\n      parsed[key] = value;\n    }\n  }\n\n  return parsed;\n}\n"]}