UNPKG

@struktoai/mirage-core

Version:

A Unified Virtual Filesystem For AI Agents

88 lines • 3.58 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 { z } from 'zod'; import { ContentType, FileType } from "../../types.js"; import { parseConfigWithSchema, refuseRepeatedFields } from "../../vfs/secrets.js"; export const LookupStatus = Object.freeze({ EXPIRED: 'expired', NOT_FOUND: 'not_found', }); export const IndexType = Object.freeze({ RAM: 'ram', REDIS: 'redis', }); /** * The wire form of a stat row: what pydantic writes for the Python * `FileStat`, which `JSON.stringify` of a `FileStat` already matches field * for field and in order. */ export const FileStatWireSchema = z.object({ name: z.string(), size: z.number().int().nullable().default(null), modified: z.string().nullable().default(null), fingerprint: z.string().nullable().default(null), revision: z.string().nullable().default(null), type: z.enum(Object.values(FileType)), content: z .enum(Object.values(ContentType)) .nullable() .default(null), mode: z.number().int().nullable().default(null), uid: z.union([z.number(), z.string()]).nullable().default(null), gid: z.union([z.number(), z.string()]).nullable().default(null), atime: z.string().nullable().default(null), ctime: z.string().nullable().default(null), birthtime: z.string().nullable().default(null), dev: z.number().int().nullable().default(null), extra: z.record(z.string(), z.unknown()).default({}), }); /** The directory row, the twin of the pydantic `IndexDirectory`. */ export const IndexDirectory = z.object({ entries: z.array(z.string()), folders: z.array(z.number().int()), expires_at: z.number(), generation: z.string(), partial: z.boolean().default(false), version: z.string().nullable().default(null), window: z.boolean().default(false), }); const IndexConfig = z.object({ type: z.enum(IndexType).optional(), ttl: z.number().optional(), }); const RedisIndexConfig = IndexConfig.extend({ url: z.string().optional(), // Absent scopes the keys to the workspace; a prefix shares them with // every workspace that names it. keyPrefix: z.string().optional(), }); /** * Check an index config the way python's `IndexConfig` checks one on * construction, and camelize its keys. * * The fields are picked by `type`, where python picks them by class, since * a TS config has no class to pick by. One field named in both spellings is * refused, as python refuses the camelCase one. * * @param config the index config as the caller passed it. * @returns the checked config with every key in its camelCase spelling. */ export function normalizeIndexConfig(config) { const input = config; refuseRepeatedFields(input); return (input.type ?? IndexType.RAM) === IndexType.RAM ? parseConfigWithSchema(IndexConfig, input) : parseConfigWithSchema(RedisIndexConfig, input); } //# sourceMappingURL=config.js.map