@utilarium/overcontext 0.0.4-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/LICENSE +65 -0
- package/README.md +286 -0
- package/dist/api/builder.d.ts +26 -0
- package/dist/api/builder.js +24 -0
- package/dist/api/builder.js.map +1 -0
- package/dist/api/context.d.ts +90 -0
- package/dist/api/context.js +94 -0
- package/dist/api/context.js.map +1 -0
- package/dist/api/index.d.ts +6 -0
- package/dist/api/query-builder.d.ts +51 -0
- package/dist/api/query-builder.js +95 -0
- package/dist/api/query-builder.js.map +1 -0
- package/dist/api/query.d.ts +32 -0
- package/dist/api/search.d.ts +20 -0
- package/dist/api/search.js +112 -0
- package/dist/api/search.js.map +1 -0
- package/dist/api/slug.d.ts +10 -0
- package/dist/api/slug.js +55 -0
- package/dist/api/slug.js.map +1 -0
- package/dist/cli/builder.d.ts +74 -0
- package/dist/cli/builder.js +42 -0
- package/dist/cli/builder.js.map +1 -0
- package/dist/cli/commands.d.ts +53 -0
- package/dist/cli/commands.js +57 -0
- package/dist/cli/commands.js.map +1 -0
- package/dist/cli/formatters.d.ts +15 -0
- package/dist/cli/formatters.js +50 -0
- package/dist/cli/formatters.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/discovery/context-root.d.ts +31 -0
- package/dist/discovery/context-root.js +48 -0
- package/dist/discovery/context-root.js.map +1 -0
- package/dist/discovery/hierarchical-provider.d.ts +13 -0
- package/dist/discovery/hierarchical-provider.js +102 -0
- package/dist/discovery/hierarchical-provider.js.map +1 -0
- package/dist/discovery/index.d.ts +18 -0
- package/dist/discovery/index.js +47 -0
- package/dist/discovery/index.js.map +1 -0
- package/dist/discovery/walker.d.ts +36 -0
- package/dist/discovery/walker.js +87 -0
- package/dist/discovery/walker.js.map +1 -0
- package/dist/index.cjs +1763 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/namespace/index.d.ts +3 -0
- package/dist/namespace/multi-context.d.ts +40 -0
- package/dist/namespace/multi-context.js +72 -0
- package/dist/namespace/multi-context.js.map +1 -0
- package/dist/namespace/resolver.d.ts +33 -0
- package/dist/namespace/resolver.js +85 -0
- package/dist/namespace/resolver.js.map +1 -0
- package/dist/namespace/types.d.ts +41 -0
- package/dist/overcontext.d.ts +7 -0
- package/dist/schema/base.d.ts +29 -0
- package/dist/schema/base.js +24 -0
- package/dist/schema/base.js.map +1 -0
- package/dist/schema/builder.d.ts +28 -0
- package/dist/schema/builder.js +39 -0
- package/dist/schema/builder.js.map +1 -0
- package/dist/schema/index.d.ts +5 -0
- package/dist/schema/inference.d.ts +49 -0
- package/dist/schema/inference.js +15 -0
- package/dist/schema/inference.js.map +1 -0
- package/dist/schema/registry.d.ts +74 -0
- package/dist/schema/registry.js +117 -0
- package/dist/schema/registry.js.map +1 -0
- package/dist/schema/validation.d.ts +26 -0
- package/dist/schema/validation.js +51 -0
- package/dist/schema/validation.js.map +1 -0
- package/dist/storage/errors.d.ts +35 -0
- package/dist/storage/errors.js +58 -0
- package/dist/storage/errors.js.map +1 -0
- package/dist/storage/events.d.ts +50 -0
- package/dist/storage/filesystem.d.ts +10 -0
- package/dist/storage/filesystem.js +284 -0
- package/dist/storage/filesystem.js.map +1 -0
- package/dist/storage/index.d.ts +6 -0
- package/dist/storage/interface.d.ts +109 -0
- package/dist/storage/memory.d.ts +7 -0
- package/dist/storage/memory.js +128 -0
- package/dist/storage/memory.js.map +1 -0
- package/dist/storage/observable.d.ts +6 -0
- package/dist/storage/observable.js +98 -0
- package/dist/storage/observable.js.map +1 -0
- package/package.json +85 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.js","sources":["../../src/schema/validation.ts"],"sourcesContent":["import { z, ZodError } from 'zod';\nimport { BaseEntity, BaseEntitySchema } from './base';\n\nexport interface ValidationResult<T> {\n success: boolean;\n data?: T;\n errors?: Array<{ path: string; message: string }>;\n}\n\n/**\n * Validate that an object satisfies at least the base entity contract.\n */\nexport const validateBaseEntity = (data: unknown): ValidationResult<BaseEntity> => {\n const result = BaseEntitySchema.safeParse(data);\n\n if (result.success) {\n return { success: true, data: result.data };\n }\n\n return {\n success: false,\n errors: result.error.issues.map(e => ({\n path: e.path.join('.'),\n message: e.message,\n })),\n };\n};\n\n/**\n * Validate data against a specific schema.\n */\nexport const validateEntity = <T extends BaseEntity>(\n schema: z.ZodType<T>,\n data: unknown\n): ValidationResult<T> => {\n const result = schema.safeParse(data);\n\n if (result.success) {\n return { success: true, data: result.data };\n }\n\n return {\n success: false,\n errors: result.error.issues.map(e => ({\n path: e.path.join('.'),\n message: e.message,\n })),\n };\n};\n\n/**\n * Check if data extends the base entity (has id, name, type).\n */\nexport const isBaseEntity = (data: unknown): data is BaseEntity => {\n return validateBaseEntity(data).success;\n};\n\n/**\n * Format Zod errors into a readable message.\n */\nexport const formatValidationErrors = (errors: ZodError): string => {\n return errors.issues\n .map(e => `${e.path.join('.')}: ${e.message}`)\n .join('; ');\n};\n"],"names":["validateBaseEntity","data","result","BaseEntitySchema","safeParse","success","errors","error","issues","map","e","path","join","message","validateEntity","schema","isBaseEntity","formatValidationErrors"],"mappings":";;AASA;;IAGO,MAAMA,kBAAAA,GAAqB,CAACC,IAAAA,GAAAA;IAC/B,MAAMC,MAAAA,GAASC,gBAAAA,CAAiBC,SAAS,CAACH,IAAAA,CAAAA;IAE1C,IAAIC,MAAAA,CAAOG,OAAO,EAAE;QAChB,OAAO;YAAEA,OAAAA,EAAS,IAAA;AAAMJ,YAAAA,IAAAA,EAAMC,OAAOD;AAAK,SAAA;AAC9C,IAAA;IAEA,OAAO;QACHI,OAAAA,EAAS,KAAA;QACTC,MAAAA,EAAQJ,MAAAA,CAAOK,KAAK,CAACC,MAAM,CAACC,GAAG,CAACC,CAAAA,CAAAA,IAAM;AAClCC,gBAAAA,IAAAA,EAAMD,CAAAA,CAAEC,IAAI,CAACC,IAAI,CAAC,GAAA,CAAA;AAClBC,gBAAAA,OAAAA,EAASH,EAAEG;aACf,CAAA;AACJ,KAAA;AACJ;AAEA;;AAEC,IACM,MAAMC,cAAAA,GAAiB,CAC1BC,MAAAA,EACAd,IAAAA,GAAAA;IAEA,MAAMC,MAAAA,GAASa,MAAAA,CAAOX,SAAS,CAACH,IAAAA,CAAAA;IAEhC,IAAIC,MAAAA,CAAOG,OAAO,EAAE;QAChB,OAAO;YAAEA,OAAAA,EAAS,IAAA;AAAMJ,YAAAA,IAAAA,EAAMC,OAAOD;AAAK,SAAA;AAC9C,IAAA;IAEA,OAAO;QACHI,OAAAA,EAAS,KAAA;QACTC,MAAAA,EAAQJ,MAAAA,CAAOK,KAAK,CAACC,MAAM,CAACC,GAAG,CAACC,CAAAA,CAAAA,IAAM;AAClCC,gBAAAA,IAAAA,EAAMD,CAAAA,CAAEC,IAAI,CAACC,IAAI,CAAC,GAAA,CAAA;AAClBC,gBAAAA,OAAAA,EAASH,EAAEG;aACf,CAAA;AACJ,KAAA;AACJ;AAEA;;IAGO,MAAMG,YAAAA,GAAe,CAACf,IAAAA,GAAAA;IACzB,OAAOD,kBAAAA,CAAmBC,MAAMI,OAAO;AAC3C;AAEA;;IAGO,MAAMY,sBAAAA,GAAyB,CAACX,MAAAA,GAAAA;IACnC,OAAOA,MAAAA,CAAOE,MAAM,CACfC,GAAG,CAACC,CAAAA,CAAAA,GAAK,GAAGA,CAAAA,CAAEC,IAAI,CAACC,IAAI,CAAC,KAAK,EAAE,EAAEF,EAAEG,OAAO,CAAA,CAAE,CAAA,CAC5CD,IAAI,CAAC,IAAA,CAAA;AACd;;;;"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export declare class StorageError extends Error {
|
|
2
|
+
readonly code: string;
|
|
3
|
+
readonly cause?: Error | undefined;
|
|
4
|
+
constructor(message: string, code: string, cause?: Error | undefined);
|
|
5
|
+
}
|
|
6
|
+
export declare class EntityNotFoundError extends StorageError {
|
|
7
|
+
readonly entityType: string;
|
|
8
|
+
readonly entityId: string;
|
|
9
|
+
readonly namespace?: string | undefined;
|
|
10
|
+
constructor(entityType: string, entityId: string, namespace?: string | undefined);
|
|
11
|
+
}
|
|
12
|
+
export declare class SchemaNotRegisteredError extends StorageError {
|
|
13
|
+
readonly entityType: string;
|
|
14
|
+
constructor(entityType: string);
|
|
15
|
+
}
|
|
16
|
+
export declare class ValidationError extends StorageError {
|
|
17
|
+
readonly validationErrors: Array<{
|
|
18
|
+
path: string;
|
|
19
|
+
message: string;
|
|
20
|
+
}>;
|
|
21
|
+
constructor(message: string, validationErrors: Array<{
|
|
22
|
+
path: string;
|
|
23
|
+
message: string;
|
|
24
|
+
}>);
|
|
25
|
+
}
|
|
26
|
+
export declare class StorageAccessError extends StorageError {
|
|
27
|
+
constructor(message: string, cause?: Error);
|
|
28
|
+
}
|
|
29
|
+
export declare class ReadonlyStorageError extends StorageError {
|
|
30
|
+
constructor();
|
|
31
|
+
}
|
|
32
|
+
export declare class NamespaceNotFoundError extends StorageError {
|
|
33
|
+
readonly namespace: string;
|
|
34
|
+
constructor(namespace: string);
|
|
35
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
function _define_property(obj, key, value) {
|
|
2
|
+
if (key in obj) {
|
|
3
|
+
Object.defineProperty(obj, key, {
|
|
4
|
+
value: value,
|
|
5
|
+
enumerable: true,
|
|
6
|
+
configurable: true,
|
|
7
|
+
writable: true
|
|
8
|
+
});
|
|
9
|
+
} else {
|
|
10
|
+
obj[key] = value;
|
|
11
|
+
}
|
|
12
|
+
return obj;
|
|
13
|
+
}
|
|
14
|
+
class StorageError extends Error {
|
|
15
|
+
constructor(message, code, cause){
|
|
16
|
+
super(message), _define_property(this, "code", void 0), _define_property(this, "cause", void 0), this.code = code, this.cause = cause;
|
|
17
|
+
this.name = 'StorageError';
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
class EntityNotFoundError extends StorageError {
|
|
21
|
+
constructor(entityType, entityId, namespace){
|
|
22
|
+
super(`Entity not found: ${entityType}/${entityId}${namespace ? ` in ${namespace}` : ''}`, 'ENTITY_NOT_FOUND'), _define_property(this, "entityType", void 0), _define_property(this, "entityId", void 0), _define_property(this, "namespace", void 0), this.entityType = entityType, this.entityId = entityId, this.namespace = namespace;
|
|
23
|
+
this.name = 'EntityNotFoundError';
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
class SchemaNotRegisteredError extends StorageError {
|
|
27
|
+
constructor(entityType){
|
|
28
|
+
super(`Schema not registered for type: ${entityType}`, 'SCHEMA_NOT_REGISTERED'), _define_property(this, "entityType", void 0), this.entityType = entityType;
|
|
29
|
+
this.name = 'SchemaNotRegisteredError';
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
class ValidationError extends StorageError {
|
|
33
|
+
constructor(message, validationErrors){
|
|
34
|
+
super(message, 'VALIDATION_ERROR'), _define_property(this, "validationErrors", void 0), this.validationErrors = validationErrors;
|
|
35
|
+
this.name = 'ValidationError';
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
class StorageAccessError extends StorageError {
|
|
39
|
+
constructor(message, cause){
|
|
40
|
+
super(message, 'STORAGE_ACCESS_ERROR', cause);
|
|
41
|
+
this.name = 'StorageAccessError';
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
class ReadonlyStorageError extends StorageError {
|
|
45
|
+
constructor(){
|
|
46
|
+
super('Storage is readonly', 'READONLY_STORAGE');
|
|
47
|
+
this.name = 'ReadonlyStorageError';
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
class NamespaceNotFoundError extends StorageError {
|
|
51
|
+
constructor(namespace){
|
|
52
|
+
super(`Namespace not found: ${namespace}`, 'NAMESPACE_NOT_FOUND'), _define_property(this, "namespace", void 0), this.namespace = namespace;
|
|
53
|
+
this.name = 'NamespaceNotFoundError';
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export { EntityNotFoundError, NamespaceNotFoundError, ReadonlyStorageError, SchemaNotRegisteredError, StorageAccessError, StorageError, ValidationError };
|
|
58
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sources":["../../src/storage/errors.ts"],"sourcesContent":["export class StorageError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n public readonly cause?: Error\n ) {\n super(message);\n this.name = 'StorageError';\n }\n}\n\nexport class EntityNotFoundError extends StorageError {\n constructor(\n public readonly entityType: string,\n public readonly entityId: string,\n public readonly namespace?: string\n ) {\n super(\n `Entity not found: ${entityType}/${entityId}${namespace ? ` in ${namespace}` : ''}`,\n 'ENTITY_NOT_FOUND'\n );\n this.name = 'EntityNotFoundError';\n }\n}\n\nexport class SchemaNotRegisteredError extends StorageError {\n constructor(public readonly entityType: string) {\n super(\n `Schema not registered for type: ${entityType}`,\n 'SCHEMA_NOT_REGISTERED'\n );\n this.name = 'SchemaNotRegisteredError';\n }\n}\n\nexport class ValidationError extends StorageError {\n constructor(\n message: string,\n public readonly validationErrors: Array<{ path: string; message: string }>\n ) {\n super(message, 'VALIDATION_ERROR');\n this.name = 'ValidationError';\n }\n}\n\nexport class StorageAccessError extends StorageError {\n constructor(message: string, cause?: Error) {\n super(message, 'STORAGE_ACCESS_ERROR', cause);\n this.name = 'StorageAccessError';\n }\n}\n\nexport class ReadonlyStorageError extends StorageError {\n constructor() {\n super('Storage is readonly', 'READONLY_STORAGE');\n this.name = 'ReadonlyStorageError';\n }\n}\n\nexport class NamespaceNotFoundError extends StorageError {\n constructor(public readonly namespace: string) {\n super(`Namespace not found: ${namespace}`, 'NAMESPACE_NOT_FOUND');\n this.name = 'NamespaceNotFoundError';\n }\n}\n"],"names":["StorageError","Error","message","code","cause","name","EntityNotFoundError","entityType","entityId","namespace","SchemaNotRegisteredError","ValidationError","validationErrors","StorageAccessError","ReadonlyStorageError","NamespaceNotFoundError"],"mappings":";;;;;;;;;;;;;AAAO,MAAMA,YAAAA,SAAqBC,KAAAA,CAAAA;AAC9B,IAAA,WAAA,CACIC,OAAe,EACCC,IAAY,EACZC,KAAa,CAC/B;AACE,QAAA,KAAK,CAACF,OAAAA,CAAAA,EAAAA,gBAAAA,CAAAA,IAAAA,EAAAA,MAAAA,EAAAA,MAAAA,CAAAA,EAAAA,gBAAAA,CAAAA,IAAAA,EAAAA,OAAAA,EAAAA,MAAAA,CAAAA,EAAAA,IAAAA,CAHUC,IAAAA,GAAAA,IAAAA,EAAAA,IAAAA,CACAC,KAAAA,GAAAA,KAAAA;QAGhB,IAAI,CAACC,IAAI,GAAG,cAAA;AAChB,IAAA;AACJ;AAEO,MAAMC,mBAAAA,SAA4BN,YAAAA,CAAAA;IACrC,WAAA,CACoBO,UAAkB,EAClBC,QAAgB,EAChBC,SAAkB,CACpC;QACE,KAAK,CACD,CAAC,kBAAkB,EAAEF,WAAW,CAAC,EAAEC,WAAWC,SAAAA,GAAY,CAAC,IAAI,EAAEA,SAAAA,CAAAA,CAAW,GAAG,EAAA,CAAA,CAAI,EACnF,iKANYF,UAAAA,GAAAA,UAAAA,EAAAA,IAAAA,CACAC,QAAAA,GAAAA,QAAAA,EAAAA,IAAAA,CACAC,SAAAA,GAAAA,SAAAA;QAMhB,IAAI,CAACJ,IAAI,GAAG,qBAAA;AAChB,IAAA;AACJ;AAEO,MAAMK,wBAAAA,SAAiCV,YAAAA,CAAAA;IAC1C,WAAA,CAA4BO,UAAkB,CAAE;AAC5C,QAAA,KAAK,CACD,CAAC,gCAAgC,EAAEA,UAAAA,CAAAA,CAAY,EAC/C,6EAHoBA,UAAAA,GAAAA,UAAAA;QAKxB,IAAI,CAACF,IAAI,GAAG,0BAAA;AAChB,IAAA;AACJ;AAEO,MAAMM,eAAAA,SAAwBX,YAAAA,CAAAA;AACjC,IAAA,WAAA,CACIE,OAAe,EACf,gBAA0E,CAC5E;QACE,KAAK,CAACA,OAAAA,EAAS,kBAAA,CAAA,EAAA,gBAAA,CAAA,IAAA,EAAA,kBAAA,EAAA,MAAA,CAAA,EAAA,IAAA,CAFCU,gBAAAA,GAAAA,gBAAAA;QAGhB,IAAI,CAACP,IAAI,GAAG,iBAAA;AAChB,IAAA;AACJ;AAEO,MAAMQ,kBAAAA,SAA2Bb,YAAAA,CAAAA;IACpC,WAAA,CAAYE,OAAe,EAAEE,KAAa,CAAE;QACxC,KAAK,CAACF,SAAS,sBAAA,EAAwBE,KAAAA,CAAAA;QACvC,IAAI,CAACC,IAAI,GAAG,oBAAA;AAChB,IAAA;AACJ;AAEO,MAAMS,oBAAAA,SAA6Bd,YAAAA,CAAAA;IACtC,WAAA,EAAc;AACV,QAAA,KAAK,CAAC,qBAAA,EAAuB,kBAAA,CAAA;QAC7B,IAAI,CAACK,IAAI,GAAG,sBAAA;AAChB,IAAA;AACJ;AAEO,MAAMU,sBAAAA,SAA+Bf,YAAAA,CAAAA;IACxC,WAAA,CAA4BS,SAAiB,CAAE;AAC3C,QAAA,KAAK,CAAC,CAAC,qBAAqB,EAAEA,SAAAA,CAAAA,CAAW,EAAE,0EADnBA,SAAAA,GAAAA,SAAAA;QAExB,IAAI,CAACJ,IAAI,GAAG,wBAAA;AAChB,IAAA;AACJ;;;;"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { BaseEntity } from '../schema/base';
|
|
2
|
+
import { StorageProvider } from './interface';
|
|
3
|
+
export type StorageEventType = 'entity:created' | 'entity:updated' | 'entity:deleted' | 'batch:saved' | 'batch:deleted' | 'storage:initialized' | 'storage:disposed';
|
|
4
|
+
export interface StorageEvent {
|
|
5
|
+
type: StorageEventType;
|
|
6
|
+
timestamp: Date;
|
|
7
|
+
namespace?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface EntityCreatedEvent extends StorageEvent {
|
|
10
|
+
type: 'entity:created';
|
|
11
|
+
entityType: string;
|
|
12
|
+
entityId: string;
|
|
13
|
+
entity: BaseEntity;
|
|
14
|
+
}
|
|
15
|
+
export interface EntityUpdatedEvent extends StorageEvent {
|
|
16
|
+
type: 'entity:updated';
|
|
17
|
+
entityType: string;
|
|
18
|
+
entityId: string;
|
|
19
|
+
entity: BaseEntity;
|
|
20
|
+
previousEntity?: BaseEntity;
|
|
21
|
+
}
|
|
22
|
+
export interface EntityDeletedEvent extends StorageEvent {
|
|
23
|
+
type: 'entity:deleted';
|
|
24
|
+
entityType: string;
|
|
25
|
+
entityId: string;
|
|
26
|
+
}
|
|
27
|
+
export interface BatchSavedEvent extends StorageEvent {
|
|
28
|
+
type: 'batch:saved';
|
|
29
|
+
entities: BaseEntity[];
|
|
30
|
+
}
|
|
31
|
+
export interface BatchDeletedEvent extends StorageEvent {
|
|
32
|
+
type: 'batch:deleted';
|
|
33
|
+
refs: Array<{
|
|
34
|
+
type: string;
|
|
35
|
+
id: string;
|
|
36
|
+
}>;
|
|
37
|
+
deletedCount: number;
|
|
38
|
+
}
|
|
39
|
+
export type AnyStorageEvent = EntityCreatedEvent | EntityUpdatedEvent | EntityDeletedEvent | BatchSavedEvent | BatchDeletedEvent | StorageEvent;
|
|
40
|
+
export type StorageEventHandler = (event: AnyStorageEvent) => void;
|
|
41
|
+
/**
|
|
42
|
+
* Observable storage provider with event subscription.
|
|
43
|
+
*/
|
|
44
|
+
export interface ObservableStorageProvider extends StorageProvider {
|
|
45
|
+
/**
|
|
46
|
+
* Subscribe to storage events.
|
|
47
|
+
* Returns unsubscribe function.
|
|
48
|
+
*/
|
|
49
|
+
subscribe(handler: StorageEventHandler): () => void;
|
|
50
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { StorageProvider, StorageProviderOptions } from './interface';
|
|
2
|
+
export interface FileSystemProviderOptions extends StorageProviderOptions {
|
|
3
|
+
/** Base path for context storage */
|
|
4
|
+
basePath: string;
|
|
5
|
+
/** Create directories if they don't exist */
|
|
6
|
+
createIfMissing?: boolean;
|
|
7
|
+
/** File extension to use (default: .yaml) */
|
|
8
|
+
extension?: '.yaml' | '.yml';
|
|
9
|
+
}
|
|
10
|
+
export declare const createFileSystemProvider: (options: FileSystemProviderOptions) => Promise<StorageProvider>;
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
import * as fs from 'node:fs/promises';
|
|
2
|
+
import { existsSync, statSync } from 'node:fs';
|
|
3
|
+
import * as path from 'node:path';
|
|
4
|
+
import * as yaml from 'js-yaml';
|
|
5
|
+
import { ReadonlyStorageError, SchemaNotRegisteredError, StorageAccessError, ValidationError } from './errors.js';
|
|
6
|
+
|
|
7
|
+
const createFileSystemProvider = async (options)=>{
|
|
8
|
+
const { basePath, registry, createIfMissing = true, extension = '.yaml', readonly = false, defaultNamespace } = options;
|
|
9
|
+
// --- Helper Functions ---
|
|
10
|
+
const getEntityDir = (type, namespace)=>{
|
|
11
|
+
const dirName = registry.getDirectoryName(type);
|
|
12
|
+
if (!dirName) {
|
|
13
|
+
throw new SchemaNotRegisteredError(type);
|
|
14
|
+
}
|
|
15
|
+
if (namespace) {
|
|
16
|
+
return path.join(basePath, namespace, dirName);
|
|
17
|
+
}
|
|
18
|
+
return path.join(basePath, dirName);
|
|
19
|
+
};
|
|
20
|
+
const getEntityPath = (type, id, namespace)=>{
|
|
21
|
+
return path.join(getEntityDir(type, namespace), `${id}${extension}`);
|
|
22
|
+
};
|
|
23
|
+
const ensureDir = async (dir)=>{
|
|
24
|
+
if (!existsSync(dir) && createIfMissing && !readonly) {
|
|
25
|
+
await fs.mkdir(dir, {
|
|
26
|
+
recursive: true
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
const readEntity = async (filePath, type)=>{
|
|
31
|
+
try {
|
|
32
|
+
const content = await fs.readFile(filePath, 'utf-8');
|
|
33
|
+
let parsed;
|
|
34
|
+
try {
|
|
35
|
+
parsed = yaml.load(content);
|
|
36
|
+
} catch (yamlError) {
|
|
37
|
+
// eslint-disable-next-line no-console
|
|
38
|
+
console.warn(`Invalid YAML at ${filePath}:`, yamlError);
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
if (!parsed || typeof parsed !== 'object') {
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
// Validate against registered schema
|
|
45
|
+
const result = registry.validateAs(type, {
|
|
46
|
+
...parsed,
|
|
47
|
+
source: filePath
|
|
48
|
+
});
|
|
49
|
+
if (!result.success) {
|
|
50
|
+
// eslint-disable-next-line no-console
|
|
51
|
+
console.warn(`Invalid entity at ${filePath}:`, result.errors);
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
return result.data;
|
|
55
|
+
} catch (error) {
|
|
56
|
+
if (error.code === 'ENOENT') {
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
throw new StorageAccessError(`Failed to read ${filePath}`, error);
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
const writeEntity = async (entity, namespace)=>{
|
|
63
|
+
if (readonly) {
|
|
64
|
+
throw new ReadonlyStorageError();
|
|
65
|
+
}
|
|
66
|
+
// Validate against schema
|
|
67
|
+
const validationResult = registry.validate(entity);
|
|
68
|
+
if (!validationResult.success) {
|
|
69
|
+
throw new ValidationError('Entity validation failed', validationResult.errors || []);
|
|
70
|
+
}
|
|
71
|
+
const dir = getEntityDir(entity.type, namespace);
|
|
72
|
+
await ensureDir(dir);
|
|
73
|
+
const filePath = getEntityPath(entity.type, entity.id, namespace);
|
|
74
|
+
// Remove framework-managed fields from saved YAML
|
|
75
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
76
|
+
const { type: _type, source: _source, ...entityToSave } = entity;
|
|
77
|
+
// Update metadata
|
|
78
|
+
const now = new Date();
|
|
79
|
+
const toSave = {
|
|
80
|
+
...entityToSave,
|
|
81
|
+
updatedAt: now,
|
|
82
|
+
createdAt: entityToSave.createdAt || now
|
|
83
|
+
};
|
|
84
|
+
const content = yaml.dump(toSave, {
|
|
85
|
+
lineWidth: -1,
|
|
86
|
+
sortKeys: false
|
|
87
|
+
});
|
|
88
|
+
await fs.writeFile(filePath, content, 'utf-8');
|
|
89
|
+
return {
|
|
90
|
+
...entity,
|
|
91
|
+
...toSave,
|
|
92
|
+
type: entity.type,
|
|
93
|
+
source: filePath
|
|
94
|
+
};
|
|
95
|
+
};
|
|
96
|
+
const listDirectoryTypes = async (basePath)=>{
|
|
97
|
+
const types = [];
|
|
98
|
+
try {
|
|
99
|
+
const entries = await fs.readdir(basePath, {
|
|
100
|
+
withFileTypes: true
|
|
101
|
+
});
|
|
102
|
+
for (const entry of entries){
|
|
103
|
+
if (entry.isDirectory()) {
|
|
104
|
+
const type = registry.getTypeFromDirectory(entry.name);
|
|
105
|
+
if (type) {
|
|
106
|
+
types.push(type);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
} catch {
|
|
111
|
+
// Directory doesn't exist
|
|
112
|
+
}
|
|
113
|
+
return types;
|
|
114
|
+
};
|
|
115
|
+
// --- StorageProvider Implementation ---
|
|
116
|
+
const provider = {
|
|
117
|
+
name: 'filesystem',
|
|
118
|
+
location: basePath,
|
|
119
|
+
registry,
|
|
120
|
+
async initialize () {
|
|
121
|
+
if (createIfMissing && !readonly) {
|
|
122
|
+
await ensureDir(basePath);
|
|
123
|
+
}
|
|
124
|
+
if (!existsSync(basePath)) {
|
|
125
|
+
throw new StorageAccessError(`Context path does not exist: ${basePath}`);
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
async dispose () {
|
|
129
|
+
// No cleanup needed for filesystem
|
|
130
|
+
},
|
|
131
|
+
async isAvailable () {
|
|
132
|
+
try {
|
|
133
|
+
const stat = statSync(basePath);
|
|
134
|
+
return stat.isDirectory();
|
|
135
|
+
} catch {
|
|
136
|
+
return false;
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
async get (type, id, namespace) {
|
|
140
|
+
const ns = namespace !== null && namespace !== void 0 ? namespace : defaultNamespace;
|
|
141
|
+
const filePath = getEntityPath(type, id, ns);
|
|
142
|
+
return readEntity(filePath, type);
|
|
143
|
+
},
|
|
144
|
+
async getAll (type, namespace) {
|
|
145
|
+
const ns = namespace !== null && namespace !== void 0 ? namespace : defaultNamespace;
|
|
146
|
+
let dir;
|
|
147
|
+
try {
|
|
148
|
+
dir = getEntityDir(type, ns);
|
|
149
|
+
} catch (error) {
|
|
150
|
+
if (error instanceof SchemaNotRegisteredError) {
|
|
151
|
+
return [];
|
|
152
|
+
}
|
|
153
|
+
throw error;
|
|
154
|
+
}
|
|
155
|
+
if (!existsSync(dir)) {
|
|
156
|
+
return [];
|
|
157
|
+
}
|
|
158
|
+
const files = await fs.readdir(dir);
|
|
159
|
+
const entities = [];
|
|
160
|
+
for (const file of files){
|
|
161
|
+
if (!file.endsWith('.yaml') && !file.endsWith('.yml')) {
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
const entity = await readEntity(path.join(dir, file), type);
|
|
165
|
+
if (entity) {
|
|
166
|
+
entities.push(entity);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return entities;
|
|
170
|
+
},
|
|
171
|
+
async find (filter) {
|
|
172
|
+
var _filter_namespace;
|
|
173
|
+
var _filter_ids;
|
|
174
|
+
let results = [];
|
|
175
|
+
const types = filter.type ? Array.isArray(filter.type) ? filter.type : [
|
|
176
|
+
filter.type
|
|
177
|
+
] : registry.types();
|
|
178
|
+
const namespace = (_filter_namespace = filter.namespace) !== null && _filter_namespace !== void 0 ? _filter_namespace : defaultNamespace;
|
|
179
|
+
for (const type of types){
|
|
180
|
+
const entities = await this.getAll(type, namespace);
|
|
181
|
+
results = results.concat(entities);
|
|
182
|
+
}
|
|
183
|
+
// Apply ID filter
|
|
184
|
+
if ((_filter_ids = filter.ids) === null || _filter_ids === void 0 ? void 0 : _filter_ids.length) {
|
|
185
|
+
results = results.filter((e)=>filter.ids.includes(e.id));
|
|
186
|
+
}
|
|
187
|
+
// Apply search filter
|
|
188
|
+
if (filter.search) {
|
|
189
|
+
const searchLower = filter.search.toLowerCase();
|
|
190
|
+
results = results.filter((e)=>e.name.toLowerCase().includes(searchLower));
|
|
191
|
+
}
|
|
192
|
+
// Apply pagination
|
|
193
|
+
if (filter.offset) {
|
|
194
|
+
results = results.slice(filter.offset);
|
|
195
|
+
}
|
|
196
|
+
if (filter.limit) {
|
|
197
|
+
results = results.slice(0, filter.limit);
|
|
198
|
+
}
|
|
199
|
+
return results;
|
|
200
|
+
},
|
|
201
|
+
async exists (type, id, namespace) {
|
|
202
|
+
const ns = namespace !== null && namespace !== void 0 ? namespace : defaultNamespace;
|
|
203
|
+
try {
|
|
204
|
+
const filePath = getEntityPath(type, id, ns);
|
|
205
|
+
return existsSync(filePath);
|
|
206
|
+
} catch {
|
|
207
|
+
return false;
|
|
208
|
+
}
|
|
209
|
+
},
|
|
210
|
+
async count (filter) {
|
|
211
|
+
const results = await this.find(filter);
|
|
212
|
+
return results.length;
|
|
213
|
+
},
|
|
214
|
+
async save (entity, namespace) {
|
|
215
|
+
const ns = namespace !== null && namespace !== void 0 ? namespace : defaultNamespace;
|
|
216
|
+
return writeEntity(entity, ns);
|
|
217
|
+
},
|
|
218
|
+
async delete (type, id, namespace) {
|
|
219
|
+
if (readonly) {
|
|
220
|
+
throw new ReadonlyStorageError();
|
|
221
|
+
}
|
|
222
|
+
const ns = namespace !== null && namespace !== void 0 ? namespace : defaultNamespace;
|
|
223
|
+
try {
|
|
224
|
+
const filePath = getEntityPath(type, id, ns);
|
|
225
|
+
await fs.unlink(filePath);
|
|
226
|
+
return true;
|
|
227
|
+
} catch (error) {
|
|
228
|
+
if (error.code === 'ENOENT') {
|
|
229
|
+
return false;
|
|
230
|
+
}
|
|
231
|
+
throw error;
|
|
232
|
+
}
|
|
233
|
+
},
|
|
234
|
+
async saveBatch (entities, namespace) {
|
|
235
|
+
const saved = [];
|
|
236
|
+
for (const entity of entities){
|
|
237
|
+
saved.push(await this.save(entity, namespace));
|
|
238
|
+
}
|
|
239
|
+
return saved;
|
|
240
|
+
},
|
|
241
|
+
async deleteBatch (refs, namespace) {
|
|
242
|
+
let count = 0;
|
|
243
|
+
for (const ref of refs){
|
|
244
|
+
if (await this.delete(ref.type, ref.id, namespace)) {
|
|
245
|
+
count++;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
return count;
|
|
249
|
+
},
|
|
250
|
+
async listNamespaces () {
|
|
251
|
+
const namespaces = [];
|
|
252
|
+
if (!existsSync(basePath)) {
|
|
253
|
+
return namespaces;
|
|
254
|
+
}
|
|
255
|
+
const entries = await fs.readdir(basePath, {
|
|
256
|
+
withFileTypes: true
|
|
257
|
+
});
|
|
258
|
+
for (const entry of entries){
|
|
259
|
+
if (!entry.isDirectory()) continue;
|
|
260
|
+
// Check if it's a namespace (contains entity type directories)
|
|
261
|
+
// vs being an entity type directory itself
|
|
262
|
+
const subPath = path.join(basePath, entry.name);
|
|
263
|
+
const subTypes = await listDirectoryTypes(subPath);
|
|
264
|
+
if (subTypes.length > 0) {
|
|
265
|
+
namespaces.push(entry.name);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
return namespaces;
|
|
269
|
+
},
|
|
270
|
+
async namespaceExists (namespace) {
|
|
271
|
+
const namespacePath = path.join(basePath, namespace);
|
|
272
|
+
return existsSync(namespacePath);
|
|
273
|
+
},
|
|
274
|
+
async listTypes (namespace) {
|
|
275
|
+
const ns = namespace !== null && namespace !== void 0 ? namespace : defaultNamespace;
|
|
276
|
+
const searchPath = ns ? path.join(basePath, ns) : basePath;
|
|
277
|
+
return listDirectoryTypes(searchPath);
|
|
278
|
+
}
|
|
279
|
+
};
|
|
280
|
+
return provider;
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
export { createFileSystemProvider };
|
|
284
|
+
//# sourceMappingURL=filesystem.js.map
|
|
@@ -0,0 +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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"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { BaseEntity } from '../schema/base';
|
|
2
|
+
import { SchemaRegistry } from '../schema/registry';
|
|
3
|
+
/**
|
|
4
|
+
* Filter options for querying entities.
|
|
5
|
+
*/
|
|
6
|
+
export interface EntityFilter {
|
|
7
|
+
/** Filter by entity type(s) */
|
|
8
|
+
type?: string | string[];
|
|
9
|
+
/** Filter by namespace */
|
|
10
|
+
namespace?: string;
|
|
11
|
+
/** Filter by specific IDs */
|
|
12
|
+
ids?: string[];
|
|
13
|
+
/** Text search across name and searchable fields */
|
|
14
|
+
search?: string;
|
|
15
|
+
/** Maximum results to return */
|
|
16
|
+
limit?: number;
|
|
17
|
+
/** Offset for pagination */
|
|
18
|
+
offset?: number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Options for creating a storage provider.
|
|
22
|
+
*/
|
|
23
|
+
export interface StorageProviderOptions {
|
|
24
|
+
/** Schema registry for validation */
|
|
25
|
+
registry: SchemaRegistry;
|
|
26
|
+
/** Default namespace for operations */
|
|
27
|
+
defaultNamespace?: string;
|
|
28
|
+
/** Whether to prevent writes */
|
|
29
|
+
readonly?: boolean;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Generic storage provider interface.
|
|
33
|
+
* Implementations work with any entity type via the schema registry.
|
|
34
|
+
*/
|
|
35
|
+
export interface StorageProvider {
|
|
36
|
+
/**
|
|
37
|
+
* Initialize the storage provider.
|
|
38
|
+
*/
|
|
39
|
+
initialize(): Promise<void>;
|
|
40
|
+
/**
|
|
41
|
+
* Clean up resources.
|
|
42
|
+
*/
|
|
43
|
+
dispose(): Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* Check if storage is accessible.
|
|
46
|
+
*/
|
|
47
|
+
isAvailable(): Promise<boolean>;
|
|
48
|
+
/**
|
|
49
|
+
* Get a single entity by type and ID.
|
|
50
|
+
* Returns undefined if not found.
|
|
51
|
+
*/
|
|
52
|
+
get<T extends BaseEntity>(type: string, id: string, namespace?: string): Promise<T | undefined>;
|
|
53
|
+
/**
|
|
54
|
+
* Get all entities of a type.
|
|
55
|
+
*/
|
|
56
|
+
getAll<T extends BaseEntity>(type: string, namespace?: string): Promise<T[]>;
|
|
57
|
+
/**
|
|
58
|
+
* Find entities matching a filter.
|
|
59
|
+
*/
|
|
60
|
+
find<T extends BaseEntity>(filter: EntityFilter): Promise<T[]>;
|
|
61
|
+
/**
|
|
62
|
+
* Check if an entity exists.
|
|
63
|
+
*/
|
|
64
|
+
exists(type: string, id: string, namespace?: string): Promise<boolean>;
|
|
65
|
+
/**
|
|
66
|
+
* Count entities matching a filter.
|
|
67
|
+
*/
|
|
68
|
+
count(filter: EntityFilter): Promise<number>;
|
|
69
|
+
/**
|
|
70
|
+
* Save an entity (create or update).
|
|
71
|
+
* Entity is validated against its registered schema.
|
|
72
|
+
* Returns the saved entity with updated metadata.
|
|
73
|
+
*/
|
|
74
|
+
save<T extends BaseEntity>(entity: T, namespace?: string): Promise<T>;
|
|
75
|
+
/**
|
|
76
|
+
* Delete an entity.
|
|
77
|
+
* Returns true if entity existed and was deleted.
|
|
78
|
+
*/
|
|
79
|
+
delete(type: string, id: string, namespace?: string): Promise<boolean>;
|
|
80
|
+
/**
|
|
81
|
+
* Save multiple entities in batch.
|
|
82
|
+
*/
|
|
83
|
+
saveBatch<T extends BaseEntity>(entities: T[], namespace?: string): Promise<T[]>;
|
|
84
|
+
/**
|
|
85
|
+
* Delete multiple entities in batch.
|
|
86
|
+
*/
|
|
87
|
+
deleteBatch(refs: Array<{
|
|
88
|
+
type: string;
|
|
89
|
+
id: string;
|
|
90
|
+
}>, namespace?: string): Promise<number>;
|
|
91
|
+
/**
|
|
92
|
+
* List available namespaces.
|
|
93
|
+
*/
|
|
94
|
+
listNamespaces(): Promise<string[]>;
|
|
95
|
+
/**
|
|
96
|
+
* Check if a namespace exists.
|
|
97
|
+
*/
|
|
98
|
+
namespaceExists(namespace: string): Promise<boolean>;
|
|
99
|
+
/**
|
|
100
|
+
* List entity types that have data in a namespace.
|
|
101
|
+
*/
|
|
102
|
+
listTypes(namespace?: string): Promise<string[]>;
|
|
103
|
+
/** Provider name (e.g., 'filesystem', 'memory') */
|
|
104
|
+
readonly name: string;
|
|
105
|
+
/** Storage location info */
|
|
106
|
+
readonly location: string;
|
|
107
|
+
/** Schema registry reference */
|
|
108
|
+
readonly registry: SchemaRegistry;
|
|
109
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { StorageProvider, StorageProviderOptions } from './interface';
|
|
2
|
+
import { BaseEntity } from '../schema/base';
|
|
3
|
+
export interface MemoryProviderOptions extends StorageProviderOptions {
|
|
4
|
+
/** Initial data to populate */
|
|
5
|
+
initialData?: BaseEntity[];
|
|
6
|
+
}
|
|
7
|
+
export declare const createMemoryProvider: (options: MemoryProviderOptions) => StorageProvider;
|