{"version":3,"sources":["../../src/mkcert.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { X509Certificate, createPrivateKey } from \"node:crypto\";\nimport { execSync } from \"node:child_process\";\nimport { getCacheDirectory } from \"./get-cache-directory.js\";\nimport { logger } from \"./logger.js\";\nimport { WritableStream } from \"node:stream/web\";\n\nconst MKCERT_VERSION = \"v1.4.4\";\n\nexport interface SelfSignedCertificate {\n  key: string;\n  cert: string;\n  rootCA?: string;\n}\n\nfunction getBinaryName() {\n  const platform = process.platform;\n  const arch = process.arch === \"x64\" ? \"amd64\" : process.arch;\n\n  if (platform === \"win32\") {\n    return `mkcert-${MKCERT_VERSION}-windows-${arch}.exe`;\n  }\n  if (platform === \"darwin\") {\n    return `mkcert-${MKCERT_VERSION}-darwin-${arch}`;\n  }\n  if (platform === \"linux\") {\n    return `mkcert-${MKCERT_VERSION}-linux-${arch}`;\n  }\n\n  throw new Error(`Unsupported platform: ${platform}`);\n}\n\nasync function downloadBinary() {\n  try {\n    const binaryName = getBinaryName();\n    const cacheDirectory = getCacheDirectory(\"mkcert\");\n    const binaryPath = path.join(cacheDirectory, binaryName);\n\n    if (fs.existsSync(binaryPath)) {\n      return binaryPath;\n    }\n\n    const downloadUrl = `https://github.com/FiloSottile/mkcert/releases/download/${MKCERT_VERSION}/${binaryName}`;\n\n    await fs.promises.mkdir(cacheDirectory, { recursive: true });\n\n    logger.info(`Downloading mkcert package...`);\n\n    const response = await fetch(downloadUrl);\n\n    if (!response.ok || !response.body) {\n      throw new Error(`request failed with status ${response.status}`);\n    }\n\n    logger.info(`Download response was successful, writing to disk`);\n\n    const binaryWriteStream = fs.createWriteStream(binaryPath);\n\n    await response.body.pipeTo(\n      new WritableStream({\n        write(chunk) {\n          return new Promise<void>((resolve, reject) => {\n            binaryWriteStream.write(chunk, (error) => {\n              if (error) {\n                reject(error);\n                return;\n              }\n\n              resolve();\n            });\n          });\n        },\n        close() {\n          return new Promise<void>((resolve, reject) => {\n            binaryWriteStream.close((error) => {\n              if (error) {\n                reject(error);\n                return;\n              }\n\n              resolve();\n            });\n          });\n        },\n      }),\n    );\n\n    await fs.promises.chmod(binaryPath, 0o755);\n\n    return binaryPath;\n  } catch (err) {\n    logger.error(\"Error downloading mkcert:\", err);\n  }\n}\n\nexport async function createSelfSignedCertificate(\n  host?: string,\n  certDir: string = \"certificates\",\n): Promise<SelfSignedCertificate | undefined> {\n  try {\n    const binaryPath = await downloadBinary();\n    if (!binaryPath) throw new Error(\"missing mkcert binary\");\n\n    const resolvedCertDir = path.resolve(process.cwd(), `./${certDir}`);\n\n    await fs.promises.mkdir(resolvedCertDir, {\n      recursive: true,\n    });\n\n    const keyPath = path.resolve(resolvedCertDir, \"localhost-key.pem\");\n    const certPath = path.resolve(resolvedCertDir, \"localhost.pem\");\n\n    if (fs.existsSync(keyPath) && fs.existsSync(certPath)) {\n      const cert = new X509Certificate(fs.readFileSync(certPath));\n      const key = fs.readFileSync(keyPath);\n\n      if (\n        cert.checkHost(host ?? \"localhost\") &&\n        cert.checkPrivateKey(createPrivateKey(key))\n      ) {\n        logger.info(\"Using already generated self signed certificate\");\n        const caLocation = execSync(`\"${binaryPath}\" -CAROOT`)\n          .toString()\n          .trim();\n\n        return {\n          key: keyPath,\n          cert: certPath,\n          rootCA: `${caLocation}/rootCA.pem`,\n        };\n      }\n    }\n\n    logger.info(\n      \"Attempting to generate self signed certificate. This may prompt for your password\",\n    );\n\n    const defaultHosts = [\"localhost\", \"127.0.0.1\", \"::1\"];\n\n    const hosts =\n      host && !defaultHosts.includes(host)\n        ? [...defaultHosts, host]\n        : defaultHosts;\n\n    execSync(\n      `\"${binaryPath}\" -install -key-file \"${keyPath}\" -cert-file \"${certPath}\" ${hosts.join(\n        \" \",\n      )}`,\n      { stdio: \"ignore\" },\n    );\n\n    const caLocation = execSync(`\"${binaryPath}\" -CAROOT`).toString().trim();\n\n    if (!fs.existsSync(keyPath) || !fs.existsSync(certPath)) {\n      throw new Error(\"Certificate files not found\");\n    }\n\n    logger.info(`CA Root certificate created in ${caLocation}`);\n    logger.info(`Certificates created in ${resolvedCertDir}`);\n\n    const gitignorePath = path.resolve(process.cwd(), \"./.gitignore\");\n\n    if (fs.existsSync(gitignorePath)) {\n      const gitignore = await fs.promises.readFile(gitignorePath, \"utf8\");\n      if (!gitignore.includes(certDir)) {\n        logger.info(\"Adding certificates to .gitignore\");\n\n        await fs.promises.appendFile(gitignorePath, `\\n${certDir}`);\n      }\n    }\n\n    return {\n      key: keyPath,\n      cert: certPath,\n      rootCA: `${caLocation}/rootCA.pem`,\n    };\n  } catch (err) {\n    logger.error(\n      \"Failed to generate self-signed certificate. Falling back to http.\",\n      err,\n    );\n  }\n}\n"],"names":["createSelfSignedCertificate","MKCERT_VERSION","getBinaryName","platform","process","arch","Error","downloadBinary","binaryName","cacheDirectory","getCacheDirectory","binaryPath","path","join","fs","existsSync","downloadUrl","promises","mkdir","recursive","logger","info","response","fetch","ok","body","status","binaryWriteStream","createWriteStream","pipeTo","WritableStream","write","chunk","Promise","resolve","reject","error","close","chmod","err","host","certDir","resolvedCertDir","cwd","keyPath","certPath","cert","X509Certificate","readFileSync","key","checkHost","checkPrivateKey","createPrivateKey","caLocation","execSync","toString","trim","rootCA","defaultHosts","hosts","includes","stdio","gitignorePath","gitignore","readFile","appendFile"],"mappings":"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"}