{"version":3,"file":"no_undefined_children_for_programmatic_components.cjs","sources":["../../src/rules/no_undefined_children_for_programmatic_components.ts"],"sourcesContent":["/**\n * @module @nhtio/eslint-config/rules/no_undefined_children_for_programmatic_components\n */\n\nimport { createRule } from './common'\n\n/**\n * An ESLint rule that disallows explicitly passing undefined as the children argument in calls to Vue's h function.\n */\nconst noUndefinedChildrenForProgrammaticComponents = createRule({\n  name: 'noUndefinedChildrenForProgrammaticComponents',\n  meta: {\n    type: 'problem',\n    docs: {\n      description:\n        \"Disallow explicitly passing undefined as the children argument in calls to Vue's h function, including when a children function returns an array with undefined values.\",\n    },\n    schema: [],\n    messages: {\n      undefinedChildren: 'The children argument of h() must not be set to undefined.',\n      undefinedChildrenFunction:\n        'The children function of h() returns an array containing undefined values.',\n    },\n  },\n  create(context) {\n    // Helper to detect if a node represents 'undefined'\n    function isUndefined(node: any) {\n      return (\n        node &&\n        ((node.type === 'Identifier' && node.name === 'undefined') ||\n          (node.type === 'UnaryExpression' && node.operator === 'void'))\n      )\n    }\n\n    // Check an array literal for any element that is undefined or conditionally returns undefined.\n    function checkArrayForUndefined(arrayNode: any) {\n      for (const element of arrayNode.elements) {\n        if (!element) continue // Skip holes\n        if (isUndefined(element)) {\n          return true\n        }\n        if (element.type === 'ConditionalExpression') {\n          // For patterns like: condition ? h(...) : undefined\n          if (isUndefined(element.alternate)) {\n            return true\n          }\n        }\n      }\n      return false\n    }\n\n    // Analyze a function used as the children argument.\n    // If the function immediately returns an array (or a filtered array), inspect it.\n    function analyzeFunctionReturn(fnNode: any) {\n      let returnedNode = null\n      // Arrow function with an expression body (or implicit return)\n      if (fnNode.type === 'ArrowFunctionExpression' && fnNode.expression) {\n        returnedNode = fnNode.body\n      } else if (\n        fnNode.type === 'ArrowFunctionExpression' ||\n        fnNode.type === 'FunctionExpression'\n      ) {\n        // Look for a single return statement in block bodies.\n        if (fnNode.body && fnNode.body.type === 'BlockStatement') {\n          for (const statement of fnNode.body.body) {\n            if (statement.type === 'ReturnStatement' && statement.argument) {\n              returnedNode = statement.argument\n              break\n            }\n          }\n        }\n      }\n      if (!returnedNode) {\n        return false\n      }\n      // If the returned node is an array literal, inspect it.\n      if (returnedNode.type === 'ArrayExpression') {\n        return checkArrayForUndefined(returnedNode)\n      }\n      // If the returned node is explicitly undefined.\n      if (isUndefined(returnedNode)) {\n        return true\n      }\n      // If it's a call expression on an array literal (e.g. [ ... ].filter(...)), inspect the array literal.\n      if (returnedNode.type === 'CallExpression') {\n        const callee = returnedNode.callee\n        if (\n          callee &&\n          callee.type === 'MemberExpression' &&\n          callee.object &&\n          callee.object.type === 'ArrayExpression'\n        ) {\n          return checkArrayForUndefined(callee.object)\n        }\n      }\n      return false\n    }\n\n    return {\n      CallExpression(node) {\n        // Check if this is a call to \"h\"\n        if (node.callee && node.callee.type === 'Identifier' && node.callee.name === 'h') {\n          // We expect h(tag, props, children)\n          if (node.arguments.length < 3) {\n            return\n          }\n          const childrenArg = node.arguments[2]\n\n          // Direct check: if children is explicitly undefined.\n          if (isUndefined(childrenArg)) {\n            context.report({\n              node: childrenArg,\n              messageId: 'undefinedChildren',\n            })\n            return\n          }\n\n          // If children is an array, check for undefined elements.\n          if (childrenArg.type === 'ArrayExpression') {\n            if (checkArrayForUndefined(childrenArg)) {\n              context.report({\n                node: childrenArg,\n                messageId: 'undefinedChildren',\n              })\n              return\n            }\n          }\n\n          // If children is a function, try to analyze its return value.\n          if (\n            childrenArg.type === 'ArrowFunctionExpression' ||\n            childrenArg.type === 'FunctionExpression'\n          ) {\n            if (analyzeFunctionReturn(childrenArg)) {\n              context.report({\n                node: childrenArg,\n                messageId: 'undefinedChildrenFunction',\n              })\n              return\n            }\n          }\n        }\n      },\n    }\n  },\n  defaultOptions: [],\n})\n\nexport default noUndefinedChildrenForProgrammaticComponents\n"],"names":["noUndefinedChildrenForProgrammaticComponents","createRule","context","isUndefined","node","checkArrayForUndefined","arrayNode","element","analyzeFunctionReturn","fnNode","returnedNode","statement","callee","childrenArg"],"mappings":"qJASMA,EAA+CC,EAAAA,WAAW,CAC9D,KAAM,+CACN,KAAM,CACJ,KAAM,UACN,KAAM,CACJ,YACE,yKAAA,EAEJ,OAAQ,CAAA,EACR,SAAU,CACR,kBAAmB,6DACnB,0BACE,4EAAA,CACJ,EAEF,OAAOC,EAAS,CAEd,SAASC,EAAYC,EAAW,CAC9B,OACEA,IACEA,EAAK,OAAS,cAAgBA,EAAK,OAAS,aAC3CA,EAAK,OAAS,mBAAqBA,EAAK,WAAa,OAE5D,CAGA,SAASC,EAAuBC,EAAgB,CAC9C,UAAWC,KAAWD,EAAU,SAC9B,GAAKC,IACDJ,EAAYI,CAAO,GAGnBA,EAAQ,OAAS,yBAEfJ,EAAYI,EAAQ,SAAS,GAC/B,MAAO,GAIb,MAAO,EACT,CAIA,SAASC,EAAsBC,EAAa,CAC1C,IAAIC,EAAe,KAEnB,GAAID,EAAO,OAAS,2BAA6BA,EAAO,WACtDC,EAAeD,EAAO,cAEtBA,EAAO,OAAS,2BAChBA,EAAO,OAAS,uBAGZA,EAAO,MAAQA,EAAO,KAAK,OAAS,kBACtC,UAAWE,KAAaF,EAAO,KAAK,KAClC,GAAIE,EAAU,OAAS,mBAAqBA,EAAU,SAAU,CAC9DD,EAAeC,EAAU,SACzB,KACF,EAIN,GAAI,CAACD,EACH,MAAO,GAGT,GAAIA,EAAa,OAAS,kBACxB,OAAOL,EAAuBK,CAAY,EAG5C,GAAIP,EAAYO,CAAY,EAC1B,MAAO,GAGT,GAAIA,EAAa,OAAS,iBAAkB,CAC1C,MAAME,EAASF,EAAa,OAC5B,GACEE,GACAA,EAAO,OAAS,oBAChBA,EAAO,QACPA,EAAO,OAAO,OAAS,kBAEvB,OAAOP,EAAuBO,EAAO,MAAM,CAE/C,CACA,MAAO,EACT,CAEA,MAAO,CACL,eAAeR,EAAM,CAEnB,GAAIA,EAAK,QAAUA,EAAK,OAAO,OAAS,cAAgBA,EAAK,OAAO,OAAS,IAAK,CAEhF,GAAIA,EAAK,UAAU,OAAS,EAC1B,OAEF,MAAMS,EAAcT,EAAK,UAAU,CAAC,EAGpC,GAAID,EAAYU,CAAW,EAAG,CAC5BX,EAAQ,OAAO,CACb,KAAMW,EACN,UAAW,mBAAA,CACZ,EACD,MACF,CAGA,GAAIA,EAAY,OAAS,mBACnBR,EAAuBQ,CAAW,EAAG,CACvCX,EAAQ,OAAO,CACb,KAAMW,EACN,UAAW,mBAAA,CACZ,EACD,MACF,CAIF,IACEA,EAAY,OAAS,2BACrBA,EAAY,OAAS,uBAEjBL,EAAsBK,CAAW,EAAG,CACtCX,EAAQ,OAAO,CACb,KAAMW,EACN,UAAW,2BAAA,CACZ,EACD,MACF,CAEJ,CACF,CAAA,CAEJ,EACA,eAAgB,CAAA,CAClB,CAAC"}