lmcs-db 1.0.4 → 2.0.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.
Files changed (39) hide show
  1. package/README.md +241 -85
  2. package/dist/core/collection.d.ts +33 -0
  3. package/dist/core/collection.js +287 -0
  4. package/dist/core/database.d.ts +35 -0
  5. package/dist/core/database.js +165 -0
  6. package/dist/core/indexer.d.ts +20 -0
  7. package/dist/core/indexer.js +89 -0
  8. package/dist/core/transaction-context.d.ts +13 -0
  9. package/dist/core/transaction-context.js +48 -0
  10. package/dist/core/transaction.d.ts +25 -0
  11. package/dist/core/transaction.js +122 -0
  12. package/dist/crypto/key-derivation.d.ts +0 -0
  13. package/dist/crypto/key-derivation.js +1 -0
  14. package/dist/crypto/manager.d.ts +22 -0
  15. package/dist/crypto/manager.js +76 -0
  16. package/dist/crypto/vault.d.ts +18 -0
  17. package/dist/crypto/vault.js +44 -0
  18. package/dist/index.d.ts +5 -2
  19. package/dist/index.js +12 -9
  20. package/dist/persistence/AsyncWriteWorker.js +11 -7
  21. package/dist/storage/aol.d.ts +26 -0
  22. package/dist/storage/aol.js +166 -0
  23. package/dist/storage/base.d.ts +36 -0
  24. package/dist/storage/base.js +13 -0
  25. package/dist/storage/binary.d.ts +21 -0
  26. package/dist/storage/binary.js +124 -0
  27. package/dist/storage/index.d.ts +5 -0
  28. package/dist/storage/index.js +13 -0
  29. package/dist/storage/json.d.ts +18 -0
  30. package/dist/storage/json.js +153 -0
  31. package/dist/storage/memory.d.ts +14 -0
  32. package/dist/storage/memory.js +42 -0
  33. package/dist/utils/checksum.d.ts +0 -0
  34. package/dist/utils/checksum.js +1 -0
  35. package/dist/utils/errors.d.ts +16 -0
  36. package/dist/utils/errors.js +37 -0
  37. package/dist/utils/lock.d.ts +9 -0
  38. package/dist/utils/lock.js +75 -0
  39. package/package.json +11 -5
@@ -0,0 +1,35 @@
1
+ import { Collection } from './collection';
2
+ import { TransactionContext } from './transaction-context';
3
+ export type StorageType = 'memory' | 'json' | 'aol' | 'binary';
4
+ export interface DatabaseOptions {
5
+ storageType: StorageType;
6
+ databaseName: string;
7
+ encryptionKey?: string;
8
+ customPath?: string;
9
+ compactionInterval?: number;
10
+ bufferSize?: number;
11
+ autosaveInterval?: number;
12
+ enableChecksums?: boolean;
13
+ }
14
+ export declare class Database {
15
+ private options;
16
+ private storage;
17
+ private collections;
18
+ private locker;
19
+ private lockPath;
20
+ private initialized;
21
+ private txManager?;
22
+ private txLock;
23
+ constructor(options: DatabaseOptions);
24
+ initialize(): Promise<void>;
25
+ collection<T extends Record<string, any>>(name: string): Collection<T>;
26
+ transaction<T>(fn: (trx: TransactionContext) => Promise<T>): Promise<T>;
27
+ save(): Promise<void>;
28
+ compact(): Promise<void>;
29
+ close(): Promise<void>;
30
+ get stats(): {
31
+ collections: number;
32
+ storage: StorageType;
33
+ };
34
+ }
35
+ export declare function createDatabase(options: DatabaseOptions): Promise<Database>;
@@ -0,0 +1,165 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Database = void 0;
4
+ exports.createDatabase = createDatabase;
5
+ const path_1 = require("path");
6
+ const promises_1 = require("fs/promises");
7
+ const storage_1 = require("../storage");
8
+ const collection_1 = require("./collection");
9
+ const transaction_1 = require("./transaction");
10
+ const transaction_context_1 = require("./transaction-context");
11
+ const lock_1 = require("../utils/lock");
12
+ class Database {
13
+ options;
14
+ storage;
15
+ collections = new Map();
16
+ locker;
17
+ lockPath;
18
+ initialized = false;
19
+ txManager;
20
+ txLock = Promise.resolve();
21
+ constructor(options) {
22
+ this.options = options;
23
+ const basePath = options.customPath || './data';
24
+ const config = {
25
+ dbPath: basePath,
26
+ dbName: options.databaseName,
27
+ encryptionKey: options.encryptionKey,
28
+ enableChecksums: options.enableChecksums ?? false
29
+ };
30
+ // Factory switch
31
+ switch (options.storageType) {
32
+ case 'memory':
33
+ this.storage = new storage_1.MemoryStorage(config);
34
+ break;
35
+ case 'json':
36
+ this.storage = new storage_1.JSONStorage(config, options.autosaveInterval);
37
+ break;
38
+ case 'aol':
39
+ this.storage = new storage_1.AOLStorage({
40
+ ...config,
41
+ compactionInterval: options.compactionInterval,
42
+ bufferSize: options.bufferSize
43
+ });
44
+ break;
45
+ case 'binary':
46
+ this.storage = new storage_1.BinaryStorage(config);
47
+ break;
48
+ default:
49
+ throw new Error(`Unknown storage type: ${options.storageType}`);
50
+ }
51
+ this.lockPath = (0, path_1.join)(basePath, `${options.databaseName}.lock`);
52
+ this.locker = new lock_1.FileLocker();
53
+ // Enable transactions by default or if configured
54
+ this.txManager = new transaction_1.TransactionManager(this.storage);
55
+ }
56
+ async initialize() {
57
+ if (this.initialized)
58
+ return;
59
+ const lockDir = (0, path_1.dirname)(this.lockPath);
60
+ await (0, promises_1.mkdir)(lockDir, { recursive: true });
61
+ try {
62
+ await (0, promises_1.access)(this.lockPath);
63
+ }
64
+ catch {
65
+ await (0, promises_1.writeFile)(this.lockPath, '', 'utf8');
66
+ }
67
+ await this.locker.acquire(this.lockPath);
68
+ await this.storage.initialize();
69
+ if (this.txManager) {
70
+ await this.txManager.recover();
71
+ }
72
+ this.initialized = true;
73
+ }
74
+ collection(name) {
75
+ if (!this.initialized)
76
+ throw new Error('Database not initialized');
77
+ if (!this.collections.has(name)) {
78
+ this.collections.set(name, new collection_1.Collection(name, this.storage));
79
+ }
80
+ return this.collections.get(name);
81
+ }
82
+ async transaction(fn) {
83
+ // Acquire lock for transaction serialization
84
+ let releaseLock;
85
+ const acquire = new Promise(resolve => releaseLock = resolve);
86
+ const currentLock = this.txLock;
87
+ this.txLock = this.txLock.then(() => acquire);
88
+ await currentLock;
89
+ try {
90
+ if (!this.txManager) {
91
+ throw new Error('Transactions not enabled');
92
+ }
93
+ const txId = await this.txManager.begin();
94
+ const context = new transaction_context_1.TransactionContext(txId, this.txManager, this.storage, async (col, id) => {
95
+ return this.collection(col).findOne({ _id: id });
96
+ });
97
+ try {
98
+ const result = await fn(context);
99
+ const ops = await this.txManager.commit(txId);
100
+ // Update in-memory state
101
+ for (const op of ops) {
102
+ const collection = this.collections.get(op.collection);
103
+ if (collection) {
104
+ let logOp;
105
+ switch (op.type) {
106
+ case 'insert':
107
+ logOp = 'INSERT';
108
+ break;
109
+ case 'update':
110
+ logOp = 'UPDATE';
111
+ break;
112
+ case 'delete':
113
+ logOp = 'DELETE';
114
+ break;
115
+ default: continue;
116
+ }
117
+ collection.applyLogEntry({
118
+ op: logOp,
119
+ collection: op.collection,
120
+ id: op.id,
121
+ data: op.newData,
122
+ checksum: '',
123
+ timestamp: Date.now(),
124
+ txId
125
+ });
126
+ }
127
+ }
128
+ return result;
129
+ }
130
+ catch (error) {
131
+ await this.txManager.rollback(txId);
132
+ throw error;
133
+ }
134
+ }
135
+ finally {
136
+ releaseLock();
137
+ }
138
+ }
139
+ async save() {
140
+ await this.storage.flush();
141
+ }
142
+ async compact() {
143
+ if (this.storage.compact) {
144
+ await this.storage.compact();
145
+ }
146
+ }
147
+ async close() {
148
+ await this.storage.close();
149
+ await this.locker.release(this.lockPath);
150
+ this.initialized = false;
151
+ }
152
+ get stats() {
153
+ return {
154
+ collections: this.collections.size,
155
+ storage: this.options.storageType
156
+ };
157
+ }
158
+ }
159
+ exports.Database = Database;
160
+ // Factory function para conveniência
161
+ async function createDatabase(options) {
162
+ const db = new Database(options);
163
+ await db.initialize();
164
+ return db;
165
+ }
@@ -0,0 +1,20 @@
1
+ export interface IndexDefinition {
2
+ fields: string[];
3
+ unique: boolean;
4
+ sparse: boolean;
5
+ name: string;
6
+ }
7
+ export declare class IndexManager {
8
+ private indexes;
9
+ private indexDefs;
10
+ createIndex(collection: string, fields: string | string[], options?: {
11
+ unique?: boolean;
12
+ sparse?: boolean;
13
+ }): void;
14
+ indexDocument(collection: string, id: string, doc: Record<string, any>): void;
15
+ removeDocument(collection: string, id: string, doc: Record<string, any>): void;
16
+ queryByIndex(collection: string, filter: Record<string, any>): Set<string> | null;
17
+ private extractKeyValue;
18
+ private getNestedValue;
19
+ getIndexDefinitions(collection: string): IndexDefinition[];
20
+ }
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.IndexManager = void 0;
4
+ class IndexManager {
5
+ indexes = new Map();
6
+ indexDefs = new Map();
7
+ createIndex(collection, fields, options) {
8
+ const fieldArray = Array.isArray(fields) ? fields : [fields];
9
+ const key = fieldArray.join(':');
10
+ if (!this.indexes.has(collection)) {
11
+ this.indexes.set(collection, new Map());
12
+ this.indexDefs.set(collection, []);
13
+ }
14
+ const colIndexes = this.indexes.get(collection);
15
+ if (colIndexes.has(key)) {
16
+ throw new Error(`Index already exists on ${key}`);
17
+ }
18
+ colIndexes.set(key, new Map());
19
+ this.indexDefs.get(collection).push({
20
+ fields: fieldArray,
21
+ unique: options?.unique ?? false,
22
+ sparse: options?.sparse ?? false,
23
+ name: key
24
+ });
25
+ }
26
+ indexDocument(collection, id, doc) {
27
+ const colIndexes = this.indexes.get(collection);
28
+ if (!colIndexes)
29
+ return;
30
+ for (const [key, indexMap] of colIndexes) {
31
+ const value = this.extractKeyValue(doc, key);
32
+ if (value === undefined)
33
+ continue;
34
+ const valueKey = JSON.stringify(value);
35
+ if (!indexMap.has(valueKey)) {
36
+ indexMap.set(valueKey, new Set());
37
+ }
38
+ indexMap.get(valueKey).add(id);
39
+ }
40
+ }
41
+ removeDocument(collection, id, doc) {
42
+ const colIndexes = this.indexes.get(collection);
43
+ if (!colIndexes)
44
+ return;
45
+ for (const [key, indexMap] of colIndexes) {
46
+ const value = this.extractKeyValue(doc, key);
47
+ if (value === undefined)
48
+ continue;
49
+ const valueKey = JSON.stringify(value);
50
+ const set = indexMap.get(valueKey);
51
+ if (set) {
52
+ set.delete(id);
53
+ if (set.size === 0)
54
+ indexMap.delete(valueKey);
55
+ }
56
+ }
57
+ }
58
+ queryByIndex(collection, filter) {
59
+ const colIndexes = this.indexes.get(collection);
60
+ if (!colIndexes)
61
+ return null;
62
+ const candidates = [];
63
+ for (const [key, indexMap] of colIndexes) {
64
+ const filterValue = this.extractKeyValue(filter, key);
65
+ if (filterValue !== undefined) {
66
+ const result = indexMap.get(JSON.stringify(filterValue));
67
+ if (result && result.size > 0)
68
+ candidates.push(new Set(result));
69
+ }
70
+ }
71
+ if (candidates.length === 0)
72
+ return null;
73
+ if (candidates.length === 1)
74
+ return candidates[0];
75
+ return candidates.reduce((a, b) => new Set([...a].filter(x => b.has(x))));
76
+ }
77
+ extractKeyValue(doc, key) {
78
+ const fields = key.split(':');
79
+ const values = fields.map(f => this.getNestedValue(doc, f));
80
+ return fields.length === 1 ? values[0] : values;
81
+ }
82
+ getNestedValue(obj, path) {
83
+ return path.split('.').reduce((o, p) => o?.[p], obj);
84
+ }
85
+ getIndexDefinitions(collection) {
86
+ return this.indexDefs.get(collection) || [];
87
+ }
88
+ }
89
+ exports.IndexManager = IndexManager;
@@ -0,0 +1,13 @@
1
+ import { IStorage } from '../storage/base';
2
+ import { TransactionManager } from './transaction';
3
+ export declare class TransactionContext {
4
+ private txId;
5
+ private txManager;
6
+ private storage;
7
+ private getData;
8
+ constructor(txId: string, txManager: TransactionManager, storage: IStorage, getData: (collection: string, id: string) => Promise<any>);
9
+ get id(): string;
10
+ insert(collection: string, data: any): Promise<void>;
11
+ update(collection: string, id: string, data: any): Promise<void>;
12
+ delete(collection: string, id: string): Promise<void>;
13
+ }
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TransactionContext = void 0;
4
+ const uuid_1 = require("uuid");
5
+ class TransactionContext {
6
+ txId;
7
+ txManager;
8
+ storage;
9
+ getData;
10
+ constructor(txId, txManager, storage, getData) {
11
+ this.txId = txId;
12
+ this.txManager = txManager;
13
+ this.storage = storage;
14
+ this.getData = getData;
15
+ }
16
+ get id() {
17
+ return this.txId;
18
+ }
19
+ async insert(collection, data) {
20
+ await this.txManager.addOperation(this.txId, {
21
+ type: 'insert',
22
+ collection,
23
+ id: data._id || (0, uuid_1.v7)(),
24
+ newData: data
25
+ });
26
+ }
27
+ async update(collection, id, data) {
28
+ const current = await this.getData(collection, id);
29
+ if (!current) {
30
+ throw new Error(`Document with id ${id} not found in collection ${collection}`);
31
+ }
32
+ const newData = { ...current, ...data };
33
+ await this.txManager.addOperation(this.txId, {
34
+ type: 'update',
35
+ collection,
36
+ id,
37
+ newData: newData
38
+ });
39
+ }
40
+ async delete(collection, id) {
41
+ await this.txManager.addOperation(this.txId, {
42
+ type: 'delete',
43
+ collection,
44
+ id
45
+ });
46
+ }
47
+ }
48
+ exports.TransactionContext = TransactionContext;
@@ -0,0 +1,25 @@
1
+ import { IStorage } from '../storage/base';
2
+ export interface Transaction {
3
+ id: string;
4
+ operations: Operation[];
5
+ status: 'pending' | 'committed' | 'aborted';
6
+ timestamp: number;
7
+ }
8
+ export interface Operation {
9
+ type: 'insert' | 'update' | 'delete';
10
+ collection: string;
11
+ id: string;
12
+ previousData?: unknown;
13
+ newData?: unknown;
14
+ }
15
+ export declare class TransactionManager {
16
+ private activeTransactions;
17
+ private storage;
18
+ constructor(storage: IStorage);
19
+ begin(): Promise<string>;
20
+ addOperation(txId: string, op: Operation): Promise<void>;
21
+ commit(txId: string): Promise<Operation[]>;
22
+ rollback(txId: string): Promise<void>;
23
+ getTransaction(txId: string): Transaction | undefined;
24
+ recover(): Promise<void>;
25
+ }
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TransactionManager = void 0;
4
+ const errors_1 = require("../utils/errors");
5
+ const uuid_1 = require("uuid");
6
+ class TransactionManager {
7
+ activeTransactions = new Map();
8
+ storage;
9
+ constructor(storage) {
10
+ this.storage = storage;
11
+ }
12
+ async begin() {
13
+ const txId = (0, uuid_1.v4)();
14
+ const tx = {
15
+ id: txId,
16
+ operations: [],
17
+ status: 'pending',
18
+ timestamp: Date.now()
19
+ };
20
+ this.activeTransactions.set(txId, tx);
21
+ await this.storage.append({
22
+ op: 'BEGIN',
23
+ collection: '_transactions',
24
+ id: txId,
25
+ checksum: '',
26
+ timestamp: tx.timestamp,
27
+ txId
28
+ });
29
+ return txId;
30
+ }
31
+ async addOperation(txId, op) {
32
+ const tx = this.activeTransactions.get(txId);
33
+ if (!tx)
34
+ throw new errors_1.TransactionError('Transaction not found');
35
+ if (tx.status !== 'pending')
36
+ throw new errors_1.TransactionError('Transaction already finalized');
37
+ tx.operations.push(op);
38
+ }
39
+ async commit(txId) {
40
+ const tx = this.activeTransactions.get(txId);
41
+ if (!tx)
42
+ throw new errors_1.TransactionError('Transaction not found');
43
+ // Apply operations to storage
44
+ for (const op of tx.operations) {
45
+ let storageOp;
46
+ switch (op.type) {
47
+ case 'insert':
48
+ storageOp = 'INSERT';
49
+ break;
50
+ case 'update':
51
+ storageOp = 'UPDATE';
52
+ break;
53
+ case 'delete':
54
+ storageOp = 'DELETE';
55
+ break;
56
+ default: continue;
57
+ }
58
+ await this.storage.append({
59
+ op: storageOp,
60
+ collection: op.collection,
61
+ id: op.id,
62
+ data: op.newData || {},
63
+ checksum: '',
64
+ timestamp: Date.now(),
65
+ txId: txId
66
+ });
67
+ }
68
+ await this.storage.append({
69
+ op: 'COMMIT',
70
+ collection: '_transactions',
71
+ id: txId,
72
+ checksum: '',
73
+ timestamp: Date.now(),
74
+ txId
75
+ });
76
+ const operations = [...tx.operations];
77
+ tx.status = 'committed';
78
+ this.activeTransactions.delete(txId);
79
+ return operations;
80
+ }
81
+ async rollback(txId) {
82
+ const tx = this.activeTransactions.get(txId);
83
+ if (!tx)
84
+ return;
85
+ await this.storage.append({
86
+ op: 'ROLLBACK',
87
+ collection: '_transactions',
88
+ id: txId,
89
+ checksum: '',
90
+ timestamp: Date.now(),
91
+ txId
92
+ });
93
+ tx.status = 'aborted';
94
+ this.activeTransactions.delete(txId);
95
+ }
96
+ getTransaction(txId) {
97
+ return this.activeTransactions.get(txId);
98
+ }
99
+ async recover() {
100
+ const pendingTxs = new Map();
101
+ for await (const entry of this.storage.readStream()) {
102
+ if (entry.collection !== '_transactions')
103
+ continue;
104
+ if (entry.op === 'BEGIN') {
105
+ pendingTxs.set(entry.id, {
106
+ id: entry.id,
107
+ operations: [],
108
+ status: 'pending',
109
+ timestamp: entry.timestamp
110
+ });
111
+ }
112
+ else if (entry.op === 'COMMIT' || entry.op === 'ROLLBACK') {
113
+ pendingTxs.delete(entry.id);
114
+ }
115
+ }
116
+ for (const [txId, tx] of pendingTxs) {
117
+ console.log(`Recovering incomplete transaction ${txId}`);
118
+ await this.rollback(txId);
119
+ }
120
+ }
121
+ }
122
+ exports.TransactionManager = TransactionManager;
File without changes
@@ -0,0 +1 @@
1
+ "use strict";
@@ -0,0 +1,22 @@
1
+ export interface EncryptedData {
2
+ data: string;
3
+ iv: string;
4
+ tag: string;
5
+ salt: string;
6
+ version: number;
7
+ }
8
+ export declare class CryptoManager {
9
+ private masterKey?;
10
+ private password?;
11
+ private _salt?;
12
+ private static readonly ALGORITHM;
13
+ private static readonly ITERATIONS;
14
+ private static readonly KEYLEN;
15
+ private static readonly VERSION;
16
+ constructor(password?: string);
17
+ private deriveKey;
18
+ encrypt(text: string): EncryptedData;
19
+ decrypt(encrypted: EncryptedData): string;
20
+ validateKey(testData?: EncryptedData): Promise<boolean>;
21
+ static hash(data: string): string;
22
+ }
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CryptoManager = void 0;
4
+ const crypto_1 = require("crypto");
5
+ class CryptoManager {
6
+ masterKey;
7
+ password;
8
+ _salt;
9
+ static ALGORITHM = 'aes-256-gcm';
10
+ static ITERATIONS = 100000;
11
+ static KEYLEN = 32;
12
+ static VERSION = 1;
13
+ constructor(password) {
14
+ if (password) {
15
+ this.password = password;
16
+ // Derivação inicial - salt aleatório gerado aqui
17
+ const salt = (0, crypto_1.randomBytes)(32);
18
+ this.masterKey = this.deriveKey(password, salt);
19
+ this._salt = salt.toString('hex'); // Guarda para referência
20
+ }
21
+ }
22
+ deriveKey(password, salt) {
23
+ return (0, crypto_1.pbkdf2Sync)(password, salt, CryptoManager.ITERATIONS, CryptoManager.KEYLEN, 'sha256');
24
+ }
25
+ encrypt(text) {
26
+ if (!this.masterKey)
27
+ throw new Error('CryptoManager not initialized with password');
28
+ const iv = (0, crypto_1.randomBytes)(16);
29
+ const cipher = (0, crypto_1.createCipheriv)(CryptoManager.ALGORITHM, this.masterKey, iv);
30
+ let encrypted = cipher.update(text, 'utf8', 'hex');
31
+ encrypted += cipher.final('hex');
32
+ return {
33
+ data: encrypted,
34
+ iv: iv.toString('hex'),
35
+ tag: cipher.getAuthTag().toString('hex'),
36
+ salt: this._salt,
37
+ version: CryptoManager.VERSION
38
+ };
39
+ }
40
+ decrypt(encrypted) {
41
+ if (!this.masterKey && !this.password)
42
+ throw new Error('CryptoManager not initialized with password');
43
+ let key = this.masterKey;
44
+ // Se o salt do dado for diferente do atual, e temos a senha, re-derivamos a chave
45
+ if (encrypted.salt && this._salt && encrypted.salt !== this._salt && this.password) {
46
+ key = this.deriveKey(this.password, Buffer.from(encrypted.salt, 'hex'));
47
+ }
48
+ else if (!key && this.password && encrypted.salt) {
49
+ // Caso onde só temos senha mas não inicializamos chave padrão (não deve ocorrer pelo construtor, mas por segurança)
50
+ key = this.deriveKey(this.password, Buffer.from(encrypted.salt, 'hex'));
51
+ }
52
+ if (!key)
53
+ throw new Error('Cannot decrypt: missing key or password');
54
+ const decipher = (0, crypto_1.createDecipheriv)(CryptoManager.ALGORITHM, key, Buffer.from(encrypted.iv, 'hex'));
55
+ decipher.setAuthTag(Buffer.from(encrypted.tag, 'hex'));
56
+ let decrypted = decipher.update(encrypted.data, 'hex', 'utf8');
57
+ decrypted += decipher.final('utf8');
58
+ return decrypted;
59
+ }
60
+ // Valida se a chave fornecida pode descriptografar os dados existentes
61
+ async validateKey(testData) {
62
+ if (!this.masterKey || !testData)
63
+ return false;
64
+ try {
65
+ this.decrypt(testData);
66
+ return true;
67
+ }
68
+ catch {
69
+ return false;
70
+ }
71
+ }
72
+ static hash(data) {
73
+ return (0, crypto_1.createHash)('sha256').update(data).digest('hex');
74
+ }
75
+ }
76
+ exports.CryptoManager = CryptoManager;
@@ -0,0 +1,18 @@
1
+ export interface EncryptedPayload {
2
+ ciphertext: string;
3
+ iv: string;
4
+ authTag: string;
5
+ salt: string;
6
+ iterations: number;
7
+ version: number;
8
+ }
9
+ export declare class CryptoVault {
10
+ private derivedKey;
11
+ private readonly ALGORITHM;
12
+ private readonly VERSION;
13
+ private readonly ITERATIONS;
14
+ private salt;
15
+ constructor(password: string, existingSalt?: string);
16
+ encrypt(data: string): EncryptedPayload;
17
+ decrypt(payload: EncryptedPayload): string;
18
+ }