@utilarium/overcontext 0.0.4-dev.0 → 0.0.4

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.
@@ -14,7 +14,9 @@ import { z } from 'zod';
14
14
  * The minimal contract every entity must satisfy.
15
15
  * Consuming libraries extend this with their own fields.
16
16
  */ const BaseEntitySchema = z.object({
17
- /** Unique identifier within the entity type (used as filename) */ id: z.string().min(1),
17
+ /** Unique identifier within the entity type (used as filename) */ id: z.string().min(1).max(255).regex(/^[a-zA-Z0-9][-a-zA-Z0-9_.]*$/, {
18
+ message: 'ID must be filesystem-safe: start with alphanumeric and contain only alphanumeric, hyphens, underscores, and dots'
19
+ }),
18
20
  /** Human-readable name (used for display and search) */ name: z.string().min(1),
19
21
  /** Entity type discriminator (must be a string literal in extensions) */ type: z.string().min(1),
20
22
  /** Optional notes - common enough to include in base */ notes: z.string().optional()
@@ -1 +1 @@
1
- {"version":3,"file":"base.js","sources":["../../src/schema/base.ts"],"sourcesContent":["import { z } from 'zod';\n\n/**\n * Metadata that overcontext manages automatically.\n * Consumers don't need to define these.\n */\nexport const EntityMetadataSchema = z.object({\n createdAt: z.date().optional(),\n updatedAt: z.date().optional(),\n createdBy: z.string().optional(), // Tool that created this entity\n namespace: z.string().optional(), // Which namespace this came from\n source: z.string().optional(), // File path or storage key\n});\n\nexport type EntityMetadata = z.infer<typeof EntityMetadataSchema>;\n\n/**\n * The minimal contract every entity must satisfy.\n * Consuming libraries extend this with their own fields.\n */\nexport const BaseEntitySchema = z.object({\n /** Unique identifier within the entity type (used as filename) */\n id: z.string().min(1),\n\n /** Human-readable name (used for display and search) */\n name: z.string().min(1),\n\n /** Entity type discriminator (must be a string literal in extensions) */\n type: z.string().min(1),\n\n /** Optional notes - common enough to include in base */\n notes: z.string().optional(),\n}).merge(EntityMetadataSchema);\n\nexport type BaseEntity = z.infer<typeof BaseEntitySchema>;\n"],"names":["EntityMetadataSchema","z","object","createdAt","date","optional","updatedAt","createdBy","string","namespace","source","BaseEntitySchema","id","min","name","type","notes","merge"],"mappings":";;AAEA;;;AAGC,IACM,MAAMA,oBAAAA,GAAuBC,CAAAA,CAAEC,MAAM,CAAC;IACzCC,SAAAA,EAAWF,CAAAA,CAAEG,IAAI,EAAA,CAAGC,QAAQ,EAAA;IAC5BC,SAAAA,EAAWL,CAAAA,CAAEG,IAAI,EAAA,CAAGC,QAAQ,EAAA;IAC5BE,SAAAA,EAAWN,CAAAA,CAAEO,MAAM,EAAA,CAAGH,QAAQ,EAAA;IAC9BI,SAAAA,EAAWR,CAAAA,CAAEO,MAAM,EAAA,CAAGH,QAAQ,EAAA;IAC9BK,MAAAA,EAAQT,CAAAA,CAAEO,MAAM,EAAA,CAAGH,QAAQ;AAC/B,CAAA;AAIA;;;AAGC,IACM,MAAMM,gBAAAA,GAAmBV,CAAAA,CAAEC,MAAM,CAAC;AACrC,uEACAU,EAAAA,EAAIX,CAAAA,CAAEO,MAAM,EAAA,CAAGK,GAAG,CAAC,CAAA,CAAA;AAEnB,6DACAC,IAAAA,EAAMb,CAAAA,CAAEO,MAAM,EAAA,CAAGK,GAAG,CAAC,CAAA,CAAA;AAErB,8EACAE,IAAAA,EAAMd,CAAAA,CAAEO,MAAM,EAAA,CAAGK,GAAG,CAAC,CAAA,CAAA;AAErB,6DACAG,KAAAA,EAAOf,CAAAA,CAAEO,MAAM,GAAGH,QAAQ;AAC9B,CAAA,CAAA,CAAGY,KAAK,CAACjB,oBAAAA;;;;"}
1
+ {"version":3,"file":"base.js","sources":["../../src/schema/base.ts"],"sourcesContent":["import { z } from 'zod';\n\n/**\n * Metadata that overcontext manages automatically.\n * Consumers don't need to define these.\n */\nexport const EntityMetadataSchema = z.object({\n createdAt: z.date().optional(),\n updatedAt: z.date().optional(),\n createdBy: z.string().optional(), // Tool that created this entity\n namespace: z.string().optional(), // Which namespace this came from\n source: z.string().optional(), // File path or storage key\n});\n\nexport type EntityMetadata = z.infer<typeof EntityMetadataSchema>;\n\n/**\n * The minimal contract every entity must satisfy.\n * Consuming libraries extend this with their own fields.\n */\nexport const BaseEntitySchema = z.object({\n /** Unique identifier within the entity type (used as filename) */\n id: z.string()\n .min(1)\n .max(255)\n .regex(/^[a-zA-Z0-9][-a-zA-Z0-9_.]*$/, {\n message: 'ID must be filesystem-safe: start with alphanumeric and contain only alphanumeric, hyphens, underscores, and dots',\n }),\n\n /** Human-readable name (used for display and search) */\n name: z.string().min(1),\n\n /** Entity type discriminator (must be a string literal in extensions) */\n type: z.string().min(1),\n\n /** Optional notes - common enough to include in base */\n notes: z.string().optional(),\n}).merge(EntityMetadataSchema);\n\nexport type BaseEntity = z.infer<typeof BaseEntitySchema>;\n"],"names":["EntityMetadataSchema","z","object","createdAt","date","optional","updatedAt","createdBy","string","namespace","source","BaseEntitySchema","id","min","max","regex","message","name","type","notes","merge"],"mappings":";;AAEA;;;AAGC,IACM,MAAMA,oBAAAA,GAAuBC,CAAAA,CAAEC,MAAM,CAAC;IACzCC,SAAAA,EAAWF,CAAAA,CAAEG,IAAI,EAAA,CAAGC,QAAQ,EAAA;IAC5BC,SAAAA,EAAWL,CAAAA,CAAEG,IAAI,EAAA,CAAGC,QAAQ,EAAA;IAC5BE,SAAAA,EAAWN,CAAAA,CAAEO,MAAM,EAAA,CAAGH,QAAQ,EAAA;IAC9BI,SAAAA,EAAWR,CAAAA,CAAEO,MAAM,EAAA,CAAGH,QAAQ,EAAA;IAC9BK,MAAAA,EAAQT,CAAAA,CAAEO,MAAM,EAAA,CAAGH,QAAQ;AAC/B,CAAA;AAIA;;;AAGC,IACM,MAAMM,gBAAAA,GAAmBV,CAAAA,CAAEC,MAAM,CAAC;AACrC,uEACAU,EAAAA,EAAIX,CAAAA,CAAEO,MAAM,EAAA,CACPK,GAAG,CAAC,CAAA,CAAA,CACJC,GAAG,CAAC,GAAA,CAAA,CACJC,KAAK,CAAC,8BAAA,EAAgC;QACnCC,OAAAA,EAAS;AACb,KAAA,CAAA;AAEJ,6DACAC,IAAAA,EAAMhB,CAAAA,CAAEO,MAAM,EAAA,CAAGK,GAAG,CAAC,CAAA,CAAA;AAErB,8EACAK,IAAAA,EAAMjB,CAAAA,CAAEO,MAAM,EAAA,CAAGK,GAAG,CAAC,CAAA,CAAA;AAErB,6DACAM,KAAAA,EAAOlB,CAAAA,CAAEO,MAAM,GAAGH,QAAQ;AAC9B,CAAA,CAAA,CAAGe,KAAK,CAACpB,oBAAAA;;;;"}
@@ -7,18 +7,78 @@ import { ReadonlyStorageError, SchemaNotRegisteredError, StorageAccessError, Val
7
7
  const createFileSystemProvider = async (options)=>{
8
8
  const { basePath, registry, createIfMissing = true, extension = '.yaml', readonly = false, defaultNamespace } = options;
9
9
  // --- Helper Functions ---
10
+ /**
11
+ * Sanitize a path component to prevent directory traversal attacks.
12
+ * Rejects path separators, parent directory references, and other unsafe characters.
13
+ */ const sanitizePathComponent = (input, componentName)=>{
14
+ // Reject path separators and parent directory references
15
+ if (input.includes('/') || input.includes('\\') || input.includes('..')) {
16
+ throw new ValidationError(`Invalid characters in ${componentName}: cannot contain path separators or ".."`, [
17
+ {
18
+ path: componentName,
19
+ message: 'Path component cannot contain path separators or ".."'
20
+ }
21
+ ]);
22
+ }
23
+ // Reject null bytes and control characters
24
+ if (input.includes('\0')) {
25
+ throw new ValidationError(`Invalid characters in ${componentName}: cannot contain null bytes`, [
26
+ {
27
+ path: componentName,
28
+ message: 'Path component cannot contain null bytes'
29
+ }
30
+ ]);
31
+ }
32
+ // Check for control characters (0x00-0x1F and 0x7F)
33
+ for(let i = 0; i < input.length; i++){
34
+ const code = input.charCodeAt(i);
35
+ if (code >= 0 && code <= 0x1F || code === 0x7F) {
36
+ throw new ValidationError(`Invalid characters in ${componentName}: cannot contain control characters`, [
37
+ {
38
+ path: componentName,
39
+ message: 'Path component cannot contain control characters'
40
+ }
41
+ ]);
42
+ }
43
+ }
44
+ return input;
45
+ };
46
+ /**
47
+ * Verify that a resolved path stays within the basePath to prevent path traversal.
48
+ */ const verifyPathWithinBase = (resolvedPath)=>{
49
+ const resolvedBase = path.resolve(basePath);
50
+ const resolvedTarget = path.resolve(resolvedPath);
51
+ if (!resolvedTarget.startsWith(resolvedBase + path.sep) && resolvedTarget !== resolvedBase) {
52
+ throw new StorageAccessError('Path traversal attempt detected');
53
+ }
54
+ };
10
55
  const getEntityDir = (type, namespace)=>{
11
56
  const dirName = registry.getDirectoryName(type);
12
57
  if (!dirName) {
13
58
  throw new SchemaNotRegisteredError(type);
14
59
  }
15
- if (namespace) {
16
- return path.join(basePath, namespace, dirName);
60
+ // Sanitize namespace if provided
61
+ const safeNamespace = namespace ? sanitizePathComponent(namespace, 'namespace') : undefined;
62
+ // Sanitize directory name (should already be safe from registry, but double-check)
63
+ const safeDirName = sanitizePathComponent(dirName, 'directoryName');
64
+ let dir;
65
+ if (safeNamespace) {
66
+ dir = path.join(basePath, safeNamespace, safeDirName);
67
+ } else {
68
+ dir = path.join(basePath, safeDirName);
17
69
  }
18
- return path.join(basePath, dirName);
70
+ // Verify the path stays within basePath
71
+ verifyPathWithinBase(dir);
72
+ return dir;
19
73
  };
20
74
  const getEntityPath = (type, id, namespace)=>{
21
- return path.join(getEntityDir(type, namespace), `${id}${extension}`);
75
+ // Sanitize ID to prevent path traversal
76
+ const safeId = sanitizePathComponent(id, 'id');
77
+ const dir = getEntityDir(type, namespace);
78
+ const fullPath = path.join(dir, `${safeId}${extension}`);
79
+ // Verify the final path stays within basePath
80
+ verifyPathWithinBase(fullPath);
81
+ return fullPath;
22
82
  };
23
83
  const ensureDir = async (dir)=>{
24
84
  if (!existsSync(dir) && createIfMissing && !readonly) {
@@ -41,9 +101,17 @@ const createFileSystemProvider = async (options)=>{
41
101
  if (!parsed || typeof parsed !== 'object') {
42
102
  return undefined;
43
103
  }
104
+ // Protect against prototype pollution from malicious YAML
105
+ // Only __proto__ is dangerous - constructor/prototype as string keys are safe
106
+ const parsedObj = parsed;
107
+ if (Object.prototype.hasOwnProperty.call(parsedObj, '__proto__')) {
108
+ // eslint-disable-next-line no-console
109
+ console.warn(`Potential prototype pollution attempt in ${filePath}: __proto__ key detected`);
110
+ return undefined;
111
+ }
44
112
  // Validate against registered schema
45
113
  const result = registry.validateAs(type, {
46
- ...parsed,
114
+ ...parsedObj,
47
115
  source: filePath
48
116
  });
49
117
  if (!result.success) {
@@ -268,12 +336,24 @@ const createFileSystemProvider = async (options)=>{
268
336
  return namespaces;
269
337
  },
270
338
  async namespaceExists (namespace) {
271
- const namespacePath = path.join(basePath, namespace);
339
+ // Sanitize namespace to prevent path traversal
340
+ const safeNamespace = sanitizePathComponent(namespace, 'namespace');
341
+ const namespacePath = path.join(basePath, safeNamespace);
342
+ // Verify path stays within basePath
343
+ verifyPathWithinBase(namespacePath);
272
344
  return existsSync(namespacePath);
273
345
  },
274
346
  async listTypes (namespace) {
275
347
  const ns = namespace !== null && namespace !== void 0 ? namespace : defaultNamespace;
276
- const searchPath = ns ? path.join(basePath, ns) : basePath;
348
+ let searchPath;
349
+ if (ns) {
350
+ // Sanitize namespace to prevent path traversal
351
+ const safeNamespace = sanitizePathComponent(ns, 'namespace');
352
+ searchPath = path.join(basePath, safeNamespace);
353
+ verifyPathWithinBase(searchPath);
354
+ } else {
355
+ searchPath = basePath;
356
+ }
277
357
  return listDirectoryTypes(searchPath);
278
358
  }
279
359
  };
@@ -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\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 } = options;\n\n // --- Helper Functions ---\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 if (namespace) {\n return path.join(basePath, namespace, dirName);\n }\n return path.join(basePath, dirName);\n };\n\n const getEntityPath = (type: string, id: string, namespace?: string): string => {\n return path.join(getEntityDir(type, namespace), `${id}${extension}`);\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 // Validate against registered schema\n const result = registry.validateAs<T>(type, {\n ...(parsed as Record<string, unknown>),\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 = getEntityPath(entity.type, entity.id, namespace);\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 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 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 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 const namespacePath = path.join(basePath, namespace);\n return existsSync(namespacePath);\n },\n\n async listTypes(namespace?: string): Promise<string[]> {\n const ns = namespace ?? defaultNamespace;\n const searchPath = ns ? path.join(basePath, ns) : basePath;\n return listDirectoryTypes(searchPath);\n },\n };\n\n return provider;\n};\n"],"names":["createFileSystemProvider","options","basePath","registry","createIfMissing","extension","readonly","defaultNamespace","getEntityDir","type","namespace","dirName","getDirectoryName","SchemaNotRegisteredError","path","join","getEntityPath","id","ensureDir","dir","existsSync","fs","mkdir","recursive","readEntity","filePath","content","readFile","parsed","yaml","load","yamlError","console","warn","undefined","result","validateAs","source","success","errors","data","error","code","StorageAccessError","writeEntity","entity","ReadonlyStorageError","validationResult","validate","ValidationError","_type","_source","entityToSave","now","Date","toSave","updatedAt","createdAt","dump","lineWidth","sortKeys","writeFile","listDirectoryTypes","types","entries","readdir","withFileTypes","entry","isDirectory","getTypeFromDirectory","name","push","provider","location","initialize","dispose","isAvailable","stat","statSync","get","ns","getAll","files","entities","file","endsWith","find","filter","results","Array","isArray","concat","ids","length","e","includes","search","searchLower","toLowerCase","offset","slice","limit","exists","count","save","delete","unlink","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\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 } = 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 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 = getEntityPath(entity.type, entity.id, namespace);\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 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 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 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","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","ensureDir","existsSync","fs","mkdir","recursive","readEntity","filePath","content","readFile","parsed","yaml","load","yamlError","console","warn","parsedObj","Object","prototype","hasOwnProperty","call","result","validateAs","source","success","errors","data","error","writeEntity","entity","ReadonlyStorageError","validationResult","validate","_type","_source","entityToSave","now","Date","toSave","updatedAt","createdAt","dump","lineWidth","sortKeys","writeFile","listDirectoryTypes","types","entries","readdir","withFileTypes","entry","isDirectory","getTypeFromDirectory","name","push","provider","location","initialize","dispose","isAvailable","stat","statSync","get","ns","getAll","files","entities","file","endsWith","find","filter","results","Array","isArray","concat","ids","e","search","searchLower","toLowerCase","offset","slice","limit","exists","count","save","delete","unlink","saveBatch","saved","deleteBatch","refs","ref","listNamespaces","namespaces","subPath","subTypes","namespaceExists","namespacePath","listTypes","searchPath"],"mappings":"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"}
@@ -1,5 +1,12 @@
1
1
  import { ReadonlyStorageError, ValidationError } from './errors.js';
2
2
 
3
+ /**
4
+ * Create a deep clone of an entity to prevent external mutation of stored data.
5
+ * Uses structured clone for proper handling of dates and nested objects.
6
+ */ const cloneEntity = (entity)=>{
7
+ // structuredClone handles Date objects properly
8
+ return structuredClone(entity);
9
+ };
3
10
  const createMemoryProvider = (options)=>{
4
11
  const { registry, readonly = false, defaultNamespace, initialData = [] } = options;
5
12
  // Storage: namespace -> type -> id -> entity
@@ -39,11 +46,14 @@ const createMemoryProvider = (options)=>{
39
46
  },
40
47
  async get (type, id, namespace) {
41
48
  const ns = resolveNamespace(namespace);
42
- return getTypeStore(ns, type).get(id);
49
+ const entity = getTypeStore(ns, type).get(id);
50
+ // Return a defensive copy to prevent external mutation of stored data
51
+ return entity ? cloneEntity(entity) : undefined;
43
52
  },
44
53
  async getAll (type, namespace) {
45
54
  const ns = resolveNamespace(namespace);
46
- return Array.from(getTypeStore(ns, type).values());
55
+ // Return defensive copies to prevent external mutation
56
+ return Array.from(getTypeStore(ns, type).values()).map((e)=>cloneEntity(e));
47
57
  },
48
58
  async find (filter) {
49
59
  var _filter_ids;
@@ -90,8 +100,10 @@ const createMemoryProvider = (options)=>{
90
100
  createdAt: (existing === null || existing === void 0 ? void 0 : existing.createdAt) || now,
91
101
  updatedAt: now
92
102
  };
93
- getTypeStore(ns, entity.type).set(entity.id, saved);
94
- return saved;
103
+ // Store a cloned copy to prevent external mutation from affecting stored data
104
+ getTypeStore(ns, entity.type).set(entity.id, cloneEntity(saved));
105
+ // Return a clone so caller can't mutate stored data through returned reference
106
+ return cloneEntity(saved);
95
107
  },
96
108
  async delete (type, id, namespace) {
97
109
  if (readonly) {
@@ -1 +1 @@
1
- {"version":3,"file":"memory.js","sources":["../../src/storage/memory.ts"],"sourcesContent":["import { StorageProvider, StorageProviderOptions, EntityFilter } from './interface';\nimport { BaseEntity } from '../schema/base';\nimport { ValidationError, ReadonlyStorageError } from './errors';\n\nexport interface MemoryProviderOptions extends StorageProviderOptions {\n /** Initial data to populate */\n initialData?: BaseEntity[];\n}\n\nexport const createMemoryProvider = (\n options: MemoryProviderOptions\n): StorageProvider => {\n const { registry, readonly = false, defaultNamespace, initialData = [] } = options;\n\n // Storage: namespace -> type -> id -> entity\n const store = new Map<string, Map<string, Map<string, BaseEntity>>>();\n\n const getNamespaceStore = (namespace: string): Map<string, Map<string, BaseEntity>> => {\n if (!store.has(namespace)) {\n store.set(namespace, new Map());\n }\n return store.get(namespace)!;\n };\n\n const getTypeStore = (\n namespace: string,\n type: string\n ): Map<string, BaseEntity> => {\n const nsStore = getNamespaceStore(namespace);\n if (!nsStore.has(type)) {\n nsStore.set(type, new Map());\n }\n return nsStore.get(type)!;\n };\n\n const resolveNamespace = (ns?: string): string => ns ?? defaultNamespace ?? '_default';\n\n // Initialize with any provided data\n for (const entity of initialData) {\n const ns = resolveNamespace(entity.namespace);\n getTypeStore(ns, entity.type).set(entity.id, entity);\n }\n\n return {\n name: 'memory',\n location: 'in-memory',\n registry,\n\n async initialize() { },\n\n async dispose() {\n store.clear();\n },\n\n async isAvailable() {\n return true;\n },\n\n async get<T extends BaseEntity>(\n type: string,\n id: string,\n namespace?: string\n ): Promise<T | undefined> {\n const ns = resolveNamespace(namespace);\n return getTypeStore(ns, type).get(id) as T | undefined;\n },\n\n async getAll<T extends BaseEntity>(\n type: string,\n namespace?: string\n ): Promise<T[]> {\n const ns = resolveNamespace(namespace);\n return Array.from(getTypeStore(ns, type).values()) as T[];\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 ns = resolveNamespace(filter.namespace);\n\n for (const type of types) {\n results = results.concat(await this.getAll<T>(type, ns));\n }\n\n if (filter.ids?.length) {\n results = results.filter(e => filter.ids!.includes(e.id));\n }\n\n if (filter.search) {\n const s = filter.search.toLowerCase();\n results = results.filter(e => e.name.toLowerCase().includes(s));\n }\n\n if (filter.offset) results = results.slice(filter.offset);\n if (filter.limit) results = results.slice(0, filter.limit);\n\n return results;\n },\n\n async exists(type: string, id: string, namespace?: string): Promise<boolean> {\n const ns = resolveNamespace(namespace);\n return getTypeStore(ns, type).has(id);\n },\n\n async count(filter: EntityFilter): Promise<number> {\n return (await this.find(filter)).length;\n },\n\n async save<T extends BaseEntity>(entity: T, namespace?: string): Promise<T> {\n if (readonly) {\n throw new ReadonlyStorageError();\n }\n\n const validationResult = registry.validate(entity);\n if (!validationResult.success) {\n throw new ValidationError(\n 'Validation failed',\n validationResult.errors || []\n );\n }\n\n const ns = resolveNamespace(namespace);\n const now = new Date();\n const existing = getTypeStore(ns, entity.type).get(entity.id);\n\n const saved = {\n ...entity,\n namespace: ns,\n createdAt: existing?.createdAt || now,\n updatedAt: now,\n } as T;\n\n getTypeStore(ns, entity.type).set(entity.id, saved);\n return saved;\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 = resolveNamespace(namespace);\n return getTypeStore(ns, type).delete(id);\n },\n\n async saveBatch<T extends BaseEntity>(\n entities: T[],\n namespace?: string\n ): Promise<T[]> {\n return Promise.all(entities.map(e => this.save(e, namespace)));\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)) count++;\n }\n return count;\n },\n\n async listNamespaces(): Promise<string[]> {\n return Array.from(store.keys()).filter(ns => ns !== '_default');\n },\n\n async namespaceExists(namespace: string): Promise<boolean> {\n return store.has(namespace);\n },\n\n async listTypes(namespace?: string): Promise<string[]> {\n const ns = resolveNamespace(namespace);\n const nsStore = store.get(ns);\n return nsStore ? Array.from(nsStore.keys()) : [];\n },\n };\n};\n"],"names":["createMemoryProvider","options","registry","readonly","defaultNamespace","initialData","store","Map","getNamespaceStore","namespace","has","set","get","getTypeStore","type","nsStore","resolveNamespace","ns","entity","id","name","location","initialize","dispose","clear","isAvailable","getAll","Array","from","values","find","filter","results","types","isArray","concat","ids","length","e","includes","search","s","toLowerCase","offset","slice","limit","exists","count","save","ReadonlyStorageError","validationResult","validate","success","ValidationError","errors","now","Date","existing","saved","createdAt","updatedAt","delete","saveBatch","entities","Promise","all","map","deleteBatch","refs","ref","listNamespaces","keys","namespaceExists","listTypes"],"mappings":"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"}
1
+ {"version":3,"file":"memory.js","sources":["../../src/storage/memory.ts"],"sourcesContent":["import { StorageProvider, StorageProviderOptions, EntityFilter } from './interface';\nimport { BaseEntity } from '../schema/base';\nimport { ValidationError, ReadonlyStorageError } from './errors';\n\n/**\n * Create a deep clone of an entity to prevent external mutation of stored data.\n * Uses structured clone for proper handling of dates and nested objects.\n */\nconst cloneEntity = <T extends BaseEntity>(entity: T): T => {\n // structuredClone handles Date objects properly\n return structuredClone(entity);\n};\n\nexport interface MemoryProviderOptions extends StorageProviderOptions {\n /** Initial data to populate */\n initialData?: BaseEntity[];\n}\n\nexport const createMemoryProvider = (\n options: MemoryProviderOptions\n): StorageProvider => {\n const { registry, readonly = false, defaultNamespace, initialData = [] } = options;\n\n // Storage: namespace -> type -> id -> entity\n const store = new Map<string, Map<string, Map<string, BaseEntity>>>();\n\n const getNamespaceStore = (namespace: string): Map<string, Map<string, BaseEntity>> => {\n if (!store.has(namespace)) {\n store.set(namespace, new Map());\n }\n return store.get(namespace)!;\n };\n\n const getTypeStore = (\n namespace: string,\n type: string\n ): Map<string, BaseEntity> => {\n const nsStore = getNamespaceStore(namespace);\n if (!nsStore.has(type)) {\n nsStore.set(type, new Map());\n }\n return nsStore.get(type)!;\n };\n\n const resolveNamespace = (ns?: string): string => ns ?? defaultNamespace ?? '_default';\n\n // Initialize with any provided data\n for (const entity of initialData) {\n const ns = resolveNamespace(entity.namespace);\n getTypeStore(ns, entity.type).set(entity.id, entity);\n }\n\n return {\n name: 'memory',\n location: 'in-memory',\n registry,\n\n async initialize() { },\n\n async dispose() {\n store.clear();\n },\n\n async isAvailable() {\n return true;\n },\n\n async get<T extends BaseEntity>(\n type: string,\n id: string,\n namespace?: string\n ): Promise<T | undefined> {\n const ns = resolveNamespace(namespace);\n const entity = getTypeStore(ns, type).get(id) as T | undefined;\n // Return a defensive copy to prevent external mutation of stored data\n return entity ? cloneEntity(entity) : undefined;\n },\n\n async getAll<T extends BaseEntity>(\n type: string,\n namespace?: string\n ): Promise<T[]> {\n const ns = resolveNamespace(namespace);\n // Return defensive copies to prevent external mutation\n return Array.from(getTypeStore(ns, type).values()).map(e => cloneEntity(e as T));\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 ns = resolveNamespace(filter.namespace);\n\n for (const type of types) {\n results = results.concat(await this.getAll<T>(type, ns));\n }\n\n if (filter.ids?.length) {\n results = results.filter(e => filter.ids!.includes(e.id));\n }\n\n if (filter.search) {\n const s = filter.search.toLowerCase();\n results = results.filter(e => e.name.toLowerCase().includes(s));\n }\n\n if (filter.offset) results = results.slice(filter.offset);\n if (filter.limit) results = results.slice(0, filter.limit);\n\n return results;\n },\n\n async exists(type: string, id: string, namespace?: string): Promise<boolean> {\n const ns = resolveNamespace(namespace);\n return getTypeStore(ns, type).has(id);\n },\n\n async count(filter: EntityFilter): Promise<number> {\n return (await this.find(filter)).length;\n },\n\n async save<T extends BaseEntity>(entity: T, namespace?: string): Promise<T> {\n if (readonly) {\n throw new ReadonlyStorageError();\n }\n\n const validationResult = registry.validate(entity);\n if (!validationResult.success) {\n throw new ValidationError(\n 'Validation failed',\n validationResult.errors || []\n );\n }\n\n const ns = resolveNamespace(namespace);\n const now = new Date();\n const existing = getTypeStore(ns, entity.type).get(entity.id);\n\n const saved = {\n ...entity,\n namespace: ns,\n createdAt: existing?.createdAt || now,\n updatedAt: now,\n } as T;\n\n // Store a cloned copy to prevent external mutation from affecting stored data\n getTypeStore(ns, entity.type).set(entity.id, cloneEntity(saved));\n // Return a clone so caller can't mutate stored data through returned reference\n return cloneEntity(saved);\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 = resolveNamespace(namespace);\n return getTypeStore(ns, type).delete(id);\n },\n\n async saveBatch<T extends BaseEntity>(\n entities: T[],\n namespace?: string\n ): Promise<T[]> {\n return Promise.all(entities.map(e => this.save(e, namespace)));\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)) count++;\n }\n return count;\n },\n\n async listNamespaces(): Promise<string[]> {\n return Array.from(store.keys()).filter(ns => ns !== '_default');\n },\n\n async namespaceExists(namespace: string): Promise<boolean> {\n return store.has(namespace);\n },\n\n async listTypes(namespace?: string): Promise<string[]> {\n const ns = resolveNamespace(namespace);\n const nsStore = store.get(ns);\n return nsStore ? Array.from(nsStore.keys()) : [];\n },\n };\n};\n"],"names":["cloneEntity","entity","structuredClone","createMemoryProvider","options","registry","readonly","defaultNamespace","initialData","store","Map","getNamespaceStore","namespace","has","set","get","getTypeStore","type","nsStore","resolveNamespace","ns","id","name","location","initialize","dispose","clear","isAvailable","undefined","getAll","Array","from","values","map","e","find","filter","results","types","isArray","concat","ids","length","includes","search","s","toLowerCase","offset","slice","limit","exists","count","save","ReadonlyStorageError","validationResult","validate","success","ValidationError","errors","now","Date","existing","saved","createdAt","updatedAt","delete","saveBatch","entities","Promise","all","deleteBatch","refs","ref","listNamespaces","keys","namespaceExists","listTypes"],"mappings":"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"}
@@ -30,6 +30,7 @@
30
30
  type: 'storage:disposed',
31
31
  timestamp: new Date()
32
32
  });
33
+ handlers.clear(); // Clear all handlers to prevent memory leaks
33
34
  await provider.dispose();
34
35
  },
35
36
  async save (entity, namespace) {
@@ -1 +1 @@
1
- {"version":3,"file":"observable.js","sources":["../../src/storage/observable.ts"],"sourcesContent":["import { BaseEntity } from '../schema/base';\nimport { StorageProvider } from './interface';\nimport {\n StorageEventHandler,\n AnyStorageEvent,\n ObservableStorageProvider,\n} from './events';\n\n/**\n * Wrap any StorageProvider to make it observable.\n */\nexport const createObservableProvider = (\n provider: StorageProvider\n): ObservableStorageProvider => {\n const handlers = new Set<StorageEventHandler>();\n\n const emit = (event: AnyStorageEvent): void => {\n handlers.forEach(handler => {\n try {\n handler(event);\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error('Storage event handler error:', error);\n }\n });\n };\n\n return {\n ...provider,\n\n subscribe(handler: StorageEventHandler): () => void {\n handlers.add(handler);\n return () => handlers.delete(handler);\n },\n\n async initialize(): Promise<void> {\n await provider.initialize();\n emit({ type: 'storage:initialized', timestamp: new Date() });\n },\n\n async dispose(): Promise<void> {\n emit({ type: 'storage:disposed', timestamp: new Date() });\n await provider.dispose();\n },\n\n async save<T extends BaseEntity>(entity: T, namespace?: string): Promise<T> {\n const existing = await provider.get(entity.type, entity.id, namespace);\n const saved = await provider.save(entity, namespace);\n\n if (existing) {\n emit({\n type: 'entity:updated',\n timestamp: new Date(),\n namespace,\n entityType: entity.type,\n entityId: entity.id,\n entity: saved,\n previousEntity: existing,\n });\n } else {\n emit({\n type: 'entity:created',\n timestamp: new Date(),\n namespace,\n entityType: entity.type,\n entityId: entity.id,\n entity: saved,\n });\n }\n\n return saved;\n },\n\n async delete(type: string, id: string, namespace?: string): Promise<boolean> {\n const deleted = await provider.delete(type, id, namespace);\n\n if (deleted) {\n emit({\n type: 'entity:deleted',\n timestamp: new Date(),\n namespace,\n entityType: type,\n entityId: id,\n });\n }\n\n return deleted;\n },\n\n async saveBatch<T extends BaseEntity>(entities: T[], namespace?: string): Promise<T[]> {\n const saved = await provider.saveBatch(entities, namespace);\n\n emit({\n type: 'batch:saved',\n timestamp: new Date(),\n namespace,\n entities: saved,\n });\n\n return saved;\n },\n\n async deleteBatch(\n refs: Array<{ type: string; id: string }>,\n namespace?: string\n ): Promise<number> {\n const count = await provider.deleteBatch(refs, namespace);\n\n emit({\n type: 'batch:deleted',\n timestamp: new Date(),\n namespace,\n refs,\n deletedCount: count,\n });\n\n return count;\n },\n };\n};\n"],"names":["createObservableProvider","provider","handlers","Set","emit","event","forEach","handler","error","console","subscribe","add","delete","initialize","type","timestamp","Date","dispose","save","entity","namespace","existing","get","id","saved","entityType","entityId","previousEntity","deleted","saveBatch","entities","deleteBatch","refs","count","deletedCount"],"mappings":"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"}
1
+ {"version":3,"file":"observable.js","sources":["../../src/storage/observable.ts"],"sourcesContent":["import { BaseEntity } from '../schema/base';\nimport { StorageProvider } from './interface';\nimport {\n StorageEventHandler,\n AnyStorageEvent,\n ObservableStorageProvider,\n} from './events';\n\n/**\n * Wrap any StorageProvider to make it observable.\n */\nexport const createObservableProvider = (\n provider: StorageProvider\n): ObservableStorageProvider => {\n const handlers = new Set<StorageEventHandler>();\n\n const emit = (event: AnyStorageEvent): void => {\n handlers.forEach(handler => {\n try {\n handler(event);\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error('Storage event handler error:', error);\n }\n });\n };\n\n return {\n ...provider,\n\n subscribe(handler: StorageEventHandler): () => void {\n handlers.add(handler);\n return () => handlers.delete(handler);\n },\n\n async initialize(): Promise<void> {\n await provider.initialize();\n emit({ type: 'storage:initialized', timestamp: new Date() });\n },\n\n async dispose(): Promise<void> {\n emit({ type: 'storage:disposed', timestamp: new Date() });\n handlers.clear(); // Clear all handlers to prevent memory leaks\n await provider.dispose();\n },\n\n async save<T extends BaseEntity>(entity: T, namespace?: string): Promise<T> {\n const existing = await provider.get(entity.type, entity.id, namespace);\n const saved = await provider.save(entity, namespace);\n\n if (existing) {\n emit({\n type: 'entity:updated',\n timestamp: new Date(),\n namespace,\n entityType: entity.type,\n entityId: entity.id,\n entity: saved,\n previousEntity: existing,\n });\n } else {\n emit({\n type: 'entity:created',\n timestamp: new Date(),\n namespace,\n entityType: entity.type,\n entityId: entity.id,\n entity: saved,\n });\n }\n\n return saved;\n },\n\n async delete(type: string, id: string, namespace?: string): Promise<boolean> {\n const deleted = await provider.delete(type, id, namespace);\n\n if (deleted) {\n emit({\n type: 'entity:deleted',\n timestamp: new Date(),\n namespace,\n entityType: type,\n entityId: id,\n });\n }\n\n return deleted;\n },\n\n async saveBatch<T extends BaseEntity>(entities: T[], namespace?: string): Promise<T[]> {\n const saved = await provider.saveBatch(entities, namespace);\n\n emit({\n type: 'batch:saved',\n timestamp: new Date(),\n namespace,\n entities: saved,\n });\n\n return saved;\n },\n\n async deleteBatch(\n refs: Array<{ type: string; id: string }>,\n namespace?: string\n ): Promise<number> {\n const count = await provider.deleteBatch(refs, namespace);\n\n emit({\n type: 'batch:deleted',\n timestamp: new Date(),\n namespace,\n refs,\n deletedCount: count,\n });\n\n return count;\n },\n };\n};\n"],"names":["createObservableProvider","provider","handlers","Set","emit","event","forEach","handler","error","console","subscribe","add","delete","initialize","type","timestamp","Date","dispose","clear","save","entity","namespace","existing","get","id","saved","entityType","entityId","previousEntity","deleted","saveBatch","entities","deleteBatch","refs","count","deletedCount"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@utilarium/overcontext",
3
- "version": "0.0.4-dev.0",
3
+ "version": "0.0.4",
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",