@struktoai/mirage-core
Version:
A Unified Virtual Filesystem For AI Agents
89 lines • 3.45 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 { enoent } from "../../errors/fs.js";
import { FileStat, FileType } from "../../types.js";
import { makeReaddir } from "../hierarchy/readdir.js";
import { databaseExists, entityExists, listCollections, listDatabases } from "./client.js";
import { detectScope, entityKind } from "./scope.js";
import { KIND_TO_DIR } from "./types.js";
export const ENTITY_FILES = ['schema.json', 'documents.jsonl'];
/** ENOENT unless the slotted database exists. */
export async function databaseGuard(accessor, match, virtual) {
if (!(await databaseExists(accessor, match.slots.database ?? ''))) {
throw enoent(virtual);
}
}
/** ENOENT unless the slotted collection or view exists. */
export async function entityGuard(accessor, match, virtual) {
const exists = await entityExists(accessor, match.slots.database ?? '', match.slots.name ?? '', entityKind(match));
if (!exists)
throw enoent(virtual);
}
function databaseExtra(match) {
return { database: match.slots.database ?? '' };
}
function kindDirExtra(match) {
return { database: match.slots.database ?? '', kind: entityKind(match) };
}
function entityExtra(match) {
return {
database: match.slots.database ?? '',
kind: entityKind(match),
name: match.slots.name ?? '',
};
}
// What each kind's stat carries in `extra`, listed or not.
export const EXTRAS = {
database: databaseExtra,
kind_dir: kindDirExtra,
database_json: databaseExtra,
schema_json: entityExtra,
entity: entityExtra,
documents: entityExtra,
};
function dirs(names) {
return names.map((name) => new FileStat({ name, type: FileType.DIRECTORY }));
}
async function listRoot(accessor, _match) {
return dirs(await listDatabases(accessor));
}
function listDatabase(_accessor, _match) {
// database.json, collections/ and views/ exist by construction under
// every database that exists at all (the guard has already run).
return Promise.resolve([
new FileStat({ name: 'database.json', type: FileType.FILE }),
...dirs(Object.values(KIND_TO_DIR)),
]);
}
async function listKindDir(accessor, match) {
return dirs(await listCollections(accessor, match.slots.database ?? '', entityKind(match)));
}
function listEntityFiles(_accessor, _match) {
return Promise.resolve(ENTITY_FILES.map((name) => new FileStat({ name, type: FileType.FILE })));
}
export const readdir = makeReaddir(detectScope, {
listers: {
root: listRoot,
database: listDatabase,
kind_dir: listKindDir,
entity: listEntityFiles,
},
guards: {
database: databaseGuard,
kind_dir: databaseGuard,
entity: entityGuard,
},
extras: EXTRAS,
});
//# sourceMappingURL=readdir.js.map