@struktoai/mirage-core
Version:
A Unified Virtual Filesystem For AI Agents
73 lines • 3.23 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 { z } from 'zod';
import { MSGRAPH_CONFIG_SHAPE, optionalText, resolveMsGraphConfig, } from "../core/msgraph/config.js";
import { stripSlash } from "../utils/slash.js";
import { Accessor } from "./base.js";
export const SharePointConfig = z.object({
...MSGRAPH_CONFIG_SHAPE,
siteFilter: z.string().optional().meta({
description: "Search term passed to Graph's `/sites?search=` to choose which sites the mount lists.",
default: '*',
}),
site: z
.string()
.optional()
.describe('Site, by display name or internal name, that scopes the mount to one document library together with `drive`. With either unset the mount lists every site as `/<site>/<library>/...`.'),
drive: z
.string()
.optional()
.describe('Document library in `site` that the mount uses as its root; takes effect only with `site` set.'),
keyPrefix: z
.string()
.optional()
.describe('Folder path inside the scoped library that the mount uses as its root; takes effect only with `site` and `drive` set. `..` segments are rejected.'),
});
function normalizePrefix(value) {
const normalized = stripSlash(value ?? '');
if (normalized.split('/').includes('..'))
throw new Error("keyPrefix must not contain '..' segments");
return normalized;
}
export function resolveSharePointConfig(config) {
return {
...resolveMsGraphConfig(config),
siteFilter: optionalText(config.siteFilter),
site: optionalText(config.site),
drive: optionalText(config.drive),
keyPrefix: normalizePrefix(config.keyPrefix),
};
}
export class SharePointAccessor extends Accessor {
config;
// Name -> id lookups for the two namespace levels above a drive item, so
// resolving a path does not call /sites and /drives on every op. They live
// on the accessor, not the module: one accessor is one mount is one
// tenant, and a site name is only unique within a tenant. A drive name is
// only unique within its site, so its key carries the site id. Entries
// live until the mount drops its caches (forget).
siteCache = new Map();
driveCache = new Map();
constructor(config) {
super();
this.config = resolveSharePointConfig(config);
}
/** Drop the site and drive ids with the mount's caches. */
forget() {
super.forget?.();
this.siteCache = new Map();
this.driveCache = new Map();
}
}
//# sourceMappingURL=sharepoint.js.map