UNPKG

@struktoai/mirage-core

Version:

A Unified Virtual Filesystem For AI Agents

66 lines • 3.09 kB
// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. ========= // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // ========= Copyright 2026 @ Strukto.AI All Rights Reserved. ========= import { eacces, eisdir } from "../../errors/fs.js"; import { chunks } from "../../io/cooperative.js"; import { ByteSpool } from "../../io/spool.js"; import { record, startOp } from "../../observe/context.js"; import { FileType } from "../../types.js"; import { uploadToken } from "../../utils/upload.js"; import { NATIVE_RESOURCE_TYPES } from "./fingerprint.js"; import { liveRow, statFromItem } from "./readdir.js"; import { eaccesOnDenied, parentFolder } from "./resolve.js"; /** * Upload a new file, or new content for an existing one, handed what is at * `path` and at its parent. A stream is spooled first, as an upload sends its * length; `signal` stops it. Answers the stored file's stat, null for a reply * that names none. Mirrors Python's `write`. */ export const write = eaccesOnDenied(async function writeImpl(accessor, path, data, handed = {}, signal) { if (!(data instanceof Uint8Array) && !(data instanceof ByteSpool)) { const spool = new ByteSpool(); try { await spool.fill(chunks(data, signal)); return await writeImpl(accessor, path, spool, handed); } finally { await spool.close(); } } const key = path.vfsPath; if (key === '') throw eisdir(path); const timer = startOp(); const drive = accessor.drive; const entry = await liveRow(accessor, path, handed.entry); if (entry !== null && entry.type === FileType.DIRECTORY) throw eisdir(path); // Google-native files are written through the gws commands, not raw bytes. if (entry !== null && NATIVE_RESOURCE_TYPES.has(entry.extra.resource_type)) { throw eacces(path); } let reply; if (entry !== null) { reply = await drive.updateFileContent(entry.extra.file_id, data); } else { const [parentId] = await parentFolder(accessor, path, handed.parent); const basename = key.includes('/') ? key.slice(key.lastIndexOf('/') + 1) : key; reply = await drive.uploadFile(basename, parentId, data); } const token = uploadToken(reply, statFromItem, path.virtual); record('write', path.virtual, 'gdrive', data instanceof ByteSpool ? data.size : data.length, timer, { fingerprint: token }); const item = reply; return typeof item === 'object' && item !== null ? statFromItem(reply) : null; }); //# sourceMappingURL=write.js.map