@utilarium/overcontext 0.0.4-dev.0 → 0.0.5-dev.0
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/dist/api/query-builder.d.ts +3 -0
- package/dist/api/query-builder.js +11 -4
- package/dist/api/query-builder.js.map +1 -1
- package/dist/api/search.js +33 -3
- package/dist/api/search.js.map +1 -1
- package/dist/discovery/hierarchical-provider.js +10 -1
- package/dist/discovery/hierarchical-provider.js.map +1 -1
- package/dist/discovery/walker.js +14 -0
- package/dist/discovery/walker.js.map +1 -1
- package/dist/index.cjs +173 -20
- package/dist/index.cjs.map +1 -1
- package/dist/schema/base.js +3 -1
- package/dist/schema/base.js.map +1 -1
- package/dist/storage/filesystem.js +87 -7
- package/dist/storage/filesystem.js.map +1 -1
- package/dist/storage/memory.js +16 -4
- package/dist/storage/memory.js.map +1 -1
- package/dist/storage/observable.js +1 -0
- package/dist/storage/observable.js.map +1 -1
- package/package.json +1 -1
package/dist/schema/base.js
CHANGED
|
@@ -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()
|
package/dist/schema/base.js.map
CHANGED
|
@@ -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,
|
|
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
|
-
|
|
16
|
-
|
|
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
|
-
|
|
70
|
+
// Verify the path stays within basePath
|
|
71
|
+
verifyPathWithinBase(dir);
|
|
72
|
+
return dir;
|
|
19
73
|
};
|
|
20
74
|
const getEntityPath = (type, id, namespace)=>{
|
|
21
|
-
|
|
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
|
-
...
|
|
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
|
-
|
|
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
|
-
|
|
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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"}
|
package/dist/storage/memory.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
94
|
-
|
|
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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"}
|
|
@@ -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":"AAQA;;IAGO,MAAMA,wBAAAA,GAA2B,CACpCC,QAAAA,GAAAA;AAEA,IAAA,MAAMC,WAAW,IAAIC,GAAAA,EAAAA;AAErB,IAAA,MAAMC,OAAO,CAACC,KAAAA,GAAAA;QACVH,QAAAA,CAASI,OAAO,CAACC,CAAAA,OAAAA,GAAAA;YACb,IAAI;gBACAA,OAAAA,CAAQF,KAAAA,CAAAA;AACZ,YAAA,CAAA,CAAE,OAAOG,KAAAA,EAAO;;gBAEZC,OAAAA,CAAQD,KAAK,CAAC,8BAAA,EAAgCA,KAAAA,CAAAA;AAClD,YAAA;AACJ,QAAA,CAAA,CAAA;AACJ,IAAA,CAAA;IAEA,OAAO;AACH,QAAA,GAAGP,QAAQ;AAEXS,QAAAA,SAAAA,CAAAA,CAAUH,OAA4B,EAAA;AAClCL,YAAAA,QAAAA,CAASS,GAAG,CAACJ,OAAAA,CAAAA;YACb,OAAO,IAAML,QAAAA,CAASU,MAAM,CAACL,OAAAA,CAAAA;AACjC,QAAA,CAAA;QAEA,MAAMM,UAAAA,CAAAA,GAAAA;AACF,YAAA,MAAMZ,SAASY,UAAU,EAAA;YACzBT,IAAAA,CAAK;gBAAEU,IAAAA,EAAM,qBAAA;AAAuBC,gBAAAA,SAAAA,EAAW,IAAIC,IAAAA;AAAO,aAAA,CAAA;AAC9D,QAAA,CAAA;QAEA,MAAMC,OAAAA,CAAAA,GAAAA;YACFb,IAAAA,CAAK;gBAAEU,IAAAA,EAAM,kBAAA;AAAoBC,gBAAAA,SAAAA,EAAW,IAAIC,IAAAA;AAAO,aAAA,CAAA;
|
|
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.
|
|
3
|
+
"version": "0.0.5-dev.0",
|
|
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",
|