| 74 | } |
| 75 | |
| 76 | function fetchLatestVersion(pkg) { |
| 77 | const registry = (pkg.publishConfig && pkg.publishConfig.registry) || DEFAULT_REGISTRY; |
| 78 | const pkgName = pkg.name; |
| 79 | if (!pkgName) return Promise.resolve(null); |
| 80 | const encodedName = pkgName.replace(/\//g, "%2F"); |
| 81 | const url = `${registry.replace(/\/$/, "")}/${encodedName}/latest`; |
| 82 | if (!url.startsWith("https://")) return Promise.resolve(null); |
| 83 | |
| 84 | return new Promise((resolve) => { |
| 85 | const options = { |
| 86 | headers: { "User-Agent": "ocr-updater", Accept: "application/json" }, |
| 87 | timeout: 15000, |
| 88 | }; |
| 89 | const req = https |
| 90 | .get(url, options, (res) => { |
| 91 | if (res.statusCode !== 200) { |
| 92 | res.resume(); |
| 93 | resolve(null); |
| 94 | return; |
| 95 | } |
| 96 | let data = ""; |
| 97 | res.on("data", (chunk) => (data += chunk)); |
| 98 | res.on("end", () => { |
| 99 | try { |
| 100 | const json = JSON.parse(data); |
| 101 | resolve(json.version || null); |
| 102 | } catch (_) { |
| 103 | resolve(null); |
| 104 | } |
| 105 | }); |
| 106 | res.on("error", () => resolve(null)); |
| 107 | }) |
| 108 | .on("error", () => resolve(null)); |
| 109 | req.on("timeout", () => { |
| 110 | req.destroy(); |
| 111 | resolve(null); |
| 112 | }); |
| 113 | }); |
| 114 | } |
| 115 | |
| 116 | const SEMVER_RE = /^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/; |
| 117 | |