{"version":3,"file":"index.cjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["function isObject(obj: unknown) {\n  return typeof obj === 'object' && obj !== null && !Array.isArray(obj);\n}\n\nfunction isEmptyObject(obj: unknown) {\n  return typeof obj === 'object' && obj !== null && !Array.isArray(obj) && !Object.keys(obj).length;\n}\n\nfunction isEmptyArray(arr: unknown) {\n  return Array.isArray(arr) && arr.length === 0;\n}\n\ntype PreservationContext = 'arrayItem' | 'objectProperty' | 'root';\n\ntype PreservationRule = boolean | Partial<Record<PreservationContext, boolean>>;\n\ninterface RemovalOptions {\n  preserveEmptyArray?: PreservationRule;\n  preserveEmptyObject?: PreservationRule;\n  preserveNullishArrays?: boolean;\n  removeAllFalsy?: boolean;\n}\n\nfunction shouldPreserve(rule: PreservationRule | undefined, context: PreservationContext) {\n  if (typeof rule === 'boolean') {\n    return rule;\n  }\n\n  return rule?.[context] ?? false;\n}\n\n// Remove objects that has undefined value or recursively contain undefined values\nfunction removeUndefined(obj: any): any {\n  if (obj === undefined) {\n    return undefined;\n  }\n  // Preserve null\n  if (obj === null) {\n    return null;\n  }\n  // Remove undefined in arrays\n  if (Array.isArray(obj)) {\n    return obj.map(removeUndefined).filter(item => item !== undefined);\n  }\n  if (typeof obj === 'object') {\n    const cleaned: Record<string, any> = {};\n    Object.entries(obj).forEach(([key, value]) => {\n      const cleanedValue = removeUndefined(value);\n      if (cleanedValue !== undefined) {\n        cleaned[key] = cleanedValue;\n      }\n    });\n    return cleaned;\n  }\n  return obj;\n}\n\n// Modified from here: https://stackoverflow.com/a/43781499\nfunction stripEmptyObjects(obj: any, options: RemovalOptions = {}) {\n  const cleanObj = obj;\n\n  if (obj === null && options.removeAllFalsy) {\n    return;\n  }\n\n  if (!isObject(obj) && !Array.isArray(cleanObj)) {\n    return cleanObj;\n  }\n\n  if (!Array.isArray(cleanObj)) {\n    Object.keys(cleanObj).forEach(key => {\n      let value = cleanObj[key];\n\n      if (typeof value !== 'object') {\n        return;\n      }\n\n      if (value === null) {\n        if (options.removeAllFalsy) {\n          delete cleanObj[key];\n        }\n        return;\n      }\n\n      value = stripEmptyObjects(value, options);\n\n      if (isEmptyObject(value) && !shouldPreserve(options.preserveEmptyObject, 'objectProperty')) {\n        delete cleanObj[key];\n      } else if (isEmptyArray(value) && !shouldPreserve(options.preserveEmptyArray, 'objectProperty')) {\n        delete cleanObj[key];\n      } else {\n        cleanObj[key] = value;\n      }\n    });\n\n    return cleanObj;\n  }\n\n  cleanObj.forEach((o, idx) => {\n    let value = o;\n    if (typeof value === 'object' && value !== null) {\n      value = stripEmptyObjects(value, options);\n\n      if (isEmptyObject(value) && !shouldPreserve(options.preserveEmptyObject, 'arrayItem')) {\n        delete cleanObj[idx];\n      } else if (isEmptyArray(value) && !shouldPreserve(options.preserveEmptyArray, 'arrayItem')) {\n        delete cleanObj[idx];\n      } else {\n        cleanObj[idx] = value;\n      }\n    } else if (value === null && (options.removeAllFalsy || !options.preserveNullishArrays)) {\n      // Null entries within an array should be removed by default, unless explicitly preserved\n      delete cleanObj[idx];\n    }\n  });\n\n  // Since deleting a key from an array will retain an undefined value in that array, we need to\n  // filter them out.\n  return cleanObj.filter(el => el !== undefined);\n}\n\nexport default function removeUndefinedObjects<T>(obj?: T, options?: RemovalOptions): T | undefined {\n  if (obj === undefined) {\n    return undefined;\n  }\n\n  // If array nulls are preserved, use the custom removeUndefined function so that\n  // undefined values in arrays aren't converted to nulls, which stringify does\n  // If we're not preserving array nulls (default behavior), it doesn't matter that the undefined array values are converted to nulls\n  // oxlint-disable-next-line readme/json-parse-try-catch -- If this fails we should fail.\n  let withoutUndefined = options?.preserveNullishArrays ? removeUndefined(obj) : JSON.parse(JSON.stringify(obj));\n\n  // Then we recursively remove all empty objects and nullish arrays\n  withoutUndefined = stripEmptyObjects(withoutUndefined, options);\n\n  // If the only thing that's leftover is an empty object or empty array then return nothing.\n  if (\n    (isEmptyObject(withoutUndefined) && !shouldPreserve(options?.preserveEmptyObject, 'root')) ||\n    (isEmptyArray(withoutUndefined) && !shouldPreserve(options?.preserveEmptyArray, 'root'))\n  ) {\n    return;\n  }\n\n  return withoutUndefined;\n}\n"],"mappings":";;AAAA,SAAS,SAAS,KAAc;CAC9B,OAAO,OAAO,QAAQ,YAAY,QAAQ,QAAQ,CAAC,MAAM,QAAQ,GAAG;AACtE;AAEA,SAAS,cAAc,KAAc;CACnC,OAAO,OAAO,QAAQ,YAAY,QAAQ,QAAQ,CAAC,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,KAAK,GAAG,EAAE;AAC7F;AAEA,SAAS,aAAa,KAAc;CAClC,OAAO,MAAM,QAAQ,GAAG,KAAK,IAAI,WAAW;AAC9C;AAaA,SAAS,eAAe,MAAoC,SAA8B;CACxF,IAAI,OAAO,SAAS,WAClB,OAAO;CAGT,OAAO,OAAO,YAAY;AAC5B;AAGA,SAAS,gBAAgB,KAAe;CACtC,IAAI,QAAQ,QACV;CAGF,IAAI,QAAQ,MACV,OAAO;CAGT,IAAI,MAAM,QAAQ,GAAG,GACnB,OAAO,IAAI,IAAI,eAAe,EAAE,QAAO,SAAQ,SAAS,MAAS;CAEnE,IAAI,OAAO,QAAQ,UAAU;EAC3B,MAAM,UAA+B,CAAC;EACtC,OAAO,QAAQ,GAAG,EAAE,SAAS,CAAC,KAAK,WAAW;GAC5C,MAAM,eAAe,gBAAgB,KAAK;GAC1C,IAAI,iBAAiB,QACnB,QAAQ,OAAO;EAEnB,CAAC;EACD,OAAO;CACT;CACA,OAAO;AACT;AAGA,SAAS,kBAAkB,KAAU,UAA0B,CAAC,GAAG;CACjE,MAAM,WAAW;CAEjB,IAAI,QAAQ,QAAQ,QAAQ,gBAC1B;CAGF,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,MAAM,QAAQ,QAAQ,GAC3C,OAAO;CAGT,IAAI,CAAC,MAAM,QAAQ,QAAQ,GAAG;EAC5B,OAAO,KAAK,QAAQ,EAAE,SAAQ,QAAO;GACnC,IAAI,QAAQ,SAAS;GAErB,IAAI,OAAO,UAAU,UACnB;GAGF,IAAI,UAAU,MAAM;IAClB,IAAI,QAAQ,gBACV,OAAO,SAAS;IAElB;GACF;GAEA,QAAQ,kBAAkB,OAAO,OAAO;GAExC,IAAI,cAAc,KAAK,KAAK,CAAC,eAAe,QAAQ,qBAAqB,gBAAgB,GACvF,OAAO,SAAS;QACX,IAAI,aAAa,KAAK,KAAK,CAAC,eAAe,QAAQ,oBAAoB,gBAAgB,GAC5F,OAAO,SAAS;QAEhB,SAAS,OAAO;EAEpB,CAAC;EAED,OAAO;CACT;CAEA,SAAS,SAAS,GAAG,QAAQ;EAC3B,IAAI,QAAQ;EACZ,IAAI,OAAO,UAAU,YAAY,UAAU,MAAM;GAC/C,QAAQ,kBAAkB,OAAO,OAAO;GAExC,IAAI,cAAc,KAAK,KAAK,CAAC,eAAe,QAAQ,qBAAqB,WAAW,GAClF,OAAO,SAAS;QACX,IAAI,aAAa,KAAK,KAAK,CAAC,eAAe,QAAQ,oBAAoB,WAAW,GACvF,OAAO,SAAS;QAEhB,SAAS,OAAO;EAEpB,OAAO,IAAI,UAAU,SAAS,QAAQ,kBAAkB,CAAC,QAAQ,wBAE/D,OAAO,SAAS;CAEpB,CAAC;CAID,OAAO,SAAS,QAAO,OAAM,OAAO,MAAS;AAC/C;AAEA,SAAwB,uBAA0B,KAAS,SAAyC;CAClG,IAAI,QAAQ,QACV;CAOF,IAAI,mBAAmB,SAAS,wBAAwB,gBAAgB,GAAG,IAAI,KAAK,MAAM,KAAK,UAAU,GAAG,CAAC;CAG7G,mBAAmB,kBAAkB,kBAAkB,OAAO;CAG9D,IACG,cAAc,gBAAgB,KAAK,CAAC,eAAe,SAAS,qBAAqB,MAAM,KACvF,aAAa,gBAAgB,KAAK,CAAC,eAAe,SAAS,oBAAoB,MAAM,GAEtF;CAGF,OAAO;AACT"}