@utilarium/overcontext 0.0.6 → 0.0.7-dev.20260220025748.d61df74
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -0
- package/dist/api/slug.js +12 -2
- package/dist/api/slug.js.map +1 -1
- package/dist/index.cjs +70 -10
- package/dist/index.cjs.map +1 -1
- package/dist/storage/filesystem.js +59 -9
- package/dist/storage/filesystem.js.map +1 -1
- package/package.json +17 -17
|
@@ -2,8 +2,12 @@ import * as fs from 'node:fs/promises';
|
|
|
2
2
|
import { existsSync, statSync } from 'node:fs';
|
|
3
3
|
import * as path from 'node:path';
|
|
4
4
|
import * as yaml from 'js-yaml';
|
|
5
|
-
import { ReadonlyStorageError, SchemaNotRegisteredError,
|
|
5
|
+
import { StorageAccessError, ReadonlyStorageError, SchemaNotRegisteredError, ValidationError } from './errors.js';
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Maximum number of entities allowed in a single batch operation.
|
|
9
|
+
* Prevents resource exhaustion from unbounded batch sizes.
|
|
10
|
+
*/ const MAX_BATCH_SIZE = 1000;
|
|
7
11
|
const createFileSystemProvider = async (options)=>{
|
|
8
12
|
const { basePath, registry, createIfMissing = true, extension = '.yaml', readonly = false, defaultNamespace, filenameStrategy } = options;
|
|
9
13
|
// --- Helper Functions ---
|
|
@@ -114,10 +118,8 @@ const createFileSystemProvider = async (options)=>{
|
|
|
114
118
|
const prefix = id.substring(0, Math.min(8, id.length));
|
|
115
119
|
const files = await fs.readdir(dir);
|
|
116
120
|
const candidates = files.filter((f)=>(f.endsWith('.yaml') || f.endsWith('.yml')) && f.startsWith(prefix));
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
}
|
|
120
|
-
// Multiple prefix matches — read and verify the id field
|
|
121
|
+
// Always verify the entity ID inside the file to prevent
|
|
122
|
+
// returning the wrong entity when IDs share a common prefix.
|
|
121
123
|
for (const file of candidates){
|
|
122
124
|
const filePath = path.join(dir, file);
|
|
123
125
|
const entity = await readEntity(filePath, type);
|
|
@@ -134,8 +136,35 @@ const createFileSystemProvider = async (options)=>{
|
|
|
134
136
|
});
|
|
135
137
|
}
|
|
136
138
|
};
|
|
139
|
+
// Cache the real basePath to handle symlinked temp directories (e.g., macOS /var/folders -> /private/var/folders).
|
|
140
|
+
// Computed lazily on first readEntity call once the directory exists.
|
|
141
|
+
let realBasePath;
|
|
137
142
|
const readEntity = async (filePath, type)=>{
|
|
138
143
|
try {
|
|
144
|
+
// Resolve symlinks and verify the real path is within basePath
|
|
145
|
+
// to prevent symlink-based path traversal.
|
|
146
|
+
let realFilePath;
|
|
147
|
+
try {
|
|
148
|
+
realFilePath = await fs.realpath(filePath);
|
|
149
|
+
} catch {
|
|
150
|
+
// If realpath fails (e.g., file doesn't exist), fall through to readFile
|
|
151
|
+
// which will throw ENOENT and be handled below.
|
|
152
|
+
realFilePath = filePath;
|
|
153
|
+
}
|
|
154
|
+
// Resolve basePath's real path to handle symlinked parent directories.
|
|
155
|
+
// Fall back to path.resolve if basePath doesn't exist yet.
|
|
156
|
+
if (!realBasePath) {
|
|
157
|
+
try {
|
|
158
|
+
realBasePath = await fs.realpath(basePath);
|
|
159
|
+
} catch {
|
|
160
|
+
realBasePath = path.resolve(basePath);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
if (!realFilePath.startsWith(realBasePath + path.sep) && realFilePath !== realBasePath) {
|
|
164
|
+
// eslint-disable-next-line no-console
|
|
165
|
+
console.warn(`Symlink traversal attempt detected: ${filePath} resolves to ${realFilePath}`);
|
|
166
|
+
return undefined;
|
|
167
|
+
}
|
|
139
168
|
const content = await fs.readFile(filePath, 'utf-8');
|
|
140
169
|
let parsed;
|
|
141
170
|
try {
|
|
@@ -148,14 +177,29 @@ const createFileSystemProvider = async (options)=>{
|
|
|
148
177
|
if (!parsed || typeof parsed !== 'object') {
|
|
149
178
|
return undefined;
|
|
150
179
|
}
|
|
151
|
-
// Protect against prototype pollution from malicious YAML
|
|
152
|
-
//
|
|
153
|
-
|
|
154
|
-
|
|
180
|
+
// Protect against prototype pollution from malicious YAML.
|
|
181
|
+
// Recursively check for __proto__ keys at all nesting levels,
|
|
182
|
+
// since nested __proto__ can still cause pollution when objects
|
|
183
|
+
// are spread or assigned downstream.
|
|
184
|
+
const hasProtoKey = (obj)=>{
|
|
185
|
+
if (!obj || typeof obj !== 'object') return false;
|
|
186
|
+
if (Object.prototype.hasOwnProperty.call(obj, '__proto__')) return true;
|
|
187
|
+
for (const value of Object.values(obj)){
|
|
188
|
+
if (hasProtoKey(value)) return true;
|
|
189
|
+
}
|
|
190
|
+
if (Array.isArray(obj)) {
|
|
191
|
+
for (const item of obj){
|
|
192
|
+
if (hasProtoKey(item)) return true;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return false;
|
|
196
|
+
};
|
|
197
|
+
if (hasProtoKey(parsed)) {
|
|
155
198
|
// eslint-disable-next-line no-console
|
|
156
199
|
console.warn(`Potential prototype pollution attempt in ${filePath}: __proto__ key detected`);
|
|
157
200
|
return undefined;
|
|
158
201
|
}
|
|
202
|
+
const parsedObj = parsed;
|
|
159
203
|
// Validate against registered schema
|
|
160
204
|
const result = registry.validateAs(type, {
|
|
161
205
|
...parsedObj,
|
|
@@ -371,6 +415,9 @@ const createFileSystemProvider = async (options)=>{
|
|
|
371
415
|
}
|
|
372
416
|
},
|
|
373
417
|
async saveBatch (entities, namespace) {
|
|
418
|
+
if (entities.length > MAX_BATCH_SIZE) {
|
|
419
|
+
throw new StorageAccessError(`Batch size ${entities.length} exceeds maximum of ${MAX_BATCH_SIZE}. Split into smaller batches.`);
|
|
420
|
+
}
|
|
374
421
|
const saved = [];
|
|
375
422
|
for (const entity of entities){
|
|
376
423
|
saved.push(await this.save(entity, namespace));
|
|
@@ -378,6 +425,9 @@ const createFileSystemProvider = async (options)=>{
|
|
|
378
425
|
return saved;
|
|
379
426
|
},
|
|
380
427
|
async deleteBatch (refs, namespace) {
|
|
428
|
+
if (refs.length > MAX_BATCH_SIZE) {
|
|
429
|
+
throw new StorageAccessError(`Batch size ${refs.length} exceeds maximum of ${MAX_BATCH_SIZE}. Split into smaller batches.`);
|
|
430
|
+
}
|
|
381
431
|
let count = 0;
|
|
382
432
|
for (const ref of refs){
|
|
383
433
|
if (await this.delete(ref.type, ref.id, namespace)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filesystem.js","sources":["../../src/storage/filesystem.ts"],"sourcesContent":["import * as fs from 'node:fs/promises';\nimport { existsSync, statSync } from 'node:fs';\nimport * as path from 'node:path';\nimport * as yaml from 'js-yaml';\nimport {\n StorageProvider,\n StorageProviderOptions,\n EntityFilter,\n} from './interface';\nimport { BaseEntity } from '../schema/base';\nimport {\n StorageAccessError,\n ValidationError,\n SchemaNotRegisteredError,\n ReadonlyStorageError,\n} from './errors';\n\nexport interface FileSystemProviderOptions extends StorageProviderOptions {\n /** Base path for context storage */\n basePath: string;\n\n /** Create directories if they don't exist */\n createIfMissing?: boolean;\n\n /** File extension to use (default: .yaml) */\n extension?: '.yaml' | '.yml';\n\n /**\n * Custom filename strategy. Given an entity, returns the filename stem (without extension).\n * When not provided, entity.id is used as the filename.\n * \n * Example: `(entity) => \\`\\${entity.id.substring(0, 8)}-\\${entity.slug}\\``\n * would produce filenames like `d00acdc4-gerald-corson.yaml`\n */\n filenameStrategy?: (entity: BaseEntity) => string;\n}\n\nexport const createFileSystemProvider = async (\n options: FileSystemProviderOptions\n): Promise<StorageProvider> => {\n const {\n basePath,\n registry,\n createIfMissing = true,\n extension = '.yaml',\n readonly = false,\n defaultNamespace,\n filenameStrategy,\n } = options;\n\n // --- Helper Functions ---\n\n /**\n * Sanitize a path component to prevent directory traversal attacks.\n * Rejects path separators, parent directory references, and other unsafe characters.\n */\n const sanitizePathComponent = (input: string, componentName: string): string => {\n // Reject path separators and parent directory references\n if (input.includes('/') || input.includes('\\\\') || input.includes('..')) {\n throw new ValidationError(\n `Invalid characters in ${componentName}: cannot contain path separators or \"..\"`,\n [{ path: componentName, message: 'Path component cannot contain path separators or \"..\"' }]\n );\n }\n // Reject null bytes and control characters\n if (input.includes('\\0')) {\n throw new ValidationError(\n `Invalid characters in ${componentName}: cannot contain null bytes`,\n [{ path: componentName, message: 'Path component cannot contain null bytes' }]\n );\n }\n // Check for control characters (0x00-0x1F and 0x7F)\n for (let i = 0; i < input.length; i++) {\n const code = input.charCodeAt(i);\n if ((code >= 0 && code <= 0x1F) || code === 0x7F) {\n throw new ValidationError(\n `Invalid characters in ${componentName}: cannot contain control characters`,\n [{ path: componentName, message: 'Path component cannot contain control characters' }]\n );\n }\n }\n return input;\n };\n\n /**\n * Verify that a resolved path stays within the basePath to prevent path traversal.\n */\n const verifyPathWithinBase = (resolvedPath: string): void => {\n const resolvedBase = path.resolve(basePath);\n const resolvedTarget = path.resolve(resolvedPath);\n \n if (!resolvedTarget.startsWith(resolvedBase + path.sep) && resolvedTarget !== resolvedBase) {\n throw new StorageAccessError('Path traversal attempt detected');\n }\n };\n\n const getEntityDir = (type: string, namespace?: string): string => {\n const dirName = registry.getDirectoryName(type);\n if (!dirName) {\n throw new SchemaNotRegisteredError(type);\n }\n\n // Sanitize namespace if provided\n const safeNamespace = namespace ? sanitizePathComponent(namespace, 'namespace') : undefined;\n \n // Sanitize directory name (should already be safe from registry, but double-check)\n const safeDirName = sanitizePathComponent(dirName, 'directoryName');\n\n let dir: string;\n if (safeNamespace) {\n dir = path.join(basePath, safeNamespace, safeDirName);\n } else {\n dir = path.join(basePath, safeDirName);\n }\n\n // Verify the path stays within basePath\n verifyPathWithinBase(dir);\n return dir;\n };\n\n const getEntityPath = (type: string, id: string, namespace?: string): string => {\n // Sanitize ID to prevent path traversal\n const safeId = sanitizePathComponent(id, 'id');\n \n const dir = getEntityDir(type, namespace);\n const fullPath = path.join(dir, `${safeId}${extension}`);\n \n // Verify the final path stays within basePath\n verifyPathWithinBase(fullPath);\n return fullPath;\n };\n\n const getEntityPathForWrite = (entity: BaseEntity, namespace?: string): string => {\n if (!filenameStrategy) {\n return getEntityPath(entity.type, entity.id, namespace);\n }\n\n const filename = filenameStrategy(entity);\n const safeFilename = sanitizePathComponent(filename, 'filename');\n const dir = getEntityDir(entity.type, namespace);\n const fullPath = path.join(dir, `${safeFilename}${extension}`);\n verifyPathWithinBase(fullPath);\n return fullPath;\n };\n\n /**\n * Find the actual file path for an entity by id, handling custom filename strategies.\n * Tries direct {id}{ext} first, then scans the directory using id prefix matching.\n */\n const findEntityFileById = async (type: string, id: string, namespace?: string): Promise<string | undefined> => {\n const directPath = getEntityPath(type, id, namespace);\n if (existsSync(directPath)) {\n return directPath;\n }\n\n if (!filenameStrategy) {\n return undefined;\n }\n\n let dir: string;\n try {\n dir = getEntityDir(type, namespace);\n } catch {\n return undefined;\n }\n\n if (!existsSync(dir)) {\n return undefined;\n }\n\n const prefix = id.substring(0, Math.min(8, id.length));\n const files = await fs.readdir(dir);\n const candidates = files.filter(f =>\n (f.endsWith('.yaml') || f.endsWith('.yml')) && f.startsWith(prefix)\n );\n\n if (candidates.length === 1) {\n return path.join(dir, candidates[0]);\n }\n\n // Multiple prefix matches — read and verify the id field\n for (const file of candidates) {\n const filePath = path.join(dir, file);\n const entity = await readEntity(filePath, type);\n if (entity && entity.id === id) {\n return filePath;\n }\n }\n\n return undefined;\n };\n\n const ensureDir = async (dir: string): Promise<void> => {\n if (!existsSync(dir) && createIfMissing && !readonly) {\n await fs.mkdir(dir, { recursive: true });\n }\n };\n\n const readEntity = async <T extends BaseEntity>(\n filePath: string,\n type: string\n ): Promise<T | undefined> => {\n try {\n const content = await fs.readFile(filePath, 'utf-8');\n \n let parsed: unknown;\n try {\n parsed = yaml.load(content);\n } catch (yamlError) {\n // eslint-disable-next-line no-console\n console.warn(`Invalid YAML at ${filePath}:`, yamlError);\n return undefined;\n }\n\n if (!parsed || typeof parsed !== 'object') {\n return undefined;\n }\n\n // Protect against prototype pollution from malicious YAML\n // Only __proto__ is dangerous - constructor/prototype as string keys are safe\n const parsedObj = parsed as Record<string, unknown>;\n if (Object.prototype.hasOwnProperty.call(parsedObj, '__proto__')) {\n // eslint-disable-next-line no-console\n console.warn(`Potential prototype pollution attempt in ${filePath}: __proto__ key detected`);\n return undefined;\n }\n\n // Validate against registered schema\n const result = registry.validateAs<T>(type, {\n ...parsedObj,\n source: filePath,\n });\n\n if (!result.success) {\n // eslint-disable-next-line no-console\n console.warn(`Invalid entity at ${filePath}:`, result.errors);\n return undefined;\n }\n\n return result.data;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return undefined;\n }\n throw new StorageAccessError(`Failed to read ${filePath}`, error as Error);\n }\n };\n\n const writeEntity = async <T extends BaseEntity>(\n entity: T,\n namespace?: string\n ): Promise<T> => {\n if (readonly) {\n throw new ReadonlyStorageError();\n }\n\n // Validate against schema\n const validationResult = registry.validate(entity);\n if (!validationResult.success) {\n throw new ValidationError(\n 'Entity validation failed',\n validationResult.errors || []\n );\n }\n\n const dir = getEntityDir(entity.type, namespace);\n await ensureDir(dir);\n\n const filePath = getEntityPathForWrite(entity, namespace);\n\n // If filenameStrategy is set, clean up any old file with a different name for the same id\n if (filenameStrategy) {\n const oldPath = await findEntityFileById(entity.type, entity.id, namespace);\n if (oldPath && path.resolve(oldPath) !== path.resolve(filePath)) {\n try { await fs.unlink(oldPath); } catch { /* best-effort cleanup */ }\n }\n }\n\n // Remove framework-managed fields from saved YAML\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { type: _type, source: _source, ...entityToSave } = entity;\n\n // Update metadata\n const now = new Date();\n const toSave = {\n ...entityToSave,\n updatedAt: now,\n createdAt: entityToSave.createdAt || now,\n };\n\n const content = yaml.dump(toSave, {\n lineWidth: -1,\n sortKeys: false,\n });\n await fs.writeFile(filePath, content, 'utf-8');\n\n return {\n ...entity,\n ...toSave,\n type: entity.type,\n source: filePath,\n } as T;\n };\n\n const listDirectoryTypes = async (basePath: string): Promise<string[]> => {\n const types: string[] = [];\n\n try {\n const entries = await fs.readdir(basePath, { withFileTypes: true });\n\n for (const entry of entries) {\n if (entry.isDirectory()) {\n const type = registry.getTypeFromDirectory(entry.name);\n if (type) {\n types.push(type);\n }\n }\n }\n } catch {\n // Directory doesn't exist\n }\n\n return types;\n };\n\n // --- StorageProvider Implementation ---\n\n const provider: StorageProvider = {\n name: 'filesystem',\n location: basePath,\n registry,\n\n async initialize(): Promise<void> {\n if (createIfMissing && !readonly) {\n await ensureDir(basePath);\n }\n\n if (!existsSync(basePath)) {\n throw new StorageAccessError(`Context path does not exist: ${basePath}`);\n }\n },\n\n async dispose(): Promise<void> {\n // No cleanup needed for filesystem\n },\n\n async isAvailable(): Promise<boolean> {\n try {\n const stat = statSync(basePath);\n return stat.isDirectory();\n } catch {\n return false;\n }\n },\n\n async get<T extends BaseEntity>(\n type: string,\n id: string,\n namespace?: string\n ): Promise<T | undefined> {\n const ns = namespace ?? defaultNamespace;\n if (filenameStrategy) {\n const filePath = await findEntityFileById(type, id, ns);\n if (!filePath) return undefined;\n return readEntity<T>(filePath, type);\n }\n const filePath = getEntityPath(type, id, ns);\n return readEntity<T>(filePath, type);\n },\n\n async getAll<T extends BaseEntity>(\n type: string,\n namespace?: string\n ): Promise<T[]> {\n const ns = namespace ?? defaultNamespace;\n\n let dir: string;\n try {\n dir = getEntityDir(type, ns);\n } catch (error) {\n if (error instanceof SchemaNotRegisteredError) {\n return [];\n }\n throw error;\n }\n\n if (!existsSync(dir)) {\n return [];\n }\n\n const files = await fs.readdir(dir);\n const entities: T[] = [];\n\n for (const file of files) {\n if (!file.endsWith('.yaml') && !file.endsWith('.yml')) {\n continue;\n }\n\n const entity = await readEntity<T>(path.join(dir, file), type);\n if (entity) {\n entities.push(entity);\n }\n }\n\n return entities;\n },\n\n async find<T extends BaseEntity>(filter: EntityFilter): Promise<T[]> {\n let results: T[] = [];\n\n const types = filter.type\n ? (Array.isArray(filter.type) ? filter.type : [filter.type])\n : registry.types();\n\n const namespace = filter.namespace ?? defaultNamespace;\n\n for (const type of types) {\n const entities = await this.getAll<T>(type, namespace);\n results = results.concat(entities);\n }\n\n // Apply ID filter\n if (filter.ids?.length) {\n results = results.filter(e => filter.ids!.includes(e.id));\n }\n\n // Apply search filter\n if (filter.search) {\n const searchLower = filter.search.toLowerCase();\n results = results.filter(e =>\n e.name.toLowerCase().includes(searchLower)\n );\n }\n\n // Apply pagination\n if (filter.offset) {\n results = results.slice(filter.offset);\n }\n if (filter.limit) {\n results = results.slice(0, filter.limit);\n }\n\n return results;\n },\n\n async exists(type: string, id: string, namespace?: string): Promise<boolean> {\n const ns = namespace ?? defaultNamespace;\n try {\n if (filenameStrategy) {\n const filePath = await findEntityFileById(type, id, ns);\n return filePath !== undefined;\n }\n const filePath = getEntityPath(type, id, ns);\n return existsSync(filePath);\n } catch {\n return false;\n }\n },\n\n async count(filter: EntityFilter): Promise<number> {\n const results = await this.find(filter);\n return results.length;\n },\n\n async save<T extends BaseEntity>(entity: T, namespace?: string): Promise<T> {\n const ns = namespace ?? defaultNamespace;\n return writeEntity(entity, ns);\n },\n\n async delete(type: string, id: string, namespace?: string): Promise<boolean> {\n if (readonly) {\n throw new ReadonlyStorageError();\n }\n\n const ns = namespace ?? defaultNamespace;\n\n try {\n if (filenameStrategy) {\n const filePath = await findEntityFileById(type, id, ns);\n if (!filePath) return false;\n await fs.unlink(filePath);\n return true;\n }\n const filePath = getEntityPath(type, id, ns);\n await fs.unlink(filePath);\n return true;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return false;\n }\n throw error;\n }\n },\n\n async saveBatch<T extends BaseEntity>(\n entities: T[],\n namespace?: string\n ): Promise<T[]> {\n const saved: T[] = [];\n for (const entity of entities) {\n saved.push(await this.save(entity, namespace));\n }\n return saved;\n },\n\n async deleteBatch(\n refs: Array<{ type: string; id: string }>,\n namespace?: string\n ): Promise<number> {\n let count = 0;\n for (const ref of refs) {\n if (await this.delete(ref.type, ref.id, namespace)) {\n count++;\n }\n }\n return count;\n },\n\n async listNamespaces(): Promise<string[]> {\n const namespaces: string[] = [];\n\n if (!existsSync(basePath)) {\n return namespaces;\n }\n\n const entries = await fs.readdir(basePath, { withFileTypes: true });\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n\n // Check if it's a namespace (contains entity type directories)\n // vs being an entity type directory itself\n const subPath = path.join(basePath, entry.name);\n const subTypes = await listDirectoryTypes(subPath);\n\n if (subTypes.length > 0) {\n namespaces.push(entry.name);\n }\n }\n\n return namespaces;\n },\n\n async namespaceExists(namespace: string): Promise<boolean> {\n // Sanitize namespace to prevent path traversal\n const safeNamespace = sanitizePathComponent(namespace, 'namespace');\n const namespacePath = path.join(basePath, safeNamespace);\n \n // Verify path stays within basePath\n verifyPathWithinBase(namespacePath);\n return existsSync(namespacePath);\n },\n\n async listTypes(namespace?: string): Promise<string[]> {\n const ns = namespace ?? defaultNamespace;\n let searchPath: string;\n if (ns) {\n // Sanitize namespace to prevent path traversal\n const safeNamespace = sanitizePathComponent(ns, 'namespace');\n searchPath = path.join(basePath, safeNamespace);\n verifyPathWithinBase(searchPath);\n } else {\n searchPath = basePath;\n }\n return listDirectoryTypes(searchPath);\n },\n };\n\n return provider;\n};\n"],"names":["createFileSystemProvider","options","basePath","registry","createIfMissing","extension","readonly","defaultNamespace","filenameStrategy","sanitizePathComponent","input","componentName","includes","ValidationError","path","message","i","length","code","charCodeAt","verifyPathWithinBase","resolvedPath","resolvedBase","resolve","resolvedTarget","startsWith","sep","StorageAccessError","getEntityDir","type","namespace","dirName","getDirectoryName","SchemaNotRegisteredError","safeNamespace","undefined","safeDirName","dir","join","getEntityPath","id","safeId","fullPath","getEntityPathForWrite","entity","filename","safeFilename","findEntityFileById","directPath","existsSync","prefix","substring","Math","min","files","fs","readdir","candidates","filter","f","endsWith","file","filePath","readEntity","ensureDir","mkdir","recursive","content","readFile","parsed","yaml","load","yamlError","console","warn","parsedObj","Object","prototype","hasOwnProperty","call","result","validateAs","source","success","errors","data","error","writeEntity","ReadonlyStorageError","validationResult","validate","oldPath","unlink","_type","_source","entityToSave","now","Date","toSave","updatedAt","createdAt","dump","lineWidth","sortKeys","writeFile","listDirectoryTypes","types","entries","withFileTypes","entry","isDirectory","getTypeFromDirectory","name","push","provider","location","initialize","dispose","isAvailable","stat","statSync","get","ns","getAll","entities","find","results","Array","isArray","concat","ids","e","search","searchLower","toLowerCase","offset","slice","limit","exists","count","save","delete","saveBatch","saved","deleteBatch","refs","ref","listNamespaces","namespaces","subPath","subTypes","namespaceExists","namespacePath","listTypes","searchPath"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"filesystem.js","sources":["../../src/storage/filesystem.ts"],"sourcesContent":["import * as fs from 'node:fs/promises';\nimport { existsSync, statSync } from 'node:fs';\nimport * as path from 'node:path';\nimport * as yaml from 'js-yaml';\nimport {\n StorageProvider,\n StorageProviderOptions,\n EntityFilter,\n} from './interface';\nimport { BaseEntity } from '../schema/base';\nimport {\n StorageAccessError,\n ValidationError,\n SchemaNotRegisteredError,\n ReadonlyStorageError,\n} from './errors';\n\nexport interface FileSystemProviderOptions extends StorageProviderOptions {\n /** Base path for context storage */\n basePath: string;\n\n /** Create directories if they don't exist */\n createIfMissing?: boolean;\n\n /** File extension to use (default: .yaml) */\n extension?: '.yaml' | '.yml';\n\n /**\n * Custom filename strategy. Given an entity, returns the filename stem (without extension).\n * When not provided, entity.id is used as the filename.\n * \n * Example: `(entity) => \\`\\${entity.id.substring(0, 8)}-\\${entity.slug}\\``\n * would produce filenames like `d00acdc4-gerald-corson.yaml`\n */\n filenameStrategy?: (entity: BaseEntity) => string;\n}\n\n/**\n * Maximum number of entities allowed in a single batch operation.\n * Prevents resource exhaustion from unbounded batch sizes.\n */\nconst MAX_BATCH_SIZE = 1000;\n\nexport const createFileSystemProvider = async (\n options: FileSystemProviderOptions\n): Promise<StorageProvider> => {\n const {\n basePath,\n registry,\n createIfMissing = true,\n extension = '.yaml',\n readonly = false,\n defaultNamespace,\n filenameStrategy,\n } = options;\n\n // --- Helper Functions ---\n\n /**\n * Sanitize a path component to prevent directory traversal attacks.\n * Rejects path separators, parent directory references, and other unsafe characters.\n */\n const sanitizePathComponent = (input: string, componentName: string): string => {\n // Reject path separators and parent directory references\n if (input.includes('/') || input.includes('\\\\') || input.includes('..')) {\n throw new ValidationError(\n `Invalid characters in ${componentName}: cannot contain path separators or \"..\"`,\n [{ path: componentName, message: 'Path component cannot contain path separators or \"..\"' }]\n );\n }\n // Reject null bytes and control characters\n if (input.includes('\\0')) {\n throw new ValidationError(\n `Invalid characters in ${componentName}: cannot contain null bytes`,\n [{ path: componentName, message: 'Path component cannot contain null bytes' }]\n );\n }\n // Check for control characters (0x00-0x1F and 0x7F)\n for (let i = 0; i < input.length; i++) {\n const code = input.charCodeAt(i);\n if ((code >= 0 && code <= 0x1F) || code === 0x7F) {\n throw new ValidationError(\n `Invalid characters in ${componentName}: cannot contain control characters`,\n [{ path: componentName, message: 'Path component cannot contain control characters' }]\n );\n }\n }\n return input;\n };\n\n /**\n * Verify that a resolved path stays within the basePath to prevent path traversal.\n */\n const verifyPathWithinBase = (resolvedPath: string): void => {\n const resolvedBase = path.resolve(basePath);\n const resolvedTarget = path.resolve(resolvedPath);\n \n if (!resolvedTarget.startsWith(resolvedBase + path.sep) && resolvedTarget !== resolvedBase) {\n throw new StorageAccessError('Path traversal attempt detected');\n }\n };\n\n const getEntityDir = (type: string, namespace?: string): string => {\n const dirName = registry.getDirectoryName(type);\n if (!dirName) {\n throw new SchemaNotRegisteredError(type);\n }\n\n // Sanitize namespace if provided\n const safeNamespace = namespace ? sanitizePathComponent(namespace, 'namespace') : undefined;\n \n // Sanitize directory name (should already be safe from registry, but double-check)\n const safeDirName = sanitizePathComponent(dirName, 'directoryName');\n\n let dir: string;\n if (safeNamespace) {\n dir = path.join(basePath, safeNamespace, safeDirName);\n } else {\n dir = path.join(basePath, safeDirName);\n }\n\n // Verify the path stays within basePath\n verifyPathWithinBase(dir);\n return dir;\n };\n\n const getEntityPath = (type: string, id: string, namespace?: string): string => {\n // Sanitize ID to prevent path traversal\n const safeId = sanitizePathComponent(id, 'id');\n \n const dir = getEntityDir(type, namespace);\n const fullPath = path.join(dir, `${safeId}${extension}`);\n \n // Verify the final path stays within basePath\n verifyPathWithinBase(fullPath);\n return fullPath;\n };\n\n const getEntityPathForWrite = (entity: BaseEntity, namespace?: string): string => {\n if (!filenameStrategy) {\n return getEntityPath(entity.type, entity.id, namespace);\n }\n\n const filename = filenameStrategy(entity);\n const safeFilename = sanitizePathComponent(filename, 'filename');\n const dir = getEntityDir(entity.type, namespace);\n const fullPath = path.join(dir, `${safeFilename}${extension}`);\n verifyPathWithinBase(fullPath);\n return fullPath;\n };\n\n /**\n * Find the actual file path for an entity by id, handling custom filename strategies.\n * Tries direct {id}{ext} first, then scans the directory using id prefix matching.\n */\n const findEntityFileById = async (type: string, id: string, namespace?: string): Promise<string | undefined> => {\n const directPath = getEntityPath(type, id, namespace);\n if (existsSync(directPath)) {\n return directPath;\n }\n\n if (!filenameStrategy) {\n return undefined;\n }\n\n let dir: string;\n try {\n dir = getEntityDir(type, namespace);\n } catch {\n return undefined;\n }\n\n if (!existsSync(dir)) {\n return undefined;\n }\n\n const prefix = id.substring(0, Math.min(8, id.length));\n const files = await fs.readdir(dir);\n const candidates = files.filter(f =>\n (f.endsWith('.yaml') || f.endsWith('.yml')) && f.startsWith(prefix)\n );\n\n // Always verify the entity ID inside the file to prevent\n // returning the wrong entity when IDs share a common prefix.\n for (const file of candidates) {\n const filePath = path.join(dir, file);\n const entity = await readEntity(filePath, type);\n if (entity && entity.id === id) {\n return filePath;\n }\n }\n\n return undefined;\n };\n\n const ensureDir = async (dir: string): Promise<void> => {\n if (!existsSync(dir) && createIfMissing && !readonly) {\n await fs.mkdir(dir, { recursive: true });\n }\n };\n\n // Cache the real basePath to handle symlinked temp directories (e.g., macOS /var/folders -> /private/var/folders).\n // Computed lazily on first readEntity call once the directory exists.\n let realBasePath: string | undefined;\n\n const readEntity = async <T extends BaseEntity>(\n filePath: string,\n type: string\n ): Promise<T | undefined> => {\n try {\n // Resolve symlinks and verify the real path is within basePath\n // to prevent symlink-based path traversal.\n let realFilePath: string;\n try {\n realFilePath = await fs.realpath(filePath);\n } catch {\n // If realpath fails (e.g., file doesn't exist), fall through to readFile\n // which will throw ENOENT and be handled below.\n realFilePath = filePath;\n }\n // Resolve basePath's real path to handle symlinked parent directories.\n // Fall back to path.resolve if basePath doesn't exist yet.\n if (!realBasePath) {\n try {\n realBasePath = await fs.realpath(basePath);\n } catch {\n realBasePath = path.resolve(basePath);\n }\n }\n if (!realFilePath.startsWith(realBasePath + path.sep) && realFilePath !== realBasePath) {\n // eslint-disable-next-line no-console\n console.warn(`Symlink traversal attempt detected: ${filePath} resolves to ${realFilePath}`);\n return undefined;\n }\n\n const content = await fs.readFile(filePath, 'utf-8');\n \n let parsed: unknown;\n try {\n parsed = yaml.load(content);\n } catch (yamlError) {\n // eslint-disable-next-line no-console\n console.warn(`Invalid YAML at ${filePath}:`, yamlError);\n return undefined;\n }\n\n if (!parsed || typeof parsed !== 'object') {\n return undefined;\n }\n\n // Protect against prototype pollution from malicious YAML.\n // Recursively check for __proto__ keys at all nesting levels,\n // since nested __proto__ can still cause pollution when objects\n // are spread or assigned downstream.\n const hasProtoKey = (obj: unknown): boolean => {\n if (!obj || typeof obj !== 'object') return false;\n if (Object.prototype.hasOwnProperty.call(obj, '__proto__')) return true;\n for (const value of Object.values(obj as Record<string, unknown>)) {\n if (hasProtoKey(value)) return true;\n }\n if (Array.isArray(obj)) {\n for (const item of obj) {\n if (hasProtoKey(item)) return true;\n }\n }\n return false;\n };\n\n if (hasProtoKey(parsed)) {\n // eslint-disable-next-line no-console\n console.warn(`Potential prototype pollution attempt in ${filePath}: __proto__ key detected`);\n return undefined;\n }\n\n const parsedObj = parsed as Record<string, unknown>;\n\n // Validate against registered schema\n const result = registry.validateAs<T>(type, {\n ...parsedObj,\n source: filePath,\n });\n\n if (!result.success) {\n // eslint-disable-next-line no-console\n console.warn(`Invalid entity at ${filePath}:`, result.errors);\n return undefined;\n }\n\n return result.data;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return undefined;\n }\n throw new StorageAccessError(`Failed to read ${filePath}`, error as Error);\n }\n };\n\n const writeEntity = async <T extends BaseEntity>(\n entity: T,\n namespace?: string\n ): Promise<T> => {\n if (readonly) {\n throw new ReadonlyStorageError();\n }\n\n // Validate against schema\n const validationResult = registry.validate(entity);\n if (!validationResult.success) {\n throw new ValidationError(\n 'Entity validation failed',\n validationResult.errors || []\n );\n }\n\n const dir = getEntityDir(entity.type, namespace);\n await ensureDir(dir);\n\n const filePath = getEntityPathForWrite(entity, namespace);\n\n // If filenameStrategy is set, clean up any old file with a different name for the same id\n if (filenameStrategy) {\n const oldPath = await findEntityFileById(entity.type, entity.id, namespace);\n if (oldPath && path.resolve(oldPath) !== path.resolve(filePath)) {\n try { await fs.unlink(oldPath); } catch { /* best-effort cleanup */ }\n }\n }\n\n // Remove framework-managed fields from saved YAML\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { type: _type, source: _source, ...entityToSave } = entity;\n\n // Update metadata\n const now = new Date();\n const toSave = {\n ...entityToSave,\n updatedAt: now,\n createdAt: entityToSave.createdAt || now,\n };\n\n const content = yaml.dump(toSave, {\n lineWidth: -1,\n sortKeys: false,\n });\n await fs.writeFile(filePath, content, 'utf-8');\n\n return {\n ...entity,\n ...toSave,\n type: entity.type,\n source: filePath,\n } as T;\n };\n\n const listDirectoryTypes = async (basePath: string): Promise<string[]> => {\n const types: string[] = [];\n\n try {\n const entries = await fs.readdir(basePath, { withFileTypes: true });\n\n for (const entry of entries) {\n if (entry.isDirectory()) {\n const type = registry.getTypeFromDirectory(entry.name);\n if (type) {\n types.push(type);\n }\n }\n }\n } catch {\n // Directory doesn't exist\n }\n\n return types;\n };\n\n // --- StorageProvider Implementation ---\n\n const provider: StorageProvider = {\n name: 'filesystem',\n location: basePath,\n registry,\n\n async initialize(): Promise<void> {\n if (createIfMissing && !readonly) {\n await ensureDir(basePath);\n }\n\n if (!existsSync(basePath)) {\n throw new StorageAccessError(`Context path does not exist: ${basePath}`);\n }\n },\n\n async dispose(): Promise<void> {\n // No cleanup needed for filesystem\n },\n\n async isAvailable(): Promise<boolean> {\n try {\n const stat = statSync(basePath);\n return stat.isDirectory();\n } catch {\n return false;\n }\n },\n\n async get<T extends BaseEntity>(\n type: string,\n id: string,\n namespace?: string\n ): Promise<T | undefined> {\n const ns = namespace ?? defaultNamespace;\n if (filenameStrategy) {\n const filePath = await findEntityFileById(type, id, ns);\n if (!filePath) return undefined;\n return readEntity<T>(filePath, type);\n }\n const filePath = getEntityPath(type, id, ns);\n return readEntity<T>(filePath, type);\n },\n\n async getAll<T extends BaseEntity>(\n type: string,\n namespace?: string\n ): Promise<T[]> {\n const ns = namespace ?? defaultNamespace;\n\n let dir: string;\n try {\n dir = getEntityDir(type, ns);\n } catch (error) {\n if (error instanceof SchemaNotRegisteredError) {\n return [];\n }\n throw error;\n }\n\n if (!existsSync(dir)) {\n return [];\n }\n\n const files = await fs.readdir(dir);\n const entities: T[] = [];\n\n for (const file of files) {\n if (!file.endsWith('.yaml') && !file.endsWith('.yml')) {\n continue;\n }\n\n const entity = await readEntity<T>(path.join(dir, file), type);\n if (entity) {\n entities.push(entity);\n }\n }\n\n return entities;\n },\n\n async find<T extends BaseEntity>(filter: EntityFilter): Promise<T[]> {\n let results: T[] = [];\n\n const types = filter.type\n ? (Array.isArray(filter.type) ? filter.type : [filter.type])\n : registry.types();\n\n const namespace = filter.namespace ?? defaultNamespace;\n\n for (const type of types) {\n const entities = await this.getAll<T>(type, namespace);\n results = results.concat(entities);\n }\n\n // Apply ID filter\n if (filter.ids?.length) {\n results = results.filter(e => filter.ids!.includes(e.id));\n }\n\n // Apply search filter\n if (filter.search) {\n const searchLower = filter.search.toLowerCase();\n results = results.filter(e =>\n e.name.toLowerCase().includes(searchLower)\n );\n }\n\n // Apply pagination\n if (filter.offset) {\n results = results.slice(filter.offset);\n }\n if (filter.limit) {\n results = results.slice(0, filter.limit);\n }\n\n return results;\n },\n\n async exists(type: string, id: string, namespace?: string): Promise<boolean> {\n const ns = namespace ?? defaultNamespace;\n try {\n if (filenameStrategy) {\n const filePath = await findEntityFileById(type, id, ns);\n return filePath !== undefined;\n }\n const filePath = getEntityPath(type, id, ns);\n return existsSync(filePath);\n } catch {\n return false;\n }\n },\n\n async count(filter: EntityFilter): Promise<number> {\n const results = await this.find(filter);\n return results.length;\n },\n\n async save<T extends BaseEntity>(entity: T, namespace?: string): Promise<T> {\n const ns = namespace ?? defaultNamespace;\n return writeEntity(entity, ns);\n },\n\n async delete(type: string, id: string, namespace?: string): Promise<boolean> {\n if (readonly) {\n throw new ReadonlyStorageError();\n }\n\n const ns = namespace ?? defaultNamespace;\n\n try {\n if (filenameStrategy) {\n const filePath = await findEntityFileById(type, id, ns);\n if (!filePath) return false;\n await fs.unlink(filePath);\n return true;\n }\n const filePath = getEntityPath(type, id, ns);\n await fs.unlink(filePath);\n return true;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return false;\n }\n throw error;\n }\n },\n\n async saveBatch<T extends BaseEntity>(\n entities: T[],\n namespace?: string\n ): Promise<T[]> {\n if (entities.length > MAX_BATCH_SIZE) {\n throw new StorageAccessError(\n `Batch size ${entities.length} exceeds maximum of ${MAX_BATCH_SIZE}. Split into smaller batches.`\n );\n }\n const saved: T[] = [];\n for (const entity of entities) {\n saved.push(await this.save(entity, namespace));\n }\n return saved;\n },\n\n async deleteBatch(\n refs: Array<{ type: string; id: string }>,\n namespace?: string\n ): Promise<number> {\n if (refs.length > MAX_BATCH_SIZE) {\n throw new StorageAccessError(\n `Batch size ${refs.length} exceeds maximum of ${MAX_BATCH_SIZE}. Split into smaller batches.`\n );\n }\n let count = 0;\n for (const ref of refs) {\n if (await this.delete(ref.type, ref.id, namespace)) {\n count++;\n }\n }\n return count;\n },\n\n async listNamespaces(): Promise<string[]> {\n const namespaces: string[] = [];\n\n if (!existsSync(basePath)) {\n return namespaces;\n }\n\n const entries = await fs.readdir(basePath, { withFileTypes: true });\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n\n // Check if it's a namespace (contains entity type directories)\n // vs being an entity type directory itself\n const subPath = path.join(basePath, entry.name);\n const subTypes = await listDirectoryTypes(subPath);\n\n if (subTypes.length > 0) {\n namespaces.push(entry.name);\n }\n }\n\n return namespaces;\n },\n\n async namespaceExists(namespace: string): Promise<boolean> {\n // Sanitize namespace to prevent path traversal\n const safeNamespace = sanitizePathComponent(namespace, 'namespace');\n const namespacePath = path.join(basePath, safeNamespace);\n \n // Verify path stays within basePath\n verifyPathWithinBase(namespacePath);\n return existsSync(namespacePath);\n },\n\n async listTypes(namespace?: string): Promise<string[]> {\n const ns = namespace ?? defaultNamespace;\n let searchPath: string;\n if (ns) {\n // Sanitize namespace to prevent path traversal\n const safeNamespace = sanitizePathComponent(ns, 'namespace');\n searchPath = path.join(basePath, safeNamespace);\n verifyPathWithinBase(searchPath);\n } else {\n searchPath = basePath;\n }\n return listDirectoryTypes(searchPath);\n },\n };\n\n return provider;\n};\n"],"names":["MAX_BATCH_SIZE","createFileSystemProvider","options","basePath","registry","createIfMissing","extension","readonly","defaultNamespace","filenameStrategy","sanitizePathComponent","input","componentName","includes","ValidationError","path","message","i","length","code","charCodeAt","verifyPathWithinBase","resolvedPath","resolvedBase","resolve","resolvedTarget","startsWith","sep","StorageAccessError","getEntityDir","type","namespace","dirName","getDirectoryName","SchemaNotRegisteredError","safeNamespace","undefined","safeDirName","dir","join","getEntityPath","id","safeId","fullPath","getEntityPathForWrite","entity","filename","safeFilename","findEntityFileById","directPath","existsSync","prefix","substring","Math","min","files","fs","readdir","candidates","filter","f","endsWith","file","filePath","readEntity","ensureDir","mkdir","recursive","realBasePath","realFilePath","realpath","console","warn","content","readFile","parsed","yaml","load","yamlError","hasProtoKey","obj","Object","prototype","hasOwnProperty","call","value","values","Array","isArray","item","parsedObj","result","validateAs","source","success","errors","data","error","writeEntity","ReadonlyStorageError","validationResult","validate","oldPath","unlink","_type","_source","entityToSave","now","Date","toSave","updatedAt","createdAt","dump","lineWidth","sortKeys","writeFile","listDirectoryTypes","types","entries","withFileTypes","entry","isDirectory","getTypeFromDirectory","name","push","provider","location","initialize","dispose","isAvailable","stat","statSync","get","ns","getAll","entities","find","results","concat","ids","e","search","searchLower","toLowerCase","offset","slice","limit","exists","count","save","delete","saveBatch","saved","deleteBatch","refs","ref","listNamespaces","namespaces","subPath","subTypes","namespaceExists","namespacePath","listTypes","searchPath"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@utilarium/overcontext",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.7-dev.20260220025748.d61df74",
|
|
4
4
|
"description": "Schema-driven framework for context management - provides infrastructure for defining and managing custom entity schemas.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
"watch": "vite build --watch",
|
|
30
30
|
"test": "vitest run --coverage",
|
|
31
31
|
"precommit": "npm run lint && npm run test",
|
|
32
|
-
"lint": "eslint .
|
|
33
|
-
"lint:fix": "eslint . --
|
|
32
|
+
"lint": "eslint .",
|
|
33
|
+
"lint:fix": "eslint . --fix",
|
|
34
34
|
"clean": "rm -rf dist",
|
|
35
35
|
"prepublishOnly": "npm run clean && npm run build",
|
|
36
36
|
"docs:dev": "cd docs && cp ../README.md public/ && npm install && npm run dev",
|
|
@@ -60,24 +60,24 @@
|
|
|
60
60
|
"zod": "^4.3.6"
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|
|
63
|
-
"@eslint/
|
|
64
|
-
"@eslint/js": "^9.
|
|
65
|
-
"@rollup/plugin-replace": "^6.0.
|
|
66
|
-
"@swc/core": "^1.
|
|
63
|
+
"@eslint/compat": "^1.4.1",
|
|
64
|
+
"@eslint/js": "^9.39.2",
|
|
65
|
+
"@rollup/plugin-replace": "^6.0.3",
|
|
66
|
+
"@swc/core": "^1.15.11",
|
|
67
67
|
"@types/js-yaml": "^4.0.9",
|
|
68
|
-
"@types/node": "^25.0
|
|
69
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
70
|
-
"@typescript-eslint/parser": "^8.
|
|
71
|
-
"@vitest/coverage-v8": "^4.0.
|
|
72
|
-
"ajv": "^8.
|
|
73
|
-
"eslint": "^9.
|
|
68
|
+
"@types/node": "^25.3.0",
|
|
69
|
+
"@typescript-eslint/eslint-plugin": "^8.56.0",
|
|
70
|
+
"@typescript-eslint/parser": "^8.56.0",
|
|
71
|
+
"@vitest/coverage-v8": "^4.0.18",
|
|
72
|
+
"ajv": "^8.18.0",
|
|
73
|
+
"eslint": "^9.39.2",
|
|
74
74
|
"eslint-plugin-import": "^2.32.0",
|
|
75
|
-
"globals": "^17.
|
|
76
|
-
"typescript": "^5.
|
|
77
|
-
"vite": "^7.
|
|
75
|
+
"globals": "^17.3.0",
|
|
76
|
+
"typescript": "^5.9.3",
|
|
77
|
+
"vite": "^7.3.1",
|
|
78
78
|
"vite-plugin-dts": "^4.5.4",
|
|
79
79
|
"vite-plugin-node": "^7.0.0",
|
|
80
|
-
"vitest": "^4.0.
|
|
80
|
+
"vitest": "^4.0.18"
|
|
81
81
|
},
|
|
82
82
|
"overrides": {
|
|
83
83
|
"wrap-ansi": "7.0.0"
|