@struktoai/mirage-core
Version:
A Unified Virtual Filesystem For AI Agents
73 lines • 3.37 kB
JavaScript
// ========= 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 { eisdir, enoent, enotdir } from "../../errors/fs.js";
import { FileType } from "../../types.js";
import { liveRow, statFromItem } from "./readdir.js";
import { driveTargetName, eaccesOnDenied, isFolder, nodeFromItem, nodeOf, parentFolder, } from "./resolve.js";
async function copyChildren(drive, src, dstFolderId) {
const children = await drive.listFiles({ folderId: src.id, driveId: src.driveId });
for (const item of children) {
const child = nodeFromItem(item, src.driveId);
if (isFolder(child)) {
const created = await drive.createFolder(child.name, dstFolderId);
await copyChildren(drive, child, created.id);
}
else {
await drive.copyFile(child.id, child.name, dstFolderId);
}
}
}
/**
* Copy a file or folder server-side, handed what is at `src` and at `dst`
* and its parent. `cp -r` merges into an existing folder and creates a
* missing one, mirroring the msgraph copy_tree. Answers the stat of what the
* copy made, null when it merged into a folder already there. Mirrors
* Python's `copy`.
*/
export const copy = eaccesOnDenied(async function (accessor, src, dst, _signal, handed = {}) {
const entry = handed.entry ?? null;
if (entry === null)
throw enoent(src);
const drive = accessor.drive;
const srcNode = nodeOf(entry);
const dstEntry = await liveRow(accessor, dst, handed.dstEntry);
const dstKey = dst.vfsPath;
const basename = dstKey.includes('/') ? dstKey.slice(dstKey.lastIndexOf('/') + 1) : dstKey;
if (isFolder(srcNode)) {
if (dstEntry !== null && dstEntry.type !== FileType.DIRECTORY)
throw enotdir(dst);
let made = null;
let dstId;
if (dstEntry === null) {
const [dstParentId] = await parentFolder(accessor, dst, handed.dstParent);
const created = await drive.createFolder(basename, dstParentId);
dstId = created.id;
made = statFromItem(created);
}
else {
dstId = dstEntry.extra.file_id;
}
await copyChildren(drive, srcNode, dstId);
return made;
}
if (dstEntry !== null && dstEntry.type === FileType.DIRECTORY)
throw eisdir(dst);
if (dstEntry !== null)
await drive.deleteFile(dstEntry.extra.file_id);
const [dstParentId] = await parentFolder(accessor, dst, handed.dstParent);
const item = await drive.copyFile(srcNode.id, driveTargetName(basename, srcNode.mimeType), dstParentId);
const copied = item;
return typeof copied === 'object' && copied !== null ? statFromItem(item) : null;
});
//# sourceMappingURL=copy.js.map