@runinfra/cli
Advanced tools
@@ -32,3 +32,3 @@ export const DEFAULT_API_BASE = "https://runinfra.ai"; | ||
| } | ||
| function isLoopbackHostname(hostname) { | ||
| export function isLoopbackHostname(hostname) { | ||
| return (hostname === "localhost" || | ||
@@ -35,0 +35,0 @@ hostname === "127.0.0.1" || |
+22
-1
| import { request as httpRequest } from "node:http"; | ||
| import { request as httpsRequest } from "node:https"; | ||
| import { isLoopbackHostname } from "./endpoints.js"; | ||
| import { CliError } from "./errors.js"; | ||
@@ -27,2 +28,18 @@ import { userAgent } from "./version.js"; | ||
| } | ||
| const CREDENTIAL_HEADERS = new Set([ | ||
| "authorization", | ||
| "cookie", | ||
| "proxy-authorization", | ||
| ]); | ||
| function headersForHop(requested, origin, originalOrigin) { | ||
| if (!requested || origin === originalOrigin) | ||
| return { ...(requested ?? {}) }; | ||
| const carried = {}; | ||
| for (const [name, value] of Object.entries(requested)) { | ||
| if (CREDENTIAL_HEADERS.has(name.toLowerCase())) | ||
| continue; | ||
| carried[name] = value; | ||
| } | ||
| return carried; | ||
| } | ||
| async function dispatch(options) { | ||
@@ -33,2 +50,3 @@ const maxRedirects = options.maxRedirects ?? DEFAULT_MAX_REDIRECTS; | ||
| let body = options.json === undefined ? null : Buffer.from(JSON.stringify(options.json), "utf8"); | ||
| const originalOrigin = new URL(options.url).origin; | ||
| for (let hop = 0; hop <= maxRedirects; hop += 1) { | ||
@@ -41,3 +59,3 @@ const parsed = new URL(currentUrl); | ||
| "user-agent": userAgent(), | ||
| ...(options.headers ?? {}), | ||
| ...headersForHop(options.headers, parsed.origin, originalOrigin), | ||
| }; | ||
@@ -80,2 +98,5 @@ if (body) { | ||
| } | ||
| if (next.protocol === "http:" && !isLoopbackHostname(next.hostname)) { | ||
| throw new CliError("network", `${parsed.host} redirected to a plaintext URL off this machine (${next.protocol}//${next.host}).`, "This is not something the CLI can safely follow. Report it to support."); | ||
| } | ||
| if (status === 303 || ((status === 301 || status === 302) && method !== "HEAD")) { | ||
@@ -82,0 +103,0 @@ method = "GET"; |
+19
-1
@@ -40,3 +40,21 @@ import { open, mkdir, rename, rm, stat, writeFile } from "node:fs/promises"; | ||
| if (existing.size === artifact.sizeBytes) { | ||
| output.info(`${fileName} is already downloaded.`); | ||
| if (lease.checksumSha256) { | ||
| let lastTickMs = 0; | ||
| const actual = await sha256File(finalPath, (hashed) => { | ||
| const nowMs = Date.now(); | ||
| if (nowMs - lastTickMs < 500) | ||
| return; | ||
| lastTickMs = nowMs; | ||
| const percent = artifact.sizeBytes > 0 ? (hashed / artifact.sizeBytes) * 100 : 0; | ||
| output.status(` Checking the file already here ${percent.toFixed(1)}%`); | ||
| }, signal); | ||
| output.endStatus(); | ||
| if (judgeChecksum(lease.checksumSha256, actual) === "mismatch") { | ||
| throw new CliError("checksum_mismatch", `${finalPath} is the published size but does not match the published checksum.`, "Move or delete that file, then run the same command again to download it fresh."); | ||
| } | ||
| output.info(`${fileName} is already downloaded, and its checksum matches.`); | ||
| } | ||
| else { | ||
| output.info(`${fileName} is already downloaded. UNVERIFIED: this package publishes no checksum.`); | ||
| } | ||
| output.result(finalPath); | ||
@@ -43,0 +61,0 @@ return 0; |
+1
-1
| export const CLI_NAME = "runinfra"; | ||
| export const CLI_PACKAGE = "@runinfra/cli"; | ||
| export const CLI_VERSION = "0.1.0"; | ||
| export const CLI_VERSION = "0.1.1"; | ||
| export const CLI_CLIENT_ID = "runinfra-cli"; | ||
@@ -5,0 +5,0 @@ export const MINIMUM_NODE_MAJOR = 20; |
+2
-2
| { | ||
| "name": "@runinfra/cli", | ||
| "version": "0.1.0", | ||
| "version": "0.1.1", | ||
| "description": "RunInfra CLI: browser-approved sign-in and resumable downloads for optimized model packages", | ||
| "license": "SEE LICENSE IN LICENSE", | ||
| "homepage": "https://runinfra.ai/optimized-models", | ||
| "homepage": "https://runinfra.ai/catalog", | ||
| "bugs": { | ||
@@ -8,0 +8,0 @@ "url": "https://runinfra.ai/contact" |
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Deprecated
MaintenanceThe maintainer of the package marked it as deprecated. This could indicate that a single version should not be used, or that the package is no longer maintained and any new vulnerabilities will not be fixed.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
129288
1.59%2757
1.43%0
-100%