'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); const index = require('./shared/gpt-runner-shared.79ccd90a.cjs'); require('minimatch'); require('debug'); const axios = require('axios'); const httpProxyAgent = require('http-proxy-agent'); const httpsProxyAgent = require('https-proxy-agent'); const node_child_process = require('node:child_process'); const fs = require('node:fs'); const os = require('node:os'); const path = require('node:path'); const getCacheDir = require('cachedir'); const node_url = require('node:url'); require('jsonc-parser'); const launch = require('launch-editor'); const nodeLocalstorage = require('@kvs/node-localstorage'); const open = require('open'); const fp = require('find-free-ports'); const ip = require('ip'); const undici = require('undici'); require('web-streams-polyfill/polyfill'); require('zod-to-json-schema'); require('zod'); function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e["default"] : e; } const axios__default = /*#__PURE__*/_interopDefaultLegacy(axios); const fs__default = /*#__PURE__*/_interopDefaultLegacy(fs); const os__default = /*#__PURE__*/_interopDefaultLegacy(os); const path__default = /*#__PURE__*/_interopDefaultLegacy(path); const getCacheDir__default = /*#__PURE__*/_interopDefaultLegacy(getCacheDir); const launch__default = /*#__PURE__*/_interopDefaultLegacy(launch); const open__default = /*#__PURE__*/_interopDefaultLegacy(open); const fp__default = /*#__PURE__*/_interopDefaultLegacy(fp); const ip__default = /*#__PURE__*/_interopDefaultLegacy(ip); function initAxios() { const httpProxyUrl = process.env.HTTP_PROXY; const httpsProxyUrl = process.env.HTTPS_PROXY; if (httpProxyUrl) { const httpAgent = new httpProxyAgent.HttpProxyAgent(httpProxyUrl); axios__default.defaults.httpAgent = httpAgent; } if (httpsProxyUrl) { const httpsAgent = new httpsProxyAgent.HttpsProxyAgent(httpsProxyUrl); axios__default.defaults.httpsAgent = httpsAgent; } } let axiosInstance = null; function getAxiosInstance() { if (!axiosInstance) { initAxios(); axiosInstance = axios__default.create(); } return axiosInstance; } class PathUtils { static getCurrentDirName(importMetaUrl, getDirname) { let dirname = ""; try { dirname = getDirname(); } catch { } if (!importMetaUrl) return index.toUnixPath(dirname); const __filename = node_url.fileURLToPath(importMetaUrl); const __dirname = path__default.dirname(__filename); return __dirname; } static join(...paths) { return index.toUnixPath(path__default.join(...paths)); } static resolve(...paths) { return index.toUnixPath(path__default.resolve(...paths)); } static relative(from, to) { return index.toUnixPath(path__default.relative(from, to)); } static dirname(filePath) { return index.toUnixPath(path__default.dirname(filePath)); } static extname(filePath) { if (!PathUtils.isFile(filePath)) return ""; return path__default.extname(filePath); } static isFile(filePath) { return fs__default.existsSync(filePath) && fs__default.statSync(filePath).isFile(); } static isDirectory(filePath) { return fs__default.existsSync(filePath) && fs__default.statSync(filePath).isDirectory(); } static includeExt(filePath, exts) { if (!exts || !Array.isArray(exts)) return false; return exts.some((ext) => filePath.endsWith(ext)); } static isExit(filePath) { return fs__default.existsSync(filePath); } static isAccessible(filePath, mode) { if (!PathUtils.isExit(filePath)) return false; const modeMap = { F: fs__default.constants.F_OK, R: fs__default.constants.R_OK, W: fs__default.constants.W_OK, X: fs__default.constants.X_OK }; const finalMode = modeMap[mode || "F"] || fs__default.constants.F_OK; try { fs__default.accessSync(filePath, finalMode); return true; } catch (err) { return false; } } static getDirPath(filePath) { return path__default.dirname(filePath); } } async function getGlobalCacheDir(name) { const cacheDir = getCacheDir__default(name); await createCacheDir(cacheDir); return cacheDir; } async function createCacheDir(cacheDir) { if (await PathUtils.isAccessible(cacheDir, "W")) return; await fs__default.promises.mkdir(cacheDir, { recursive: true }); } const _BinaryDownloader = class { static async getBinaryPath() { const cacheDir = await getGlobalCacheDir("nicepkg-tunnel"); const binaryPath = path__default.join(cacheDir, _BinaryDownloader.BINARY_FILENAME); return binaryPath; } static async downloadBinary() { const debug = new index.Debug("tunnel"); const binaryPath = await _BinaryDownloader.getBinaryPath(); if (!fs__default.existsSync(binaryPath)) { const binaryUrl = `https://cdn-media.huggingface.co/frpc-gradio-${_BinaryDownloader.VERSION}/${_BinaryDownloader.BINARY_NAME}${_BinaryDownloader.EXTENSION}`; debug.log(`Downloading ${binaryUrl} to ${binaryPath}...`); try { const axios = getAxiosInstance(); const response = await axios.get(binaryUrl, { responseType: "arraybuffer" }); await fs__default.promises.writeFile(binaryPath, response.data, "binary"); fs__default.chmodSync(binaryPath, 493); debug.log(`Downloaded success ${binaryUrl} to ${binaryPath}`); } catch (err) { debug.error(`Failed to download ${binaryUrl}: ${err}`); if (err?.response?.status === 403) { throw new Error( `Cannot set up a share link as this platform is incompatible. Please create a GitHub issue with information about your platform: ${JSON.stringify( os__default.userInfo() )}` ); } throw err; } } } }; let BinaryDownloader = _BinaryDownloader; BinaryDownloader.VERSION = "0.2"; BinaryDownloader.EXTENSION = os__default.platform() === "win32" ? ".exe" : ""; BinaryDownloader.MACHINE = os__default.arch(); BinaryDownloader.ARCH = _BinaryDownloader.MACHINE === "x64" ? "amd64" : _BinaryDownloader.MACHINE; BinaryDownloader.BINARY_NAME = `frpc_${os__default.type().toLowerCase()}_${_BinaryDownloader.ARCH.toLowerCase()}`; BinaryDownloader.BINARY_FILENAME = `${_BinaryDownloader.BINARY_NAME}_v${_BinaryDownloader.VERSION}`; class TunnelProcess { constructor(command) { this.proc = null; this.command = command; } async start() { const binaryPath = await BinaryDownloader.getBinaryPath(); await BinaryDownloader.downloadBinary(); return this._startProcess(binaryPath); } kill() { if (this.proc !== null) { this.proc.kill("SIGTERM"); this.proc = null; } } _startProcess(binary) { return new Promise((resolve, reject) => { this.proc = node_child_process.spawn(binary, this.command, { stdio: ["ignore", "pipe", "pipe"] }); process.once("exit", () => this.kill()); let output = ""; this.proc.stdout.on("data", (data) => { output += data.toString(); const match = output.match(/start proxy success: (.+)/); if (match) { resolve(match[1]); output = ""; } }); this.proc.stderr.on("data", (data) => { output += data.toString(); }); this.proc.on("error", (err) => { reject(err); }); }); } } class Tunnel { constructor(options) { this.GRADIO_API_SERVER_URL = "https://api.gradio.app/v2/tunnel-request"; const { remoteHost, remotePort, localHost, localPort, shareToken } = options; this.url = null; this.remoteHost = remoteHost || ""; this.remotePort = remotePort || 0; this.localHost = localHost || "localhost"; this.localPort = localPort; this.shareToken = shareToken || ""; } async initProcess() { if (!this.remoteHost || !this.remotePort) { try { const axios = getAxiosInstance(); const res = await axios.get(this.GRADIO_API_SERVER_URL); const data = res.data; this.remoteHost = data[0].host; this.remotePort = data[0].port; } catch (err) { throw new Error(`Failed to fetch ${this.GRADIO_API_SERVER_URL}: ${index.getErrorMsg(err)}`); } } const command = [ "http", "-n", this.shareToken, "-l", `${this.localPort}`, "-i", this.localHost, "--uc", "--sd", "random", "--ue", "--server_addr", `${this.remoteHost}:${this.remotePort}`, "--disable_log_color" ]; this.tunnelProcess = new TunnelProcess(command); } async startTunnel() { if (!this.tunnelProcess) await this.initProcess(); this.url = await this.tunnelProcess.start(); return this.url; } kill() { if (this.tunnelProcess) { console.log( `Killing tunnel ${this.localHost}:${this.localPort} <> ${this.url}` ); this.tunnelProcess.kill(); } } } function compareVersion(a, b) { const aParts = a.split("."); const bParts = b.split("."); const len = Math.max(aParts.length, bParts.length); const stringToNum = (str) => parseInt(str.match(/\d+/)?.[0] || "0") || 0; for (let i = 0; i < len; i++) { const aPart = stringToNum(aParts[i]) || 0; const bPart = stringToNum(bParts[i]) || 0; if (aPart > bPart) return 1; if (aPart < bPart) return -1; } return 0; } function checkNodeVersion() { const currentNodeVersion = process.version; if (compareVersion(currentNodeVersion, index.MIN_NODE_VERSION) < 0) return `You are using Node ${currentNodeVersion}, but GPT-Runner requires Node ${index.MIN_NODE_VERSION}. Please upgrade your Node version in https://nodejs.org/en/download`; } function canUseNodeFetchWithoutCliFlag() { const currentNodeVersion = process.version; return compareVersion(currentNodeVersion, "18.0.0") > 0; } function getRunServerEnv() { if (!canUseNodeFetchWithoutCliFlag()) { return { NODE_OPTIONS: "--experimental-fetch", NODE_NO_WARNINGS: "1" }; } return {}; } class FileUtils { static async readFile(params) { const { filePath, valid = true } = params; if (typeof filePath !== "string") return ""; if (valid && !PathUtils.isFile(filePath)) return ""; if (!filePath) return ""; return fs.promises.readFile(filePath, { encoding: "utf8" }); } static async writeFile(params) { const { filePath, content, overwrite = true, valid = true } = params; if (valid) { if (!PathUtils.isAccessible(filePath, "W")) return; if (!PathUtils.isFile(filePath)) return; } const dir = PathUtils.getDirPath(filePath); if (!PathUtils.isExit(dir)) await fs.promises.mkdir(dir, { recursive: true }); if (overwrite) await fs.promises.writeFile(filePath, content, { encoding: "utf8" }); else await fs.promises.appendFile(filePath, content, { encoding: "utf8" }); } static async deletePath(fullPath) { if (!PathUtils.isAccessible(fullPath, "W")) await fs.promises.rm(fullPath, { recursive: true }); } static async ensurePath(params) { const { filePath } = params; if (!PathUtils.isAccessible(filePath, "W")) await fs.promises.mkdir(filePath, { recursive: true }); } static async movePath(params) { const { oldPath, newPath } = params; if (PathUtils.isAccessible(oldPath, "W")) await fs.promises.rename(oldPath, newPath); } static async travelFiles(params) { const { isValidPath, callback } = params; const filePath = PathUtils.resolve(params.filePath); if (!PathUtils.isAccessible(filePath, "R")) return; const promises = []; if (PathUtils.isDirectory(filePath)) { const entries = await fs.promises.readdir(filePath); for (const entry of entries) { const fullPath = PathUtils.join(filePath, entry); if (!PathUtils.isAccessible(filePath, "R")) continue; const isValid = await isValidPath(fullPath); if (isValid) promises.push(FileUtils.travelFiles({ filePath: fullPath, isValidPath, callback })); } } else { const result = callback(filePath); if (result instanceof Promise) promises.push(result); } await Promise.allSettled(promises); } static async travelFilesByFilterPattern(params) { const { filePath, isValidPath, callback, exts = [], includes = null, excludes = null } = params; await FileUtils.travelFiles({ filePath, isValidPath: async (filePath2) => { if (exts.length > 0 && PathUtils.isFile(filePath2) && !PathUtils.includeExt(filePath2, exts)) return false; if (!index.createFilterByPattern(includes)(filePath2)) return false; if (index.createFilterByPattern(excludes)(filePath2)) return false; if (!isValidPath(filePath2)) return false; return true; }, callback }); } } async function launchEditor(params) { return new Promise((resolve, reject) => { const { path, lineNum, columnNum = 0, editorName, onError } = params; const finalPath = lineNum && columnNum ? `${path}:${lineNum}:${columnNum}` : path; launch__default(finalPath, editorName, (error) => { if (error) { onError?.(error); reject(error); } }); resolve(); }); } async function launchEditorByPathAndContent(params) { const { path, matchContent, editorName, onError } = params; const content = await FileUtils.readFile({ filePath: path }); let lineNum = 0; let columnNum = 0; if (matchContent) { const matchContentStartIndex = content.indexOf(matchContent); if (matchContentStartIndex !== -1) { const beforeMatchContent = content.slice(0, matchContentStartIndex); lineNum = beforeMatchContent.split("\n").length; columnNum = matchContentStartIndex - beforeMatchContent.lastIndexOf("\n"); } } await launchEditor({ path, lineNum, columnNum, editorName, onError }); return { lineNum, columnNum }; } async function getStorage(storageName) { const cacheFolder = await getGlobalCacheDir("gpt-runner-server"); const storage = await nodeLocalstorage.kvsLocalStorage({ name: storageName, storeFilePath: cacheFolder, version: 1 }); return { cacheDir: cacheFolder, storage }; } function openInBrowser(props) { const { url } = props; try { open__default(url); } catch (error) { throw new Error(`Server is started at ${url} but failed to open browser. ${error}`); } } async function getPort(props) { const { defaultPort, autoFreePort, excludePorts } = props; if (defaultPort) { if (!autoFreePort) return defaultPort; const canUseDefaultPort = await fp__default.isFreePort(defaultPort); if (canUseDefaultPort) return defaultPort; } const freePorts = await fp__default.findFreePorts(1, { startPort: 3001, endPort: 9999, isFree: async (port) => { if (excludePorts?.includes(port)) return false; return fp__default.isFreePort(port); } }); return freePorts[0]; } function getLocalHostname() { return ip__default.address("public", "ipv4"); } function addNodejsPolyfill() { if (!canUseNodeFetchWithoutCliFlag()) { console.log("GPT Runner: add polyfill for fetch", process.version); globalThis.fetch = undici.fetch; globalThis.Headers = undici.Headers; globalThis.Request = undici.Request; globalThis.Response = undici.Response; } } async function getDefaultProxyUrl() { let proxyUrl = ""; try { const { storage } = await getStorage(index.ServerStorageName.SecretsConfig); const proxySecret = await storage.get(index.SecretStorageKey.Proxy); proxyUrl = proxySecret?.proxyUrl ?? ""; } catch (error) { console.error("getDefaultProxyUrl error", error); } if (proxyUrl) return proxyUrl; ["HTTP_PROXY", "HTTPS_PROXY", "ALL_PROXY"].forEach((key) => { if (proxyUrl) return; const upperKey = key.toUpperCase(); const lowerKey = key.toLowerCase(); const upperKeyValue = process.env[upperKey] && process.env[upperKey] !== "undefined" ? process.env[upperKey] || "" : ""; const lowerKeyValue = process.env[lowerKey] && process.env[lowerKey] !== "undefined" ? process.env[lowerKey] || "" : ""; return proxyUrl = upperKeyValue || lowerKeyValue || ""; }); return proxyUrl; } function sendSuccessResponse(res, options) { return res.status(options.status || 200).json(index.buildSuccessResponse(options)); } function sendFailResponse(res, options) { return res.status(options.status || 400).json(index.buildFailResponse(options)); } function verifyParamsByZod(params, schema) { index.verifyZod(schema, params); } exports.FileUtils = FileUtils; exports.PathUtils = PathUtils; exports.Tunnel = Tunnel; exports.addNodejsPolyfill = addNodejsPolyfill; exports.canUseNodeFetchWithoutCliFlag = canUseNodeFetchWithoutCliFlag; exports.checkNodeVersion = checkNodeVersion; exports.compareVersion = compareVersion; exports.getDefaultProxyUrl = getDefaultProxyUrl; exports.getGlobalCacheDir = getGlobalCacheDir; exports.getLocalHostname = getLocalHostname; exports.getPort = getPort; exports.getRunServerEnv = getRunServerEnv; exports.getStorage = getStorage; exports.launchEditor = launchEditor; exports.launchEditorByPathAndContent = launchEditorByPathAndContent; exports.openInBrowser = openInBrowser; exports.sendFailResponse = sendFailResponse; exports.sendSuccessResponse = sendSuccessResponse; exports.verifyParamsByZod = verifyParamsByZod;