{"version":3,"sources":["../../../../src/server/typescript/rules/server-boundary.ts"],"sourcesContent":["// This module provides intellisense for all exports from `\"use server\"` directive.\n\nimport { NEXT_TS_ERRORS } from '../constant'\nimport { getTs, getTypeChecker } from '../utils'\nimport type tsModule from 'typescript/lib/tsserverlibrary'\n\n// Check if the type is `Promise<T>`.\nfunction isPromiseType(type: tsModule.Type, typeChecker: tsModule.TypeChecker) {\n  const typeReferenceType = type as tsModule.TypeReference\n  if (!typeReferenceType.target) return false\n\n  // target should be Promise or Promise<...>\n  if (\n    !/^Promise(<.+>)?$/.test(typeChecker.typeToString(typeReferenceType.target))\n  ) {\n    return false\n  }\n\n  return true\n}\n\nfunction isFunctionReturningPromise(\n  node: tsModule.Node,\n  typeChecker: tsModule.TypeChecker,\n  ts: typeof tsModule\n) {\n  const type = typeChecker.getTypeAtLocation(node)\n  const signatures = typeChecker.getSignaturesOfType(\n    type,\n    ts.SignatureKind.Call\n  )\n\n  let isPromise = true\n  if (signatures.length) {\n    for (const signature of signatures) {\n      const returnType = signature.getReturnType()\n      if (returnType.isUnion()) {\n        for (const t of returnType.types) {\n          if (!isPromiseType(t, typeChecker)) {\n            isPromise = false\n            break\n          }\n        }\n      } else {\n        isPromise = isPromiseType(returnType, typeChecker)\n      }\n    }\n  } else {\n    isPromise = false\n  }\n\n  return isPromise\n}\n\nconst serverBoundary = {\n  getSemanticDiagnosticsForExportDeclaration(\n    source: tsModule.SourceFile,\n    node: tsModule.ExportDeclaration\n  ) {\n    const ts = getTs()\n    const typeChecker = getTypeChecker()\n    if (!typeChecker) return []\n\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        if (!isFunctionReturningPromise(e, typeChecker, ts)) {\n          diagnostics.push({\n            file: source,\n            category: ts.DiagnosticCategory.Error,\n            code: NEXT_TS_ERRORS.INVALID_SERVER_ENTRY_RETURN,\n            messageText: `The \"use server\" file can only export async functions.`,\n            start: e.getStart(),\n            length: e.getWidth(),\n          })\n        }\n      }\n    }\n\n    return diagnostics\n  },\n\n  getSemanticDiagnosticsForExportVariableStatement(\n    source: tsModule.SourceFile,\n    node: tsModule.VariableStatement\n  ) {\n    const ts = getTs()\n\n    const diagnostics: tsModule.Diagnostic[] = []\n\n    if (ts.isVariableDeclarationList(node.declarationList)) {\n      for (const declaration of node.declarationList.declarations) {\n        const initializer = declaration.initializer\n        if (\n          initializer &&\n          (ts.isArrowFunction(initializer) ||\n            ts.isFunctionDeclaration(initializer) ||\n            ts.isFunctionExpression(initializer) ||\n            ts.isCallExpression(initializer) ||\n            ts.isIdentifier(initializer))\n        ) {\n          diagnostics.push(\n            ...serverBoundary.getSemanticDiagnosticsForFunctionExport(\n              source,\n              initializer\n            )\n          )\n        } else {\n          diagnostics.push({\n            file: source,\n            category: ts.DiagnosticCategory.Error,\n            code: NEXT_TS_ERRORS.INVALID_SERVER_ENTRY_RETURN,\n            messageText: `The \"use server\" file can only export async functions.`,\n            start: declaration.getStart(),\n            length: declaration.getWidth(),\n          })\n        }\n      }\n    }\n\n    return diagnostics\n  },\n\n  getSemanticDiagnosticsForFunctionExport(\n    source: tsModule.SourceFile,\n    node:\n      | tsModule.FunctionDeclaration\n      | tsModule.ArrowFunction\n      | tsModule.FunctionExpression\n      | tsModule.CallExpression\n      | tsModule.Identifier\n  ) {\n    const ts = getTs()\n    const typeChecker = getTypeChecker()\n    if (!typeChecker) return []\n\n    const diagnostics: tsModule.Diagnostic[] = []\n\n    if (!isFunctionReturningPromise(node, typeChecker, ts)) {\n      diagnostics.push({\n        file: source,\n        category: ts.DiagnosticCategory.Error,\n        code: NEXT_TS_ERRORS.INVALID_SERVER_ENTRY_RETURN,\n        messageText: `The \"use server\" file can only export async functions. Add \"async\" to the function declaration or return a Promise.`,\n        start: node.getStart(),\n        length: node.getWidth(),\n      })\n    }\n\n    return diagnostics\n  },\n}\n\nexport default serverBoundary\n"],"names":["isPromiseType","type","typeChecker","typeReferenceType","target","test","typeToString","isFunctionReturningPromise","node","ts","getTypeAtLocation","signatures","getSignaturesOfType","SignatureKind","Call","isPromise","length","signature","returnType","getReturnType","isUnion","t","types","serverBoundary","getSemanticDiagnosticsForExportDeclaration","source","getTs","getTypeChecker","diagnostics","exportClause","isTypeOnly","isNamedExports","e","elements","push","file","category","DiagnosticCategory","Error","code","NEXT_TS_ERRORS","INVALID_SERVER_ENTRY_RETURN","messageText","start","getStart","getWidth","getSemanticDiagnosticsForExportVariableStatement","isVariableDeclarationList","declarationList","declaration","declarations","initializer","isArrowFunction","isFunctionDeclaration","isFunctionExpression","isCallExpression","isIdentifier","getSemanticDiagnosticsForFunctionExport"],"mappings":"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","ignoreList":[0]}