UNPKG

9.38 kBSource Map (JSON)View Raw
1{"version":3,"file":"index.es.js","sources":["../src/index.ts"],"sourcesContent":["import {\r\n values,\r\n set,\r\n isFunction,\r\n isUndefined,\r\n toString,\r\n isArray,\r\n constant,\r\n flow,\r\n find,\r\n eq,\r\n pickBy,\r\n result,\r\n spread,\r\n defaultTo,\r\n isPlainObject,\r\n negate,\r\n curryN,\r\n} from 'lodash/fp';\r\n\r\ntype Choice = {\r\n when: any;\r\n then?: any;\r\n ref?: number;\r\n use?: any;\r\n eager?: Function;\r\n};\r\n\r\ntype PlainObject = { [x: string]: any };\r\ntype Choices = Choice[] | PlainObject;\r\ntype LazyChoices = () => Choices;\r\ntype EqualityFn = (input: any, when: any) => boolean;\r\ntype CurriedEqualityFn = (input: any) => (when: any) => boolean;\r\n\r\ntype Args = {\r\n input: any;\r\n choices: Choices | LazyChoices;\r\n equalityFn?: EqualityFn;\r\n};\r\n\r\nconst ARG_PATTERN = /^\\{(?:\\$(\\d+?))?(?:#(.+?))?\\}$/;\r\n\r\n/**\r\n * Transforms a plain object to a `choice` array.\r\n * Keys will be mapped to `when` and values to `then`.\r\n * Values can use the `ref` and `use` shorthand syntax like `'{$0}'` and `'{#one}'`,\r\n * which translates to `{ ref: '0' }` and `{ use: 'one' }` respectively.\r\n *\r\n * @example\r\n * const plain = {\r\n * one: 1,\r\n * two: 2,\r\n * three: '{$1}',\r\n * four: '{#one}',\r\n * };\r\n *\r\n * const transformed = transformChoiceObjectToArray(plain);\r\n * // =>\r\n * // [\r\n * // { when: 'one', then: 1 },\r\n * // { when: 'two', then: 2 },\r\n * // { when: 'three', ref: '1' },\r\n * // { when: 'four', use: 'one' },\r\n * // ]\r\n *\r\n * @param choices A plain object.\r\n */\r\nconst transformChoiceObjectToArray = (choices: PlainObject): Choices =>\r\n Object.entries(choices).map(([key, value]) => {\r\n const match = ARG_PATTERN.exec(value);\r\n\r\n const [, ref, use] = match || [];\r\n\r\n const choice = {\r\n when: key,\r\n ref,\r\n use,\r\n then: value,\r\n };\r\n\r\n return pickBy(negate(isUndefined), choice);\r\n }, []);\r\n\r\n/**\r\n * If the `choices` argument is a plain object, it is transformed into a `choice` array,\r\n * else it is returned as is.\r\n *\r\n * @param choices A `choice` array or a plain object.\r\n */\r\nconst normalizeChoices = (choices: Choices): Choices =>\r\n isPlainObject(choices) ? transformChoiceObjectToArray(choices) : choices;\r\n\r\n/**\r\n * If the `choices` argument is a function, it is called so as to extract\r\n * a plain object, or a `choice` array.\r\n *\r\n * @param choices A `choice` array or a plain object, or a function that returns either.\r\n */\r\nconst getChoices = (choices: Choices | LazyChoices): Choices =>\r\n isFunction(choices) ? choices() : choices;\r\n\r\n/**\r\n * Transforms the user's input to string when the choices is a plain object and no equalityFn has\r\n * been provided, else returns it as is.\r\n *\r\n * @param choices A `choice` array or a plain object.\r\n * @param input The user's input. Can be anything that will correspond to a `when` value.\r\n */\r\nconst normalizeInput = (\r\n choices: Choices,\r\n input: any,\r\n equalityFn?: EqualityFn,\r\n): any =>\r\n isPlainObject(choices) && isUndefined(equalityFn) ? toString(input) : input;\r\n\r\n/**\r\n * Curries the `equalityFn` specified by the user.\r\n *\r\n * @param equalityFn The equalityFn specified by the user.\r\n */\r\nconst normalizeEqualityFn = (\r\n equalityFn?: EqualityFn,\r\n): CurriedEqualityFn | undefined =>\r\n equalityFn && curryN<any, any, boolean>(2, equalityFn);\r\n\r\n/**\r\n * Normalizes the library's main args before passing them on.\r\n *\r\n * @param args The library's main args supplied by the user, that will first be normalized.\r\n */\r\nconst normalizeArgs = ({ input, choices, equalityFn }: Args): any[] =>\r\n flow(\r\n (args: Args) => set('choices', getChoices(args.choices), args),\r\n (args: Args) =>\r\n set('input', normalizeInput(args.choices, args.input, equalityFn), args),\r\n (args: Args) => set('choices', normalizeChoices(args.choices), args),\r\n (args: Args) => set('equalityFn', normalizeEqualityFn(equalityFn), args),\r\n values,\r\n )({ input, choices, equalityFn });\r\n\r\n/**\r\n * Finds a `choice` entry from a `choice` array based on the user's input. It can recursively refer to itself with a\r\n * different index, if a `ref` is specified in the choice.\r\n *\r\n * @param input The user's input. Can be anything that will correspond to a `when` value.\r\n * @param choices A `choice` array or a plain object.\r\n * @param equalityFn Used to override the default equality function `eq` from `lodash`.\r\n * @param index Used to recursively refer to a different choice entry by using a `ref`.\r\n */\r\nconst findChoiceFromArray = (\r\n input: any,\r\n choices: Choices,\r\n equalityFn: CurriedEqualityFn = eq,\r\n index?: number,\r\n): Choice => {\r\n return flow(\r\n !isUndefined(index)\r\n ? constant(choices[index])\r\n : find(({ when }) =>\r\n isArray(when) ? when.some(equalityFn(input)) : equalityFn(input)(when),\r\n ),\r\n defaultTo({}),\r\n (selectedChoice: Choice) =>\r\n !isUndefined(selectedChoice.ref)\r\n ? findChoiceFromArray(input, choices, equalityFn, selectedChoice.ref)\r\n : !isUndefined(selectedChoice.use)\r\n ? findChoiceFromArray(selectedChoice.use, choices, equalityFn)\r\n : selectedChoice,\r\n )(choices);\r\n};\r\n\r\n/**\r\n * The heart of this library, a curried function which stores the specified choices (and extra options) in the first call,\r\n * and returns a function that will take the user's input, find the corresponding choice, and return its `then` value.\r\n *\r\n * It will attempt to resolve it by finding the entry in the `choice` array whose `when` corresponds to the given\r\n * `input`. If a `ref` exists in that entry, it will instead find its referenced entry. IF `use` exists in that entry,\r\n * it will instead try to find an entry that corresponds to the given `use` instead of `when`.\r\n *\r\n * The matching between the `input` and the `when` is performed by running the `equalityFn` with the `input` against the value of `when`,\r\n * or against each element in `when` if it is an array.\r\n *\r\n * After all recursive calls have returned and a choice has been found, the `then` of the choice is returned.\r\n * If the `then` is a function, it is called and its result is returned instead, to leverage lazy evaluation.\r\n *\r\n * As an escape hatch for the above lazy evaluation mechanism, a function can be specified under the `eager` key,\r\n * and it will be returned as is, without it being executed to extract its result.\r\n *\r\n * @param choices A `choice` array or a plain object.\r\n * @param defaultValue A default value to be returned if the `input` does not yield a choice.\r\n * @param equalityFn Used to override the default equality function `eq` from `lodash`.\r\n */\r\nconst chooser = (\r\n choices: Choices | LazyChoices,\r\n defaultValue?: any,\r\n equalityFn?: EqualityFn,\r\n) =>\r\n function choose(input: any, equalityFnOverride?: EqualityFn): any {\r\n return flow(\r\n spread(findChoiceFromArray),\r\n (choice) =>\r\n !isUndefined(choice.eager) ? choice.eager : result('then', choice),\r\n defaultTo(defaultValue),\r\n )(\r\n normalizeArgs({\r\n input,\r\n choices,\r\n equalityFn: equalityFnOverride || equalityFn,\r\n }),\r\n );\r\n };\r\n\r\nexport default chooser;\r\n"],"names":["ARG_PATTERN","normalizeChoices","choices","isPlainObject","Object","entries","map","_a","key","value","_b","exec","choice","when","ref","use","then","pickBy","negate","isUndefined","transformChoiceObjectToArray","normalizeArgs","input","equalityFn","flow","args","set","isFunction","getChoices","toString","normalizeInput","curryN","normalizeEqualityFn","values","findChoiceFromArray","index","find","isArray","some","constant","defaultTo","selectedChoice","defaultValue","equalityFnOverride","spread","eager","result"],"mappings":"gPAwCA,IAAMA,EAAc,iCAiDdC,EAAmB,SAACC,GACxB,OAAAC,EAAcD,GAvBqB,SAACA,GACpC,OAAAE,OAAOC,QAAQH,GAASI,KAAI,SAACC,OAACC,OAAKC,OAG3BC,EAFQV,EAAYW,KAAKF,OAIzBG,EAAS,CACbC,KAAML,EACNM,SACAC,SACAC,KAAMP,GAGR,OAAOQ,EAAOC,EAAOC,GAAcP,KAClC,IASsBQ,CAA6BlB,GAAWA,GAwC7DmB,EAAgB,SAACd,OAAEe,UAAOpB,YAASqB,eACvC,OAAAC,GACE,SAACC,GAAe,OAAAC,EAAI,UAlCL,SAACxB,GAClB,OAAAyB,EAAWzB,GAAWA,IAAYA,EAiCD0B,CAAWH,EAAKvB,SAAUuB,MACzD,SAACA,GACC,OAAAC,EAAI,QA1Ba,SACrBxB,EACAoB,EACAC,GAEA,OAAApB,EAAcD,IAAYiB,EAAYI,GAAcM,EAASP,GAASA,EAqBrDQ,CAAeL,EAAKvB,QAASuB,EAAKH,MAAOC,GAAaE,MACrE,SAACA,GAAe,OAAAC,EAAI,UAAWzB,EAAiBwB,EAAKvB,SAAUuB,MAC/D,SAACA,GAAe,OAAAC,EAAI,aAhBI,SAC1BH,GAEA,OAAAA,GAAcQ,EAA0B,EAAGR,GAaPS,CAAoBT,GAAaE,KACnEQ,EANFT,CAOE,CAAEF,QAAOpB,UAASqB,gBAWhBW,EAAsB,SAC1BZ,EACApB,EACAqB,EACAY,GAEA,oBAHAZ,KAGOC,EACJL,EAAYgB,GAETC,GAAK,SAAC7B,OAAEM,SACN,OAAAwB,EAAQxB,GAAQA,EAAKyB,KAAKf,EAAWD,IAAUC,EAAWD,EAAXC,CAAkBV,MAFnE0B,EAASrC,EAAQiC,IAIrBK,EAAU,KACV,SAACC,GACC,OAACtB,EAAYsB,EAAe3B,KAEvBK,EAAYsB,EAAe1B,KAE5B0B,EADAP,EAAoBO,EAAe1B,IAAKb,EAASqB,GAFjDW,EAAoBZ,EAAOpB,EAASqB,EAAYkB,EAAe3B,OAThEU,CAaLtB,mBAwBY,SACdA,EACAwC,EACAnB,GAEA,OAAA,SAAgBD,EAAYqB,GAC1B,OAAOnB,EACLoB,EAAOV,IACP,SAACtB,GACC,OAACO,EAAYP,EAAOiC,OAAwBC,EAAO,OAAQlC,GAA9BA,EAAOiC,QACtCL,EAAUE,GAJLlB,CAMLH,EAAc,CACZC,QACApB,UACAqB,WAAYoB,GAAsBpB"}
\No newline at end of file