{"version":3,"file":"route-param-names.rule.cjs","names":[],"sources":["../../../../src/rules/route-param-names/route-param-names.rule.ts"],"sourcesContent":["import { AST_NODE_TYPES, ESLintUtils } from '@typescript-eslint/utils'\n\nimport { getDocsUrl } from '../../utils/get-docs-url'\nimport { detectTanstackRouterImports } from '../../utils/detect-router-imports'\nimport { getInvalidParams } from './route-param-names.utils'\nimport { pathAsFirstArgFunctions, pathAsPropertyFunctions } from './constants'\nimport type { TSESTree } from '@typescript-eslint/utils'\nimport type { ExtraRuleDocs } from '../../types'\n\nconst createRule = ESLintUtils.RuleCreator<ExtraRuleDocs>(getDocsUrl)\n\nconst pathAsFirstArgSet = new Set<string>(pathAsFirstArgFunctions)\nconst pathAsPropertySet = new Set<string>(pathAsPropertyFunctions)\n\nexport const name = 'route-param-names'\n\nexport const rule = createRule({\n  name,\n  meta: {\n    type: 'problem',\n    docs: {\n      description: 'Ensure route param names are valid JavaScript identifiers',\n      recommended: 'error',\n    },\n    messages: {\n      invalidParamName:\n        'Invalid param name \"{{paramName}}\" in route path. Param names must be valid JavaScript identifiers (match /[a-zA-Z_$][a-zA-Z0-9_$]*/).',\n    },\n    schema: [],\n  },\n  defaultOptions: [],\n\n  create: detectTanstackRouterImports((context, _, helpers) => {\n    function reportInvalidParams(node: TSESTree.Node, path: string) {\n      const invalidParams = getInvalidParams(path)\n\n      for (const param of invalidParams) {\n        context.report({\n          node,\n          messageId: 'invalidParamName',\n          data: { paramName: param.paramName },\n        })\n      }\n    }\n\n    function getStringLiteralValue(node: TSESTree.Node): string | null {\n      if (\n        node.type === AST_NODE_TYPES.Literal &&\n        typeof node.value === 'string'\n      ) {\n        return node.value\n      }\n      if (\n        node.type === AST_NODE_TYPES.TemplateLiteral &&\n        node.quasis.length === 1\n      ) {\n        const cooked = node.quasis[0]?.value.cooked\n        if (cooked != null) {\n          return cooked\n        }\n      }\n      return null\n    }\n\n    return {\n      CallExpression(node) {\n        // Handle direct function call: createRoute({ path: '...' })\n        if (node.callee.type === AST_NODE_TYPES.Identifier) {\n          const funcName = node.callee.name\n\n          // Skip if not imported from TanStack Router\n          if (!helpers.isTanstackRouterImport(node.callee)) {\n            return\n          }\n\n          // Case: createRoute({ path: '/path/$param' }) or createRoute({ 'path': '/path/$param' })\n          if (pathAsPropertySet.has(funcName)) {\n            const arg = node.arguments[0]\n            if (arg?.type === AST_NODE_TYPES.ObjectExpression) {\n              for (const prop of arg.properties) {\n                if (prop.type === AST_NODE_TYPES.Property) {\n                  const isPathKey =\n                    (prop.key.type === AST_NODE_TYPES.Identifier &&\n                      prop.key.name === 'path') ||\n                    (prop.key.type === AST_NODE_TYPES.Literal &&\n                      prop.key.value === 'path')\n                  if (isPathKey) {\n                    const pathValue = getStringLiteralValue(prop.value)\n                    if (pathValue) {\n                      reportInvalidParams(prop.value, pathValue)\n                    }\n                  }\n                }\n              }\n            }\n            return\n          }\n        }\n\n        // Handle curried function call: createFileRoute('/path')({ ... })\n        if (node.callee.type === AST_NODE_TYPES.CallExpression) {\n          const innerCall = node.callee\n\n          if (innerCall.callee.type === AST_NODE_TYPES.Identifier) {\n            const funcName = innerCall.callee.name\n\n            // Skip if not imported from TanStack Router\n            if (!helpers.isTanstackRouterImport(innerCall.callee)) {\n              return\n            }\n\n            // Case: createFileRoute('/path/$param')(...) or similar\n            if (pathAsFirstArgSet.has(funcName)) {\n              const pathArg = innerCall.arguments[0]\n              if (pathArg) {\n                const pathValue = getStringLiteralValue(pathArg)\n                if (pathValue) {\n                  reportInvalidParams(pathArg, pathValue)\n                }\n              }\n            }\n          }\n        }\n      },\n    }\n  }),\n})\n"],"mappings":";;;;;;AASA,IAAM,aAAa,yBAAA,YAAY,YAA2B,qBAAA,WAAW;AAErE,IAAM,oBAAoB,IAAI,IAAY,kBAAA,wBAAwB;AAClE,IAAM,oBAAoB,IAAI,IAAY,kBAAA,wBAAwB;AAElE,IAAa,OAAO;AAEpB,IAAa,OAAO,WAAW;CAC7B;CACA,MAAM;EACJ,MAAM;EACN,MAAM;GACJ,aAAa;GACb,aAAa;GACd;EACD,UAAU,EACR,kBACE,4IACH;EACD,QAAQ,EAAE;EACX;CACD,gBAAgB,EAAE;CAElB,QAAQ,8BAAA,6BAA6B,SAAS,GAAG,YAAY;EAC3D,SAAS,oBAAoB,MAAqB,MAAc;GAC9D,MAAM,gBAAgB,gCAAA,iBAAiB,KAAK;AAE5C,QAAK,MAAM,SAAS,cAClB,SAAQ,OAAO;IACb;IACA,WAAW;IACX,MAAM,EAAE,WAAW,MAAM,WAAW;IACrC,CAAC;;EAIN,SAAS,sBAAsB,MAAoC;AACjE,OACE,KAAK,SAAS,yBAAA,eAAe,WAC7B,OAAO,KAAK,UAAU,SAEtB,QAAO,KAAK;AAEd,OACE,KAAK,SAAS,yBAAA,eAAe,mBAC7B,KAAK,OAAO,WAAW,GACvB;IACA,MAAM,SAAS,KAAK,OAAO,IAAI,MAAM;AACrC,QAAI,UAAU,KACZ,QAAO;;AAGX,UAAO;;AAGT,SAAO,EACL,eAAe,MAAM;AAEnB,OAAI,KAAK,OAAO,SAAS,yBAAA,eAAe,YAAY;IAClD,MAAM,WAAW,KAAK,OAAO;AAG7B,QAAI,CAAC,QAAQ,uBAAuB,KAAK,OAAO,CAC9C;AAIF,QAAI,kBAAkB,IAAI,SAAS,EAAE;KACnC,MAAM,MAAM,KAAK,UAAU;AAC3B,SAAI,KAAK,SAAS,yBAAA,eAAe;WAC1B,MAAM,QAAQ,IAAI,WACrB,KAAI,KAAK,SAAS,yBAAA,eAAe;WAE5B,KAAK,IAAI,SAAS,yBAAA,eAAe,cAChC,KAAK,IAAI,SAAS,UACnB,KAAK,IAAI,SAAS,yBAAA,eAAe,WAChC,KAAK,IAAI,UAAU,QACR;QACb,MAAM,YAAY,sBAAsB,KAAK,MAAM;AACnD,YAAI,UACF,qBAAoB,KAAK,OAAO,UAAU;;;;AAMpD;;;AAKJ,OAAI,KAAK,OAAO,SAAS,yBAAA,eAAe,gBAAgB;IACtD,MAAM,YAAY,KAAK;AAEvB,QAAI,UAAU,OAAO,SAAS,yBAAA,eAAe,YAAY;KACvD,MAAM,WAAW,UAAU,OAAO;AAGlC,SAAI,CAAC,QAAQ,uBAAuB,UAAU,OAAO,CACnD;AAIF,SAAI,kBAAkB,IAAI,SAAS,EAAE;MACnC,MAAM,UAAU,UAAU,UAAU;AACpC,UAAI,SAAS;OACX,MAAM,YAAY,sBAAsB,QAAQ;AAChD,WAAI,UACF,qBAAoB,SAAS,UAAU;;;;;KAOpD;GACD;CACH,CAAC"}