{"version":3,"sources":["../src/index.ts"],"names":["s","root"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * MIT License\n * Copyright (c) 2025\n */\n\nexport type FlattenOptions = {\n  /**\n   * Path delimiter for object traversal (default \".\")\n   */\n  delimiter?: string;\n  /**\n   * Joiner string used when merging multiple values under the same key (default \",\")\n   */\n  joiner?: string;\n  /**\n   * If true, include `null` and `undefined` as string values (\"null\" / \"undefined\") (default false)\n   */\n  includeNullUndefined?: boolean;\n  /**\n   * If true, de-duplicate repeated values per key before joining (default false)\n   * Only applies when preserveArrayStructure is false.\n   */\n  dedupeArrayValues?: boolean;\n  /**\n   * If true, sort resulting keys alphabetically (default false)\n   */\n  sortKeys?: boolean;\n  /**\n   * If true, arrays are flattened with numeric indexes to preserve structure (default false).\n   * When false, arrays merge values under the same key and join at the end (original behavior).\n   */\n  preserveArrayStructure?: boolean;\n};\n\n/**\n * Flattens any JSON-like value into { \"a.b.c\": \"value\", ... }.\n * - Objects become dot paths.\n * - With preserveArrayStructure=true: arrays use numeric indices in paths.\n * - With preserveArrayStructure=false (default): arrays of primitives are joined with `joiner`,\n *   arrays of objects merge matching leaf paths across elements.\n * - Top-level primitives produce an empty object (no anonymous key).\n *\n * Design notes:\n *  - Aggregates multiple values for the same leaf key and joins at the end when not preserving arrays.\n *  - Dates become ISO strings via `.toISOString()`.\n *  - Non-primitive leftovers are JSON.stringified where possible; otherwise `String(v)`.\n */\nexport function flattenToKeyValue(\n  input: unknown,\n  opts: FlattenOptions = {}\n): Record<string, string> {\n  const delimiter = opts.delimiter ?? \".\";\n  const joiner = opts.joiner ?? \",\";\n  const includeNullUndefined = opts.includeNullUndefined ?? false;\n  const dedupe = opts.dedupeArrayValues ?? false;\n  const preserveArrays = opts.preserveArrayStructure ?? false;\n\n  // Accumulator keeps arrays of strings per key; we join at the end (when not preserving arrays).\n  const acc = new Map<string, string[]>();\n\n  const add = (key: string, val: string) => {\n    if (!key) return; // skip adding empty path\n    const list = acc.get(key);\n    if (list) {\n      if (!dedupe || !list.includes(val)) list.push(val);\n    } else {\n      acc.set(key, [val]);\n    }\n  };\n\n  const isPlainObject = (v: unknown): v is Record<string, unknown> =>\n    typeof v === \"object\" && v !== null && !Array.isArray(v);\n\n  const isPrimitive = (v: unknown) =>\n    v === null ||\n    typeof v === \"string\" ||\n    typeof v === \"number\" ||\n    typeof v === \"boolean\" ||\n    typeof v === \"bigint\";\n\n  const toStr = (v: unknown, allowNullUndefined = includeNullUndefined): string | undefined => {\n    if (v === null || v === undefined) {\n      return allowNullUndefined ? String(v) : undefined;\n    }\n    if (v instanceof Date) return v.toISOString();\n    if (isPrimitive(v)) return String(v);\n    try {\n      return JSON.stringify(v);\n    } catch {\n      return String(v);\n    }\n  };\n\n  const joinPath = (base: string, seg: string) =>\n    base ? `${base}${delimiter}${seg}` : seg;\n\n  const walk = (val: unknown, path: string, fromMergedArray = false) => {\n    if (isPrimitive(val) || val instanceof Date) {\n      const s = toStr(val, includeNullUndefined || fromMergedArray);\n      if (s !== undefined) add(path, s);\n      return;\n    }\n\n    if (Array.isArray(val)) {\n      if (preserveArrays) {\n        // Use numeric indices to preserve structure.\n        for (let i = 0; i < val.length; i++) {\n          const next = joinPath(path, String(i));\n          const item = val[i];\n          if (isPrimitive(item) || item instanceof Date) {\n            const s = toStr(item, includeNullUndefined);\n            if (s !== undefined) add(next, s);\n          } else {\n            walk(item, next, false);\n          }\n        }\n        return;\n      }\n\n      // NOT preserving arrays (original behavior)\n      // Arrays of primitives -> add each value to the same key\n      if (val.every(isPrimitive)) {\n        for (const item of val) {\n          const s = toStr(item, true);\n          if (s !== undefined) add(path, s);\n        }\n        return;\n      }\n\n      // Arrays of objects/mixed -> flatten each element under the SAME path.\n      for (const item of val) {\n        if (isPrimitive(item) || item instanceof Date) {\n          const s = toStr(item, true);\n          if (s !== undefined) add(path, s);\n        } else if (Array.isArray(item)) {\n          // Nested arrays: recurse with same path so leaves aggregate\n          walk(item, path, true);\n        } else if (isPlainObject(item)) {\n          for (const [k, v] of Object.entries(item)) {\n            const next = joinPath(path, k);\n            walk(v, next, true);\n          }\n        }\n      }\n      return;\n    }\n\n    if (isPlainObject(val)) {\n      for (const [k, v] of Object.entries(val)) {\n        const next = joinPath(path, k);\n        walk(v, next, fromMergedArray);\n      }\n      return;\n    }\n\n    // Fallback (functions, symbols, etc.) -> stringify if asked\n    const s = toStr(val, includeNullUndefined || fromMergedArray);\n    if (s !== undefined) add(path, s);\n  };\n\n  walk(input, \"\", false);\n\n  // Build the final object (joined values per key when not preserving arrays).\n  const entries = Array.from(acc.entries()).map(([k, arr]) => [\n    k,\n    preserveArrays ? (arr.length === 1 ? arr[0] : arr.join(joiner)) : arr.join(joiner),\n  ]);\n  if (opts.sortKeys) entries.sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));\n  return Object.fromEntries(entries);\n}\n\n/**\n * Reconstructs a nested object/array structure from flattened key-value pairs.\n *\n * Example input:\n *   { '0.firstname': 'Jane', '0.lastName': 'Doe', '1.firstname': 'Bob' }\n *\n * Output:\n *   [\n *     { firstname: 'Jane', lastName: 'Doe' },\n *     { firstname: 'Bob' }\n *   ]\n *\n * Design:\n *  - Uses the same delimiter as flattenToKeyValue (default \".\") to split keys into paths.\n *  - Detects numeric path segments (like \"0\", \"1\") and builds arrays instead of objects.\n *  - Automatically converts primitive strings back to booleans, numbers, dates, null, etc.\n *  - When preserveArrayStructure=true, it assumes each indexed key refers to an array element\n *    and does not split joined strings.\n */\nexport function unFlattenKeyValue(\n  input: Record<string, string>,\n  opts: FlattenOptions = {}\n): unknown {\n  const delimiter = opts.delimiter ?? \".\";\n  const joiner = opts.joiner ?? \",\";\n  const preserveArrays = opts.preserveArrayStructure ?? false;\n\n  // Check if a path segment looks like a numeric index\n  const isIndex = (s: string) => /^\\d+$/.test(s);\n\n  /**\n   * Parses a string value into its most likely native type:\n   * - \"true\" / \"false\" → boolean\n   * - numeric strings → number\n   * - \"null\" / \"undefined\" → null / undefined\n   * - ISO dates → Date objects\n   * - JSON-like strings → parsed via JSON.parse\n   * - otherwise left as string\n   */\n  const parseAtom = (s: string) => {\n    if (s === \"null\") return null;\n    if (s === \"undefined\") return undefined;\n    if (s === \"true\") return true;\n    if (s === \"false\") return false;\n    if (!isNaN(Number(s)) && s.trim() !== \"\") return Number(s);\n\n    // ISO date detection\n    const d = new Date(s);\n    if (!isNaN(d.getTime()) && /^\\d{4}-\\d{2}-\\d{2}T/.test(s)) return d;\n\n    // Try to parse JSON strings like '{\"x\":1}'\n    try {\n      return JSON.parse(s);\n    } catch {\n      return s;\n    }\n  };\n\n  /**\n   * Recursively creates nested objects or arrays as needed based on key path.\n   * - Replaces current containers in-place when switching between object ↔ array.\n   * - Returns the possibly replaced root each time (in case root becomes an array).\n   */\n  const setDeep = (root: any, path: string[], value: any) => {\n    let curr = root;\n    const stack: Array<{ parent: any; prop: string | number }> = [];\n\n    for (let i = 0; i < path.length; i++) {\n      const key = path[i];\n      const last = i === path.length - 1;\n      const keyIsIndex = isIndex(key);\n      const nextIsIndex = !last && isIndex(path[i + 1]);\n\n      // Helper: replace current container (object → array, array → object)\n      const replaceHere = (newContainer: any) => {\n        const top = stack[stack.length - 1];\n        if (top) {\n          top.parent[top.prop as any] = newContainer;\n        } else {\n          root = newContainer;\n        }\n        return newContainer;\n      };\n\n      if (last) {\n        // --- Assign the final value ---\n        if (keyIsIndex) {\n          if (!Array.isArray(curr)) curr = replaceHere([]);\n          curr[Number(key)] = value;\n        } else {\n          if (typeof curr !== \"object\" || curr === null || Array.isArray(curr)) {\n            curr = replaceHere({});\n          }\n          curr[key] = value;\n        }\n      } else {\n        // --- Traverse deeper into nested path ---\n        if (keyIsIndex) {\n          if (!Array.isArray(curr)) curr = replaceHere([]);\n          const idx = Number(key);\n\n          // Ensure the next container exists\n          if (curr[idx] === undefined) curr[idx] = nextIsIndex ? [] : {};\n          else if (nextIsIndex && !Array.isArray(curr[idx])) curr[idx] = [];\n          else if (\n            !nextIsIndex &&\n            (typeof curr[idx] !== \"object\" || curr[idx] === null || Array.isArray(curr[idx]))\n          )\n            curr[idx] = {};\n\n          stack.push({ parent: curr, prop: idx });\n          curr = curr[idx];\n        } else {\n          if (typeof curr !== \"object\" || curr === null || Array.isArray(curr)) {\n            curr = replaceHere({});\n          }\n\n          // Ensure next container exists\n          if (!(key in curr)) curr[key] = nextIsIndex ? [] : {};\n          else if (nextIsIndex && !Array.isArray(curr[key])) curr[key] = [];\n          else if (\n            !nextIsIndex &&\n            (typeof curr[key] !== \"object\" || curr[key] === null || Array.isArray(curr[key]))\n          )\n            curr[key] = {};\n\n          stack.push({ parent: curr, prop: key });\n          curr = curr[key];\n        }\n      }\n    }\n\n    return root;\n  };\n\n  const parsedEntries = Object.entries(input).map(([flatKey, strVal]) => {\n    const path = flatKey.split(delimiter);\n    const parts = preserveArrays ? [strVal] : strVal.split(joiner).map((s) => s.trim());\n    const parsedValues = parts.map(parseAtom);\n    return { path, parts, parsedValues };\n  });\n\n  if (!preserveArrays && parsedEntries.length > 0) {\n    const maxLen = parsedEntries.reduce((max, entry) => Math.max(max, entry.parsedValues.length), 0);\n    const allHaveSameLength =\n      maxLen > 1 && parsedEntries.every((entry) => entry.parsedValues.length === maxLen);\n\n    if (allHaveSameLength) {\n      const result: any[] = Array.from({ length: maxLen }, () => ({}));\n\n      for (const entry of parsedEntries) {\n        for (let i = 0; i < maxLen; i++) {\n          const value = entry.parsedValues[i];\n          result[i] = setDeep(result[i], entry.path, value);\n        }\n      }\n\n      return result;\n    }\n  }\n\n  // --- MAIN reconstruction loop (default behaviour) ---\n  let root: any = {};\n\n  for (const entry of parsedEntries) {\n    const { path, parsedValues } = entry;\n    const value = preserveArrays\n      ? parsedValues[0]\n      : parsedValues.length === 1\n      ? parsedValues[0]\n      : parsedValues;\n    root = setDeep(root, path, value);\n  }\n\n  return root;\n}\n\n\nexport default flattenToKeyValue;\n"]}