@struktoai/mirage-core
Version:
A Unified Virtual Filesystem For AI Agents
144 lines • 5.95 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 { DropboxAccessor } from "../../accessor/dropbox.js";
import { capacity as dropboxCapacity } from "../../core/dropbox/capacity.js";
import { DropboxTokenManager } from "../../core/dropbox/client.js";
import { CONDITION_SUPPORT } from "../../core/dropbox/constants.js";
import { copy as dropboxCopy, dirCopy as dropboxDirCopy } from "../../core/dropbox/copy.js";
import { create as dropboxCreate } from "../../core/dropbox/create.js";
import { buildDeltaHook } from "../../core/dropbox/events.js";
import { exists as dropboxExists } from "../../core/dropbox/exists.js";
import { mkdir as dropboxMkdir } from "../../core/dropbox/mkdir.js";
import { read as dropboxRead, readByPath as dropboxReadByPath, readStream as dropboxStream, } from "../../core/dropbox/read.js";
import { readdir as dropboxReaddir } from "../../core/dropbox/readdir.js";
import { rename as dropboxRename } from "../../core/dropbox/rename.js";
import { rmR as dropboxRmR } from "../../core/dropbox/rm.js";
import { rmdir as dropboxRmdir } from "../../core/dropbox/rmdir.js";
import { filesContaining as dropboxFilesContaining } from "../../core/dropbox/search.js";
import { stat as dropboxStat, tree as dropboxTree } from "../../core/dropbox/stat.js";
import { unlink as dropboxUnlink } from "../../core/dropbox/unlink.js";
import { replace as dropboxReplace, write as dropboxWrite } from "../../core/dropbox/write.js";
import { truncateByRewrite } from "../../core/generic/rewrite.js";
import {} from "../../events/index.js";
import { VFSName } from "../../types.js";
import { BaseVFS } from "../base.js";
import { DropboxConfig } from "./config.js";
export class DropboxVFS extends BaseVFS {
get conditionSupport() {
return CONDITION_SUPPORT;
}
name = VFSName.DROPBOX;
cachesReads = true;
// list_folder carries an exact byte `size` for every file (0 included).
// Paper docs 409 on raw download, a loud error, never a silent empty read.
sizesAlwaysKnown = true;
// stat and every read stamp content_hash: a listing row and get_metadata
// carry it, and a download, ranged or not, names it in Dropbox-API-Result
// at no extra request.
readRevalidatable = true;
indexTtl = 86_400;
handed = {
read: ['entry'],
truncate: ['entry'],
};
wholeWordSearch = true;
config;
accessor;
constructor(config) {
super();
this.config = config;
const tm = new DropboxTokenManager(config);
this.accessor = new DropboxAccessor({
tokenManager: tm,
...(config.rootPath !== undefined ? { rootPath: config.rootPath } : {}),
});
}
readsRanges = true;
readTree(path) {
return dropboxTree(this.accessor, path);
}
readdir(path, handed) {
return dropboxReaddir(this.accessor, path, handed?.limit);
}
read(path, handed, offset = 0, size = null) {
if (offset === 0 && size === null)
return dropboxStream(this.accessor, path, handed?.entry);
return dropboxRead(this.accessor, path, size === null ? { offset } : { offset, size }, handed?.entry);
}
stat(path) {
return dropboxStat(this.accessor, path);
}
exists(path) {
return dropboxExists(this.accessor, path);
}
write(path, data, signal) {
return dropboxWrite(this.accessor, path, data, signal);
}
truncate(path, length, noCreate = false, handed = {}) {
return truncateByRewrite((p) => handed.entry === undefined || handed.entry === null
? dropboxReadByPath(this.accessor, p)
: dropboxRead(this.accessor, p, undefined, handed.entry), (request) => this._replace(request), path, length, noCreate);
}
_replace(request, signal) {
return dropboxReplace(this.accessor, request, signal);
}
create(path) {
return dropboxCreate(this.accessor, path);
}
mkdir(path, parents = false) {
return dropboxMkdir(this.accessor, path, parents);
}
unlink(path) {
return dropboxUnlink(this.accessor, path);
}
rmdir(path) {
return dropboxRmdir(this.accessor, path);
}
rmR(path) {
return dropboxRmR(this.accessor, path);
}
rename(src, dst) {
return dropboxRename(this.accessor, src, dst);
}
copy(src, dst) {
return dropboxCopy(this.accessor, src, dst);
}
dirCopy(src, dst) {
return dropboxDirCopy(this.accessor, src, dst);
}
/**
* Whether this VFS answers `name`; with no walk limit it reads every
* file rather than ask the service's search.
*/
supports(name) {
if (name === 'files_containing' && this.walkLimit < 0)
return false;
return super.supports(name);
}
filesContaining(path, text, opts) {
if (!opts.wholeWord || this.walkLimit < 0)
return Promise.resolve(null);
return dropboxFilesContaining(this.accessor, text, [path]);
}
capacity() {
return dropboxCapacity(this.accessor);
}
deltaHook() {
return buildDeltaHook(this.accessor);
}
getState() {
return Promise.resolve(this.configState(DropboxConfig, this.config));
}
}
//# sourceMappingURL=dropbox.js.map