{"version":3,"file":"fromEntries.cjs","names":["purry"],"sources":["../src/fromEntries.ts"],"sourcesContent":["import type { Simplify } from \"type-fest\";\nimport type { IterableContainer } from \"./internal/types/IterableContainer\";\nimport type { RemedaTypeError } from \"./internal/types/RemedaTypeError\";\nimport { purry } from \"./purry\";\n\ntype FromEntriesError<Message extends string> = RemedaTypeError<\n  \"fromEntries\",\n  Message\n>;\n\ntype Entry<Key extends PropertyKey = PropertyKey, Value = unknown> = readonly [\n  key: Key,\n  value: Value,\n];\n\n// The 2 kinds of arrays we accept result in different kinds of outputs:\n// 1. If the input is a *tuple*, we know exactly what entries it would hold,\n// and thus can type the result so that the keys are required. We will then run\n// recursively on the rest of the tuple.\n// 2. If the input is an *array* then any keys defined in the array might not\n// actually show up in runtime, and thus need to be optional. (e.g. if the input\n// is an empty array).\ntype FromEntries<Entries> = Entries extends readonly [\n  infer First,\n  ...infer Tail,\n]\n  ? FromEntriesTuple<First, Tail>\n  : Entries extends readonly [...infer Head, infer Last]\n    ? FromEntriesTuple<Last, Head>\n    : Entries extends IterableContainer<Entry>\n      ? FromEntriesArray<Entries>\n      : FromEntriesError<\"Entries array-like could not be inferred\">;\n\n// For strict tuples we build the result by intersecting each entry as a record\n// between it's key and value, recursively. The recursion goes through our main\n// type so that we support tuples which also contain rest parts.\ntype FromEntriesTuple<E, Rest> = E extends Entry\n  ? FromEntries<Rest> & Record<E[0], E[1]>\n  : FromEntriesError<\"Array-like contains a non-entry element\">;\n\n// For the array case we also need to handle what kind of keys it defines:\n// 1. If it defines a *broad* key (one that has an infinite set of values, like\n// number or string) then the result is a simple record.\n// 2. If the keys are *literals* then we need to make the record partial\n// (because those props are explicit), and we need to match each key it's\n// specific possible value, as defined by the entries.\n//\n// Note that this destination between keys is the result of how typescript\n// considers Record<string, unknown> to be **implicitly** partial, whereas\n// Record<\"a\", unknown> is not.\ntype FromEntriesArray<Entries extends IterableContainer<Entry>> =\n  string extends AllKeys<Entries>\n    ? Record<string, Entries[number][1]>\n    : number extends AllKeys<Entries>\n      ? Record<number, Entries[number][1]>\n      : symbol extends AllKeys<Entries>\n        ? Record<symbol, Entries[number][1]>\n        : FromEntriesArrayWithLiteralKeys<Entries>;\n\n// This type is largely copied from `objectFromEntries` in the repo:\n// *sindresorhus/ts-extras* but makes all properties of the output optional,\n// which is more correct because we can't assure that an entry will exist for\n// every possible prop/key of the input.\n// @see https://github.com/sindresorhus/ts-extras/blob/44f57392c5f027268330771996c4fdf9260b22d6/source/object-from-entries.ts)\ntype FromEntriesArrayWithLiteralKeys<Entries extends IterableContainer<Entry>> =\n  {\n    [P in AllKeys<Entries>]?: ValueForKey<Entries, P>;\n  };\n\ntype AllKeys<Entries extends IterableContainer<Entry>> = Extract<\n  Entries[number],\n  Entry\n>[0];\n\n// I tried and failed to simplify the type here! What the ternary does here is\n// to support the cases where the entries are defined by a single type that\n// defines all entries, but it defines the keys as a union of literals\n// (`['a' | 'b', number]`); which is different from the output of toPairs\n// which would define a separate tuple literal for each key (`['a', number] |\n// ['b', number]`). We need to support both cases!\ntype ValueForKey<\n  Entries extends IterableContainer<Entry>,\n  K extends PropertyKey,\n> = (Extract<Entries[number], Entry<K>> extends never\n  ? Entries[number]\n  : Extract<Entries[number], Entry<K>>)[1];\n\n/**\n * Creates a new object from an array of tuples by pairing up first and second elements as {[key]: value}.\n * If a tuple is not supplied for any element in the array, the element will be ignored\n * If duplicate keys exist, the tuple with the greatest index in the input array will be preferred.\n *\n * The strict option supports more sophisticated use-cases like those that would\n * result when calling the strict `toPairs` function.\n *\n * There are several other functions that could be used to build an object from\n * an array:\n * * `fromKeys` - Builds an object from an array of *keys* and a mapper for values.\n * * `indexBy` - Builds an object from an array of *values* and a mapper for keys.\n * * `pullObject` - Builds an object from an array of items with mappers for *both* keys and values.\n * Refer to the docs for more details.\n *\n * @param entries - An array of key-value pairs.\n * @signature\n *   fromEntries(tuples)\n * @example\n *   fromEntries([['a', 'b'], ['c', 'd']]); // => {a: 'b', c: 'd'}\n * @dataFirst\n * @category Object\n */\nexport function fromEntries<Entries extends IterableContainer<Entry>>(\n  entries: Entries,\n): Simplify<FromEntries<Entries>>;\n\n/**\n * Creates a new object from an array of tuples by pairing up first and second elements as {[key]: value}.\n * If a tuple is not supplied for any element in the array, the element will be ignored\n * If duplicate keys exist, the tuple with the greatest index in the input array will be preferred.\n *\n * The strict option supports more sophisticated use-cases like those that would\n * result when calling the strict `toPairs` function.\n *\n * There are several other functions that could be used to build an object from\n * an array:\n * * `fromKeys` - Builds an object from an array of *keys* and a mapper for values.\n * * `indexBy` - Builds an object from an array of *values* and a mapper for keys.\n * * `pullObject` - Builds an object from an array of items with mappers for *both* keys and values.\n * Refer to the docs for more details.\n *\n * @signature\n *   fromEntries()(tuples)\n * @example\n *   pipe(\n *     [['a', 'b'], ['c', 'd']] as const,\n *     fromEntries(),\n *   ); // => {a: 'b', c: 'd'}\n * @dataLast\n * @category Object\n */\nexport function fromEntries(): <Entries extends IterableContainer<Entry>>(\n  entries: Entries,\n) => Simplify<FromEntries<Entries>>;\n\nexport function fromEntries(...args: readonly unknown[]): unknown {\n  return purry(Object.fromEntries, args);\n}\n"],"mappings":"kGA+IA,SAAgB,EAAY,GAAG,EAAmC,CAChE,OAAOA,EAAAA,MAAM,OAAO,YAAa,EAAK"}