{"version":3,"file":"index.cjs","sources":["../src/index.ts"],"sourcesContent":["export type Primitive = null | undefined | string | number | boolean | symbol | bigint;\n\ntype ArrayKey = number;\n\ntype IsTuple<T extends readonly any[]> = number extends T['length'] ? false : true;\n\ntype TupleKeys<T extends readonly any[]> = Exclude<keyof T, keyof any[]>;\n\nexport type PathConcat<TKey extends string | number, TValue> = TValue extends Primitive\n  ? `${TKey}`\n  : `${TKey}` | `${TKey}.${Path<TValue>}`;\n\nexport type Path<T> = T extends readonly (infer V)[]\n  ? IsTuple<T> extends true\n    ? {\n        [K in TupleKeys<T>]-?: PathConcat<K & string, T[K]>;\n      }[TupleKeys<T>]\n    : PathConcat<ArrayKey, V>\n  : {\n      [K in keyof T]-?: PathConcat<K & string, T[K]>;\n    }[keyof T];\n\ntype ArrayPathConcat<TKey extends string | number, TValue> = TValue extends Primitive\n  ? never\n  : TValue extends readonly (infer U)[]\n    ? U extends Primitive\n      ? never\n      : `${TKey}` | `${TKey}.${ArrayPath<TValue>}`\n    : `${TKey}.${ArrayPath<TValue>}`;\n\nexport type ArrayPath<T> = T extends readonly (infer V)[]\n  ? IsTuple<T> extends true\n    ? {\n        [K in TupleKeys<T>]-?: ArrayPathConcat<K & string, T[K]>;\n      }[TupleKeys<T>]\n    : ArrayPathConcat<ArrayKey, V>\n  : {\n      [K in keyof T]-?: ArrayPathConcat<K & string, T[K]>;\n    }[keyof T];\n\nexport type PathValue<T, TPath extends Path<T> | ArrayPath<T>> = T extends any\n  ? TPath extends `${infer K}.${infer R}`\n    ? K extends keyof T\n      ? R extends Path<T[K]>\n        ? undefined extends T[K]\n          ? PathValue<T[K], R> | undefined\n          : PathValue<T[K], R>\n        : never\n      : K extends `${ArrayKey}`\n        ? T extends readonly (infer V)[]\n          ? PathValue<V, R & Path<V>>\n          : never\n        : never\n    : TPath extends keyof T\n      ? T[TPath]\n      : TPath extends `${ArrayKey}`\n        ? T extends readonly (infer V)[]\n          ? V\n          : never\n        : never\n  : never;\n\nconst UNSAFE_PATH_SEGMENTS = new Set(['__proto__', 'constructor', 'prototype']);\n\nfunction assertNoUnsafePathSegments(path: string): void {\n  for (const segment of path.split('.')) {\n    if (UNSAFE_PATH_SEGMENTS.has(segment)) {\n      throw new TypeError(`Path segment \"${segment}\" is not allowed (prototype pollution risk)`);\n    }\n  }\n}\n\nexport function getByPath<T extends Record<string, any>, TPath extends Path<T>>(\n  obj: T,\n  path: TPath,\n): PathValue<T, TPath> {\n  assertNoUnsafePathSegments(path);\n  return path.split('.').reduce((acc, key) => acc?.[key], obj) as PathValue<T, TPath>;\n}\n\nexport function setByPath<T extends Record<string, any>, TPath extends Path<T>>(\n  obj: T,\n  path: TPath,\n  value: PathValue<T, TPath>,\n) {\n  assertNoUnsafePathSegments(path);\n  const segments = path.split('.') as TPath[];\n  const lastKey = segments.pop();\n\n  let target: T = obj;\n\n  for (let i = 0; i < segments.length; i++) {\n    const key = segments[i] as TPath;\n    if (!(key in target)) {\n      target[key] = {} as PathValue<T, TPath>;\n    }\n    target = target[key];\n  }\n\n  if (lastKey) {\n    target[lastKey] = value;\n  }\n\n  return obj;\n}\n"],"names":["UNSAFE_PATH_SEGMENTS","Set","assertNoUnsafePathSegments","path","_step","_iterator","_createForOfIteratorHelperLoose","split","done","segment","value","has","TypeError","obj","reduce","acc","key","segments","lastKey","pop","target","i","length"],"mappings":"sGA8DA,IAAMA,EAAuB,IAAIC,IAAI,CAAC,YAAa,cAAe,cAElE,SAASC,EAA2BC,GAClC,IAAA,IAAqCC,EAArCC,2pBAAAC,CAAsBH,EAAKI,MAAM,QAAIH,EAAAC,KAAAG,MAAE,CAA5B,IAAAC,EAAOL,EAAAM,MAChB,GAAIV,EAAqBW,IAAIF,GAC3B,UAAUG,UAA2BH,iBAAAA,EAAoD,8CAE7F,CACF,mBAEgB,SACdI,EACAV,GAGA,OADAD,EAA2BC,GACpBA,EAAKI,MAAM,KAAKO,OAAO,SAACC,EAAKC,GAAQ,OAAAD,MAAAA,OAAAA,EAAAA,EAAMC,EAAI,EAAEH,EAC1D,6BAGEA,EACAV,EACAO,GAEAR,EAA2BC,GAM3B,IALA,IAAMc,EAAWd,EAAKI,MAAM,KACtBW,EAAUD,EAASE,MAErBC,EAAYP,EAEPQ,EAAI,EAAGA,EAAIJ,EAASK,OAAQD,IAAK,CACxC,IAAML,EAAMC,EAASI,GACfL,KAAOI,IACXA,EAAOJ,GAAO,CAChB,GACAI,EAASA,EAAOJ,EAClB,CAMA,OAJIE,IACFE,EAAOF,GAAWR,GAGbG,CACT"}