mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-25 03:04:29 -04:00
fix: resolve main-rebase fallout for sandbox fs bridge
This commit is contained in:
@@ -3,8 +3,8 @@ import { Type } from "@sinclair/typebox";
|
|||||||
import fs from "node:fs/promises";
|
import fs from "node:fs/promises";
|
||||||
import os from "node:os";
|
import os from "node:os";
|
||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
import { applyUpdateHunk } from "./apply-patch-update.js";
|
|
||||||
import type { SandboxFsBridge } from "./sandbox/fs-bridge.js";
|
import type { SandboxFsBridge } from "./sandbox/fs-bridge.js";
|
||||||
|
import { applyUpdateHunk } from "./apply-patch-update.js";
|
||||||
|
|
||||||
const BEGIN_PATCH_MARKER = "*** Begin Patch";
|
const BEGIN_PATCH_MARKER = "*** Begin Patch";
|
||||||
const END_PATCH_MARKER = "*** End Patch";
|
const END_PATCH_MARKER = "*** End Patch";
|
||||||
@@ -242,7 +242,9 @@ function resolvePatchFileOps(options: ApplyPatchOptions): PatchFileOps {
|
|||||||
|
|
||||||
async function ensureDir(filePath: string, ops: PatchFileOps) {
|
async function ensureDir(filePath: string, ops: PatchFileOps) {
|
||||||
const parent = path.dirname(filePath);
|
const parent = path.dirname(filePath);
|
||||||
if (!parent || parent === ".") return;
|
if (!parent || parent === ".") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
await ops.mkdirp(parent);
|
await ops.mkdirp(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import type { OpenClawConfig } from "../config/config.js";
|
import type { OpenClawConfig } from "../config/config.js";
|
||||||
import type { GatewayMessageChannel } from "../utils/message-channel.js";
|
import type { GatewayMessageChannel } from "../utils/message-channel.js";
|
||||||
|
import type { SandboxFsBridge } from "./sandbox/fs-bridge.js";
|
||||||
import type { AnyAgentTool } from "./tools/common.js";
|
import type { AnyAgentTool } from "./tools/common.js";
|
||||||
import { resolvePluginTools } from "../plugins/tools.js";
|
import { resolvePluginTools } from "../plugins/tools.js";
|
||||||
import { resolveSessionAgentId } from "./agent-scope.js";
|
import { resolveSessionAgentId } from "./agent-scope.js";
|
||||||
@@ -17,7 +18,7 @@ import { createSessionsListTool } from "./tools/sessions-list-tool.js";
|
|||||||
import { createSessionsSendTool } from "./tools/sessions-send-tool.js";
|
import { createSessionsSendTool } from "./tools/sessions-send-tool.js";
|
||||||
import { createSessionsSpawnTool } from "./tools/sessions-spawn-tool.js";
|
import { createSessionsSpawnTool } from "./tools/sessions-spawn-tool.js";
|
||||||
import { createTtsTool } from "./tools/tts-tool.js";
|
import { createTtsTool } from "./tools/tts-tool.js";
|
||||||
import type { SandboxFsBridge } from "./sandbox/fs-bridge.js";
|
import { createWebFetchTool, createWebSearchTool } from "./tools/web-tools.js";
|
||||||
|
|
||||||
export function createOpenClawTools(options?: {
|
export function createOpenClawTools(options?: {
|
||||||
sandboxBrowserBridgeUrl?: string;
|
sandboxBrowserBridgeUrl?: string;
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
|
import type { ImageContent } from "@mariozechner/pi-ai";
|
||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
import { fileURLToPath } from "node:url";
|
import { fileURLToPath } from "node:url";
|
||||||
|
import type { SandboxFsBridge } from "../../sandbox/fs-bridge.js";
|
||||||
import type { ImageContent } from "@mariozechner/pi-ai";
|
|
||||||
|
|
||||||
import { sanitizeImageBlocks } from "../../tool-images.js";
|
import { sanitizeImageBlocks } from "../../tool-images.js";
|
||||||
import { log } from "../logger.js";
|
import { log } from "../logger.js";
|
||||||
import type { SandboxFsBridge } from "../../sandbox/fs-bridge.js";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Common image file extensions for detection.
|
* Common image file extensions for detection.
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import type { AgentToolResult } from "@mariozechner/pi-agent-core";
|
import type { AgentToolResult } from "@mariozechner/pi-agent-core";
|
||||||
import { createEditTool, createReadTool, createWriteTool } from "@mariozechner/pi-coding-agent";
|
import { createEditTool, createReadTool, createWriteTool } from "@mariozechner/pi-coding-agent";
|
||||||
import type { AnyAgentTool } from "./pi-tools.types.js";
|
import type { AnyAgentTool } from "./pi-tools.types.js";
|
||||||
|
import type { SandboxFsBridge } from "./sandbox/fs-bridge.js";
|
||||||
import { detectMime } from "../media/mime.js";
|
import { detectMime } from "../media/mime.js";
|
||||||
import { assertSandboxPath } from "./sandbox-paths.js";
|
import { assertSandboxPath } from "./sandbox-paths.js";
|
||||||
import { sanitizeToolResultImages } from "./tool-images.js";
|
import { sanitizeToolResultImages } from "./tool-images.js";
|
||||||
import type { SandboxFsBridge } from "./sandbox/fs-bridge.js";
|
|
||||||
|
|
||||||
// NOTE(steipete): Upstream read now does file-magic MIME detection; we keep the wrapper
|
// NOTE(steipete): Upstream read now does file-magic MIME detection; we keep the wrapper
|
||||||
// to normalize payloads and sanitize oversized images before they hit providers.
|
// to normalize payloads and sanitize oversized images before they hit providers.
|
||||||
@@ -278,7 +278,7 @@ export function createSandboxedReadTool(params: SandboxToolParams) {
|
|||||||
const base = createReadTool(params.root, {
|
const base = createReadTool(params.root, {
|
||||||
operations: createSandboxReadOperations(params),
|
operations: createSandboxReadOperations(params),
|
||||||
}) as unknown as AnyAgentTool;
|
}) as unknown as AnyAgentTool;
|
||||||
return wrapSandboxPathGuard(createMoltbotReadTool(base), params.root);
|
return wrapSandboxPathGuard(createOpenClawReadTool(base), params.root);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createSandboxedWriteTool(params: SandboxToolParams) {
|
export function createSandboxedWriteTool(params: SandboxToolParams) {
|
||||||
|
|||||||
@@ -3,9 +3,6 @@ import os from "node:os";
|
|||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
import { describe, expect, it, vi } from "vitest";
|
import { describe, expect, it, vi } from "vitest";
|
||||||
import { createOpenClawCodingTools } from "./pi-tools.js";
|
import { createOpenClawCodingTools } from "./pi-tools.js";
|
||||||
|
|
||||||
import { describe, expect, it } from "vitest";
|
|
||||||
import { createMoltbotCodingTools } from "./pi-tools.js";
|
|
||||||
import { createHostSandboxFsBridge } from "./test-helpers/host-sandbox-fs-bridge.js";
|
import { createHostSandboxFsBridge } from "./test-helpers/host-sandbox-fs-bridge.js";
|
||||||
|
|
||||||
vi.mock("../infra/shell-env.js", async (importOriginal) => {
|
vi.mock("../infra/shell-env.js", async (importOriginal) => {
|
||||||
|
|||||||
@@ -9,11 +9,11 @@ import { DEFAULT_AGENT_WORKSPACE_DIR } from "../workspace.js";
|
|||||||
import { ensureSandboxBrowser } from "./browser.js";
|
import { ensureSandboxBrowser } from "./browser.js";
|
||||||
import { resolveSandboxConfigForAgent } from "./config.js";
|
import { resolveSandboxConfigForAgent } from "./config.js";
|
||||||
import { ensureSandboxContainer } from "./docker.js";
|
import { ensureSandboxContainer } from "./docker.js";
|
||||||
|
import { createSandboxFsBridge } from "./fs-bridge.js";
|
||||||
import { maybePruneSandboxes } from "./prune.js";
|
import { maybePruneSandboxes } from "./prune.js";
|
||||||
import { resolveSandboxRuntimeStatus } from "./runtime-status.js";
|
import { resolveSandboxRuntimeStatus } from "./runtime-status.js";
|
||||||
import { resolveSandboxScopeKey, resolveSandboxWorkspaceDir } from "./shared.js";
|
import { resolveSandboxScopeKey, resolveSandboxWorkspaceDir } from "./shared.js";
|
||||||
import { ensureSandboxWorkspace } from "./workspace.js";
|
import { ensureSandboxWorkspace } from "./workspace.js";
|
||||||
import { createSandboxFsBridge } from "./fs-bridge.js";
|
|
||||||
|
|
||||||
export async function resolveSandboxContext(params: {
|
export async function resolveSandboxContext(params: {
|
||||||
config?: OpenClawConfig;
|
config?: OpenClawConfig;
|
||||||
|
|||||||
@@ -38,7 +38,9 @@ export function execDockerRaw(
|
|||||||
|
|
||||||
const signal = opts?.signal;
|
const signal = opts?.signal;
|
||||||
const handleAbort = () => {
|
const handleAbort = () => {
|
||||||
if (aborted) return;
|
if (aborted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
aborted = true;
|
aborted = true;
|
||||||
child.kill("SIGTERM");
|
child.kill("SIGTERM");
|
||||||
};
|
};
|
||||||
@@ -58,12 +60,16 @@ export function execDockerRaw(
|
|||||||
});
|
});
|
||||||
|
|
||||||
child.on("error", (error) => {
|
child.on("error", (error) => {
|
||||||
if (signal) signal.removeEventListener("abort", handleAbort);
|
if (signal) {
|
||||||
|
signal.removeEventListener("abort", handleAbort);
|
||||||
|
}
|
||||||
reject(error);
|
reject(error);
|
||||||
});
|
});
|
||||||
|
|
||||||
child.on("close", (code) => {
|
child.on("close", (code) => {
|
||||||
if (signal) signal.removeEventListener("abort", handleAbort);
|
if (signal) {
|
||||||
|
signal.removeEventListener("abort", handleAbort);
|
||||||
|
}
|
||||||
const stdout = Buffer.concat(stdoutChunks);
|
const stdout = Buffer.concat(stdoutChunks);
|
||||||
const stderr = Buffer.concat(stderrChunks);
|
const stderr = Buffer.concat(stderrChunks);
|
||||||
if (aborted || signal?.aborted) {
|
if (aborted || signal?.aborted) {
|
||||||
@@ -98,7 +104,6 @@ export function execDockerRaw(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
import { defaultRuntime } from "../../runtime.js";
|
|
||||||
import { formatCliCommand } from "../../cli/command-format.js";
|
import { formatCliCommand } from "../../cli/command-format.js";
|
||||||
import { defaultRuntime } from "../../runtime.js";
|
import { defaultRuntime } from "../../runtime.js";
|
||||||
import { computeSandboxConfigHash } from "./config-hash.js";
|
import { computeSandboxConfigHash } from "./config-hash.js";
|
||||||
@@ -281,9 +286,7 @@ export function buildSandboxCreateArgs(params: {
|
|||||||
if (typeof params.cfg.cpus === "number" && params.cfg.cpus > 0) {
|
if (typeof params.cfg.cpus === "number" && params.cfg.cpus > 0) {
|
||||||
args.push("--cpus", String(params.cfg.cpus));
|
args.push("--cpus", String(params.cfg.cpus));
|
||||||
}
|
}
|
||||||
for (const [name, value] of Object.entries(params.cfg.ulimits ?? {}) as Array<
|
for (const [name, value] of Object.entries(params.cfg.ulimits ?? {})) {
|
||||||
[string, string | number | { soft?: number; hard?: number }]
|
|
||||||
>) {
|
|
||||||
const formatted = formatUlimitValue(name, value);
|
const formatted = formatUlimitValue(name, value);
|
||||||
if (formatted) {
|
if (formatted) {
|
||||||
args.push("--ulimit", formatted);
|
args.push("--ulimit", formatted);
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ vi.mock("./docker.js", () => ({
|
|||||||
execDockerRaw: vi.fn(),
|
execDockerRaw: vi.fn(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
import type { SandboxContext } from "./types.js";
|
||||||
import { execDockerRaw } from "./docker.js";
|
import { execDockerRaw } from "./docker.js";
|
||||||
import { createSandboxFsBridge } from "./fs-bridge.js";
|
import { createSandboxFsBridge } from "./fs-bridge.js";
|
||||||
import type { SandboxContext } from "./types.js";
|
|
||||||
|
|
||||||
const mockedExecDockerRaw = vi.mocked(execDockerRaw);
|
const mockedExecDockerRaw = vi.mocked(execDockerRaw);
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
|
|
||||||
import { resolveSandboxPath } from "../sandbox-paths.js";
|
|
||||||
import type { SandboxContext, SandboxWorkspaceAccess } from "./types.js";
|
import type { SandboxContext, SandboxWorkspaceAccess } from "./types.js";
|
||||||
|
import { resolveSandboxPath } from "../sandbox-paths.js";
|
||||||
import { execDockerRaw, type ExecDockerRawResult } from "./docker.js";
|
import { execDockerRaw, type ExecDockerRawResult } from "./docker.js";
|
||||||
|
|
||||||
type RunCommandOptions = {
|
type RunCommandOptions = {
|
||||||
@@ -244,9 +243,15 @@ function resolveSandboxFsPath(params: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function coerceStatType(typeRaw?: string): "file" | "directory" | "other" {
|
function coerceStatType(typeRaw?: string): "file" | "directory" | "other" {
|
||||||
if (!typeRaw) return "other";
|
if (!typeRaw) {
|
||||||
|
return "other";
|
||||||
|
}
|
||||||
const normalized = typeRaw.trim().toLowerCase();
|
const normalized = typeRaw.trim().toLowerCase();
|
||||||
if (normalized.includes("directory")) return "directory";
|
if (normalized.includes("directory")) {
|
||||||
if (normalized.includes("file")) return "file";
|
return "directory";
|
||||||
|
}
|
||||||
|
if (normalized.includes("file")) {
|
||||||
|
return "file";
|
||||||
|
}
|
||||||
return "other";
|
return "other";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
import fs from "node:fs/promises";
|
import fs from "node:fs/promises";
|
||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
|
|
||||||
import { resolveSandboxPath } from "../sandbox-paths.js";
|
|
||||||
import type { SandboxFsBridge, SandboxFsStat, SandboxResolvedPath } from "../sandbox/fs-bridge.js";
|
import type { SandboxFsBridge, SandboxFsStat, SandboxResolvedPath } from "../sandbox/fs-bridge.js";
|
||||||
|
import { resolveSandboxPath } from "../sandbox-paths.js";
|
||||||
|
|
||||||
export function createHostSandboxFsBridge(rootDir: string): SandboxFsBridge {
|
export function createHostSandboxFsBridge(rootDir: string): SandboxFsBridge {
|
||||||
const root = path.resolve(rootDir);
|
const root = path.resolve(rootDir);
|
||||||
@@ -65,7 +64,9 @@ export function createHostSandboxFsBridge(rootDir: string): SandboxFsBridge {
|
|||||||
mtimeMs: stats.mtimeMs,
|
mtimeMs: stats.mtimeMs,
|
||||||
} satisfies SandboxFsStat;
|
} satisfies SandboxFsStat;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if ((error as NodeJS.ErrnoException).code === "ENOENT") return null;
|
if ((error as NodeJS.ErrnoException).code === "ENOENT") {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ import os from "node:os";
|
|||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
import type { OpenClawConfig } from "../../config/config.js";
|
import type { OpenClawConfig } from "../../config/config.js";
|
||||||
import { __testing, createImageTool, resolveImageModelConfigForTool } from "./image-tool.js";
|
|
||||||
import { createHostSandboxFsBridge } from "../test-helpers/host-sandbox-fs-bridge.js";
|
import { createHostSandboxFsBridge } from "../test-helpers/host-sandbox-fs-bridge.js";
|
||||||
|
import { __testing, createImageTool, resolveImageModelConfigForTool } from "./image-tool.js";
|
||||||
|
|
||||||
async function writeAuthProfiles(agentDir: string, profiles: unknown) {
|
async function writeAuthProfiles(agentDir: string, profiles: unknown) {
|
||||||
await fs.mkdir(agentDir, { recursive: true });
|
await fs.mkdir(agentDir, { recursive: true });
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
|
import { type Api, type Context, complete, type Model } from "@mariozechner/pi-ai";
|
||||||
|
import { Type } from "@sinclair/typebox";
|
||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
import type { OpenClawConfig } from "../../config/config.js";
|
import type { OpenClawConfig } from "../../config/config.js";
|
||||||
|
import type { SandboxFsBridge } from "../sandbox/fs-bridge.js";
|
||||||
import type { AnyAgentTool } from "./common.js";
|
import type { AnyAgentTool } from "./common.js";
|
||||||
import { resolveUserPath } from "../../utils.js";
|
import { resolveUserPath } from "../../utils.js";
|
||||||
import { loadWebMedia } from "../../web/media.js";
|
import { loadWebMedia } from "../../web/media.js";
|
||||||
@@ -9,9 +12,8 @@ import { minimaxUnderstandImage } from "../minimax-vlm.js";
|
|||||||
import { getApiKeyForModel, requireApiKey, resolveEnvApiKey } from "../model-auth.js";
|
import { getApiKeyForModel, requireApiKey, resolveEnvApiKey } from "../model-auth.js";
|
||||||
import { runWithImageModelFallback } from "../model-fallback.js";
|
import { runWithImageModelFallback } from "../model-fallback.js";
|
||||||
import { resolveConfiguredModelRef } from "../model-selection.js";
|
import { resolveConfiguredModelRef } from "../model-selection.js";
|
||||||
import { ensureMoltbotModelsJson } from "../models-config.js";
|
import { ensureOpenClawModelsJson } from "../models-config.js";
|
||||||
import type { AnyAgentTool } from "./common.js";
|
import { discoverAuthStorage, discoverModels } from "../pi-model-discovery.js";
|
||||||
import type { SandboxFsBridge } from "../sandbox/fs-bridge.js";
|
|
||||||
import {
|
import {
|
||||||
coerceImageAssistantText,
|
coerceImageAssistantText,
|
||||||
coerceImageModelConfig,
|
coerceImageModelConfig,
|
||||||
@@ -207,7 +209,9 @@ async function resolveSandboxedImagePath(params: {
|
|||||||
filePath: candidateRel,
|
filePath: candidateRel,
|
||||||
cwd: params.sandbox.root,
|
cwd: params.sandbox.root,
|
||||||
});
|
});
|
||||||
if (!stat) throw err;
|
if (!stat) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
} catch {
|
} catch {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
@@ -398,8 +402,12 @@ export function createImageTool(options?: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const resolvedImage = (() => {
|
const resolvedImage = (() => {
|
||||||
if (sandboxConfig) return imageRaw;
|
if (sandboxConfig) {
|
||||||
if (imageRaw.startsWith("~")) return resolveUserPath(imageRaw);
|
return imageRaw;
|
||||||
|
}
|
||||||
|
if (imageRaw.startsWith("~")) {
|
||||||
|
return resolveUserPath(imageRaw);
|
||||||
|
}
|
||||||
return imageRaw;
|
return imageRaw;
|
||||||
})();
|
})();
|
||||||
const resolvedPathInfo: { resolved: string; rewrittenFrom?: string } = isDataUrl
|
const resolvedPathInfo: { resolved: string; rewrittenFrom?: string } = isDataUrl
|
||||||
|
|||||||
@@ -100,9 +100,9 @@ describe("web media loading", () => {
|
|||||||
const { buffer, file } = await createLargeTestJpeg();
|
const { buffer, file } = await createLargeTestJpeg();
|
||||||
const cap = Math.max(1, Math.floor(buffer.length * 0.8));
|
const cap = Math.max(1, Math.floor(buffer.length * 0.8));
|
||||||
|
|
||||||
await expect(
|
await expect(loadWebMedia(file, { maxBytes: cap, optimizeImages: false })).rejects.toThrow(
|
||||||
loadWebMedia(file, { maxBytes: cap, optimizeImages: false }),
|
/Media exceeds/i,
|
||||||
).rejects.toThrow(/Media exceeds/i);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("sniffs mime before extension when loading local files", async () => {
|
it("sniffs mime before extension when loading local files", async () => {
|
||||||
|
|||||||
@@ -25,6 +25,9 @@ export type WebMediaResult = {
|
|||||||
type WebMediaOptions = {
|
type WebMediaOptions = {
|
||||||
maxBytes?: number;
|
maxBytes?: number;
|
||||||
optimizeImages?: boolean;
|
optimizeImages?: boolean;
|
||||||
|
ssrfPolicy?: SsrFPolicy;
|
||||||
|
/** Allowed root directories for local path reads. "any" skips the check (caller already validated). */
|
||||||
|
localRoots?: string[] | "any";
|
||||||
readFile?: (filePath: string) => Promise<Buffer>;
|
readFile?: (filePath: string) => Promise<Buffer>;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -163,7 +166,13 @@ async function loadWebMediaInternal(
|
|||||||
mediaUrl: string,
|
mediaUrl: string,
|
||||||
options: WebMediaOptions = {},
|
options: WebMediaOptions = {},
|
||||||
): Promise<WebMediaResult> {
|
): Promise<WebMediaResult> {
|
||||||
const { maxBytes, optimizeImages = true, readFile: readFileOverride } = options;
|
const {
|
||||||
|
maxBytes,
|
||||||
|
optimizeImages = true,
|
||||||
|
ssrfPolicy,
|
||||||
|
localRoots,
|
||||||
|
readFile: readFileOverride,
|
||||||
|
} = options;
|
||||||
// Use fileURLToPath for proper handling of file:// URLs (handles file://localhost/path, etc.)
|
// Use fileURLToPath for proper handling of file:// URLs (handles file://localhost/path, etc.)
|
||||||
if (mediaUrl.startsWith("file://")) {
|
if (mediaUrl.startsWith("file://")) {
|
||||||
try {
|
try {
|
||||||
@@ -285,35 +294,39 @@ async function loadWebMediaInternal(
|
|||||||
|
|
||||||
export async function loadWebMedia(
|
export async function loadWebMedia(
|
||||||
mediaUrl: string,
|
mediaUrl: string,
|
||||||
options?: number | WebMediaOptions,
|
maxBytesOrOptions?: number | WebMediaOptions,
|
||||||
|
options?: { ssrfPolicy?: SsrFPolicy; localRoots?: string[] | "any" },
|
||||||
): Promise<WebMediaResult> {
|
): Promise<WebMediaResult> {
|
||||||
if (typeof options === "number" || options === undefined) {
|
if (typeof maxBytesOrOptions === "number" || maxBytesOrOptions === undefined) {
|
||||||
return await loadWebMediaInternal(mediaUrl, {
|
return await loadWebMediaInternal(mediaUrl, {
|
||||||
maxBytes: options,
|
maxBytes: maxBytesOrOptions,
|
||||||
optimizeImages: true,
|
optimizeImages: true,
|
||||||
|
ssrfPolicy: options?.ssrfPolicy,
|
||||||
|
localRoots: options?.localRoots,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return await loadWebMediaInternal(mediaUrl, {
|
return await loadWebMediaInternal(mediaUrl, {
|
||||||
...options,
|
...maxBytesOrOptions,
|
||||||
optimizeImages: options.optimizeImages ?? true,
|
optimizeImages: maxBytesOrOptions.optimizeImages ?? true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function loadWebMediaRaw(
|
export async function loadWebMediaRaw(
|
||||||
mediaUrl: string,
|
mediaUrl: string,
|
||||||
options?: number | WebMediaOptions,
|
maxBytesOrOptions?: number | WebMediaOptions,
|
||||||
|
options?: { ssrfPolicy?: SsrFPolicy; localRoots?: string[] | "any" },
|
||||||
): Promise<WebMediaResult> {
|
): Promise<WebMediaResult> {
|
||||||
if (typeof options === "number" || options === undefined) {
|
if (typeof maxBytesOrOptions === "number" || maxBytesOrOptions === undefined) {
|
||||||
return await loadWebMediaInternal(mediaUrl, {
|
return await loadWebMediaInternal(mediaUrl, {
|
||||||
maxBytes: options,
|
maxBytes: maxBytesOrOptions,
|
||||||
optimizeImages: false,
|
optimizeImages: false,
|
||||||
|
ssrfPolicy: options?.ssrfPolicy,
|
||||||
|
localRoots: options?.localRoots,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return await loadWebMediaInternal(mediaUrl, {
|
return await loadWebMediaInternal(mediaUrl, {
|
||||||
...options,
|
...maxBytesOrOptions,
|
||||||
optimizeImages: false,
|
optimizeImages: false,
|
||||||
ssrfPolicy: options?.ssrfPolicy,
|
|
||||||
localRoots: options?.localRoots,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user