{"version":3,"sources":["../../../../../src/server/typescript/rules/metadata.ts"],"sourcesContent":["import { NEXT_TS_ERRORS } from '../constant'\nimport { getSource, getTs, getTypeChecker } from '../utils'\n\nimport type tsModule from 'typescript/lib/tsserverlibrary'\n\nconst metadata = {\n  client: {\n    getSemanticDiagnosticsForExportVariableStatement(\n      fileName: string,\n      node: tsModule.VariableStatement | tsModule.FunctionDeclaration\n    ): tsModule.Diagnostic[] {\n      const source = getSource(fileName)\n      const ts = getTs()\n\n      // It is not allowed to export `metadata` or `generateMetadata` in client entry\n      if (ts.isFunctionDeclaration(node)) {\n        if (node.name?.getText() === 'generateMetadata') {\n          return [\n            {\n              file: source,\n              category: ts.DiagnosticCategory.Error,\n              code: NEXT_TS_ERRORS.INVALID_METADATA_EXPORT,\n              messageText: `The Next.js 'generateMetadata' API is not allowed in a Client Component.`,\n              start: node.name.getStart(),\n              length: node.name.getWidth(),\n            },\n          ]\n        }\n      } else {\n        for (const declaration of node.declarationList.declarations) {\n          const name = declaration.name.getText()\n          if (name === 'metadata') {\n            return [\n              {\n                file: source,\n                category: ts.DiagnosticCategory.Error,\n                code: NEXT_TS_ERRORS.INVALID_METADATA_EXPORT,\n                messageText: `The Next.js 'metadata' API is not allowed in a Client Component.`,\n                start: declaration.name.getStart(),\n                length: declaration.name.getWidth(),\n              },\n            ]\n          }\n        }\n      }\n      return []\n    },\n    getSemanticDiagnosticsForExportDeclaration(\n      fileName: string,\n      node: tsModule.ExportDeclaration\n    ): tsModule.Diagnostic[] {\n      const ts = getTs()\n      const source = getSource(fileName)\n      const diagnostics: tsModule.Diagnostic[] = []\n\n      const exportClause = node.exportClause\n      if (exportClause && ts.isNamedExports(exportClause)) {\n        for (const e of exportClause.elements) {\n          if (['generateMetadata', 'metadata'].includes(e.name.getText())) {\n            diagnostics.push({\n              file: source,\n              category: ts.DiagnosticCategory.Error,\n              code: NEXT_TS_ERRORS.INVALID_METADATA_EXPORT,\n              messageText: `The Next.js '${e.name.getText()}' API is not allowed in a Client Component.`,\n              start: e.name.getStart(),\n              length: e.name.getWidth(),\n            })\n          }\n        }\n      }\n\n      return diagnostics\n    },\n  },\n  server: {\n    getSemanticDiagnosticsForExportVariableStatement(\n      fileName: string,\n      node: tsModule.VariableStatement | tsModule.FunctionDeclaration\n    ): tsModule.Diagnostic[] {\n      const source = getSource(fileName)\n      const ts = getTs()\n\n      if (ts.isFunctionDeclaration(node)) {\n        if (node.name?.getText() === 'generateMetadata') {\n          if (hasType(node)) {\n            return []\n          }\n\n          const isAsync = node.modifiers?.some(\n            (m) => m.kind === ts.SyntaxKind.AsyncKeyword\n          )\n\n          return [\n            {\n              file: source,\n              category: ts.DiagnosticCategory.Warning,\n              code: NEXT_TS_ERRORS.INVALID_METADATA_EXPORT,\n              messageText: `The Next.js \"generateMetadata\" export should have a return type of ${isAsync ? '\"Promise<Metadata>\"' : '\"Metadata\"'} from \"next\".`,\n              start: node.name.getStart(),\n              length: node.name.getWidth(),\n            },\n          ]\n        }\n      } else {\n        for (const declaration of node.declarationList.declarations) {\n          if (hasType(declaration)) {\n            return []\n          }\n\n          const name = declaration.name.getText()\n          if (name === 'metadata') {\n            return [\n              {\n                file: source,\n                category: ts.DiagnosticCategory.Warning,\n                code: NEXT_TS_ERRORS.INVALID_METADATA_EXPORT,\n                messageText: `The Next.js \"metadata\" export should be type of \"Metadata\" from \"next\".`,\n                start: declaration.name.getStart(),\n                length: declaration.name.getWidth(),\n              },\n            ]\n          }\n          if (name === 'generateMetadata') {\n            // Check if it's a function expression or arrow function\n            if (\n              declaration.initializer &&\n              (ts.isFunctionExpression(declaration.initializer) ||\n                ts.isArrowFunction(declaration.initializer))\n            ) {\n              const isAsync = declaration.initializer.modifiers?.some(\n                (m) => m.kind === ts.SyntaxKind.AsyncKeyword\n              )\n              return [\n                {\n                  file: source,\n                  category: ts.DiagnosticCategory.Warning,\n                  code: NEXT_TS_ERRORS.INVALID_METADATA_EXPORT,\n                  messageText: `The Next.js \"generateMetadata\" export should have a return type of ${isAsync ? '\"Promise<Metadata>\"' : '\"Metadata\"'} from \"next\".`,\n                  start: declaration.name.getStart(),\n                  length: declaration.name.getWidth(),\n                },\n              ]\n            }\n          }\n        }\n      }\n      return []\n    },\n    getSemanticDiagnosticsForExportDeclaration(\n      fileName: string,\n      node: tsModule.ExportDeclaration\n    ) {\n      const typeChecker = getTypeChecker()\n      if (!typeChecker) {\n        return []\n      }\n\n      const ts = getTs()\n      const source = getSource(fileName)\n      const diagnostics: tsModule.Diagnostic[] = []\n\n      const exportClause = node.exportClause\n      if (!node.isTypeOnly && exportClause && ts.isNamedExports(exportClause)) {\n        for (const e of exportClause.elements) {\n          if (e.isTypeOnly) {\n            continue\n          }\n          const exportName = e.name.getText()\n          if (exportName !== 'metadata' && exportName !== 'generateMetadata') {\n            continue\n          }\n\n          const symbol = typeChecker.getSymbolAtLocation(e.name)\n          if (!symbol) {\n            continue\n          }\n\n          const originalSymbol = typeChecker.getAliasedSymbol(symbol)\n          const declarations = originalSymbol.getDeclarations()\n          if (!declarations) {\n            continue\n          }\n\n          const declaration = declarations[0]\n          if (hasType(declaration)) {\n            continue\n          }\n\n          if (exportName === 'generateMetadata') {\n            let isAsync = false\n\n            // async function() {}\n            if (ts.isFunctionDeclaration(declaration)) {\n              isAsync =\n                declaration.modifiers?.some(\n                  (m) => m.kind === ts.SyntaxKind.AsyncKeyword\n                ) ?? false\n            }\n\n            // foo = async function() {}\n            // foo = async () => {}\n            if (\n              ts.isVariableDeclaration(declaration) &&\n              declaration.initializer\n            ) {\n              const initializer = declaration.initializer\n              const isFunction =\n                ts.isArrowFunction(initializer) ||\n                ts.isFunctionExpression(initializer)\n\n              if (isFunction) {\n                isAsync =\n                  initializer.modifiers?.some(\n                    (m) => m.kind === ts.SyntaxKind.AsyncKeyword\n                  ) ?? false\n              }\n            }\n\n            diagnostics.push({\n              file: source,\n              category: ts.DiagnosticCategory.Warning,\n              code: NEXT_TS_ERRORS.INVALID_METADATA_EXPORT,\n              messageText: `The Next.js \"generateMetadata\" export should have a return type of ${isAsync ? '\"Promise<Metadata>\"' : '\"Metadata\"'} from \"next\".`,\n              start: e.name.getStart(),\n              length: e.name.getWidth(),\n            })\n          } else {\n            diagnostics.push({\n              file: source,\n              category: ts.DiagnosticCategory.Warning,\n              code: NEXT_TS_ERRORS.INVALID_METADATA_EXPORT,\n              messageText: `The Next.js \"metadata\" export should be type of \"Metadata\" from \"next\".`,\n              start: e.name.getStart(),\n              length: e.name.getWidth(),\n            })\n          }\n        }\n      }\n      return diagnostics\n    },\n  },\n}\n\nfunction hasType(node: tsModule.Declaration): boolean {\n  const ts = getTs()\n\n  if (\n    !ts.isVariableDeclaration(node) &&\n    !ts.isFunctionDeclaration(node) &&\n    !ts.isArrowFunction(node) &&\n    !ts.isFunctionExpression(node)\n  ) {\n    return false\n  }\n\n  // For function declarations, expressions, and arrow functions, check if they have return type\n  if (\n    ts.isFunctionDeclaration(node) ||\n    ts.isFunctionExpression(node) ||\n    ts.isArrowFunction(node)\n  ) {\n    return !!node.type\n  }\n\n  // For variable declarations\n  if (!node.name) return false\n  const name = node.name.getText()\n  if (name === 'generateMetadata') {\n    // If it's a function expression or arrow function, check if it has return type\n    if (\n      node.initializer &&\n      (ts.isFunctionExpression(node.initializer) ||\n        ts.isArrowFunction(node.initializer))\n    ) {\n      return !!node.initializer.type\n    }\n  }\n\n  // For all other cases, check if the node has a type annotation\n  return !!node.type\n}\n\nexport default metadata\n"],"names":["NEXT_TS_ERRORS","getSource","getTs","getTypeChecker","metadata","client","getSemanticDiagnosticsForExportVariableStatement","fileName","node","source","ts","isFunctionDeclaration","name","getText","file","category","DiagnosticCategory","Error","code","INVALID_METADATA_EXPORT","messageText","start","getStart","length","getWidth","declaration","declarationList","declarations","getSemanticDiagnosticsForExportDeclaration","diagnostics","exportClause","isNamedExports","e","elements","includes","push","server","hasType","isAsync","modifiers","some","m","kind","SyntaxKind","AsyncKeyword","Warning","initializer","isFunctionExpression","isArrowFunction","typeChecker","isTypeOnly","exportName","symbol","getSymbolAtLocation","originalSymbol","getAliasedSymbol","getDeclarations","isVariableDeclaration","isFunction","type"],"mappings":"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","ignoreList":[0]}