@wxn0brp/db-core 0.12.9 → 0.12.10-alpha.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/base/actions.d.ts +2 -1
- package/dist/base/actions.js +9 -3
- package/dist/db/memory.d.ts +5 -0
- package/dist/db/memory.js +5 -0
- package/dist/db/multiStorage.js +10 -3
- package/dist/db/routedStorage.js +10 -3
- package/dist/db/transaction.d.ts +1 -1
- package/dist/db/transaction.js +25 -8
- package/dist/db/valthera.d.ts +5 -0
- package/dist/db/valthera.js +80 -15
- package/dist/errors.d.ts +71 -0
- package/dist/errors.js +156 -0
- package/dist/helpers/relation.js +9 -2
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/types/action.d.ts +6 -0
- package/dist/types/export.d.ts +1 -0
- package/dist/types/valthera.d.ts +2 -0
- package/dist/utils/hasFieldsAdvanced.js +4 -1
- package/dist/utils/updateObject.js +12 -3
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/base/actions.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ActionsBaseInterface } from "../types/action.js";
|
|
1
|
+
import { ActionsBaseInterface, AdapterCapabilities } from "../types/action.js";
|
|
2
2
|
import { DataInternal } from "../types/data.js";
|
|
3
3
|
import { Id } from "../types/Id.js";
|
|
4
4
|
import { AdapterOpts } from "../types/options.js";
|
|
@@ -8,6 +8,7 @@ export declare abstract class ActionsBase implements ActionsBaseInterface {
|
|
|
8
8
|
_inited: boolean;
|
|
9
9
|
adapterOpts: AdapterOpts;
|
|
10
10
|
smartExecutor: boolean;
|
|
11
|
+
capabilities: AdapterCapabilities;
|
|
11
12
|
version: string;
|
|
12
13
|
init(...args: any[]): Promise<void>;
|
|
13
14
|
close(...args: any[]): Promise<void>;
|
package/dist/base/actions.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { UnsupportedOperationError } from "../errors.js";
|
|
1
2
|
import { setDataForToggleOne, setDataForUpdateOneOrAdd, } from "../helpers/assignDataPush.js";
|
|
2
3
|
import { version } from "../version.js";
|
|
3
4
|
export class ActionsBase {
|
|
@@ -7,17 +8,22 @@ export class ActionsBase {
|
|
|
7
8
|
idKey: "_id",
|
|
8
9
|
};
|
|
9
10
|
smartExecutor = false;
|
|
11
|
+
capabilities = {
|
|
12
|
+
transactions: false,
|
|
13
|
+
indexes: false,
|
|
14
|
+
persistent: true,
|
|
15
|
+
};
|
|
10
16
|
version = "ActionsBase-core-" + version;
|
|
11
17
|
async init(...args) { }
|
|
12
18
|
async close(...args) { }
|
|
13
19
|
async beginTransaction(id) {
|
|
14
|
-
throw new
|
|
20
|
+
throw new UnsupportedOperationError("beginTransaction");
|
|
15
21
|
}
|
|
16
22
|
async commitTransaction(handle) {
|
|
17
|
-
throw new
|
|
23
|
+
throw new UnsupportedOperationError("commitTransaction");
|
|
18
24
|
}
|
|
19
25
|
async rollbackTransaction(handle) {
|
|
20
|
-
throw new
|
|
26
|
+
throw new UnsupportedOperationError("rollbackTransaction");
|
|
21
27
|
}
|
|
22
28
|
async createIndex(config) {
|
|
23
29
|
// No-op: adapter does not use indexes internally
|
package/dist/db/memory.d.ts
CHANGED
|
@@ -6,6 +6,11 @@ import { ValtheraClass } from "./valthera.js";
|
|
|
6
6
|
export declare class MemoryAction extends CustomActionsBase {
|
|
7
7
|
memory: Map<string, any[]>;
|
|
8
8
|
smartExecutor: boolean;
|
|
9
|
+
capabilities: {
|
|
10
|
+
transactions: boolean;
|
|
11
|
+
indexes: boolean;
|
|
12
|
+
persistent: boolean;
|
|
13
|
+
};
|
|
9
14
|
constructor();
|
|
10
15
|
_readMemory(key: string): any[];
|
|
11
16
|
_writeMemory(key: string, data: any[]): void;
|
package/dist/db/memory.js
CHANGED
|
@@ -6,6 +6,11 @@ import { ValtheraClass } from "./valthera.js";
|
|
|
6
6
|
export class MemoryAction extends CustomActionsBase {
|
|
7
7
|
memory;
|
|
8
8
|
smartExecutor = true;
|
|
9
|
+
capabilities = {
|
|
10
|
+
transactions: false,
|
|
11
|
+
indexes: false,
|
|
12
|
+
persistent: false,
|
|
13
|
+
};
|
|
9
14
|
constructor() {
|
|
10
15
|
super();
|
|
11
16
|
this.fileCpu = new CustomFileCpu(this._readMemory.bind(this), this._writeMemory.bind(this), true);
|
package/dist/db/multiStorage.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ActionsBase } from "../base/actions.js";
|
|
2
|
+
import { UnsupportedOperationError } from "../errors.js";
|
|
2
3
|
export class MultiBackend extends ActionsBase {
|
|
3
4
|
backends;
|
|
4
5
|
primaryBackend;
|
|
@@ -107,12 +108,18 @@ export class MultiBackend extends ActionsBase {
|
|
|
107
108
|
return Array.from(uniqueCollections);
|
|
108
109
|
}
|
|
109
110
|
async beginTransaction() {
|
|
110
|
-
throw new
|
|
111
|
+
throw new UnsupportedOperationError("beginTransaction", {
|
|
112
|
+
adapter: "MultiBackend",
|
|
113
|
+
});
|
|
111
114
|
}
|
|
112
115
|
async commitTransaction() {
|
|
113
|
-
throw new
|
|
116
|
+
throw new UnsupportedOperationError("commitTransaction", {
|
|
117
|
+
adapter: "MultiBackend",
|
|
118
|
+
});
|
|
114
119
|
}
|
|
115
120
|
async rollbackTransaction() {
|
|
116
|
-
throw new
|
|
121
|
+
throw new UnsupportedOperationError("rollbackTransaction", {
|
|
122
|
+
adapter: "MultiBackend",
|
|
123
|
+
});
|
|
117
124
|
}
|
|
118
125
|
}
|
package/dist/db/routedStorage.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ActionsBase } from "../base/actions.js";
|
|
2
|
+
import { UnsupportedOperationError } from "../errors.js";
|
|
2
3
|
export class RoutedStorage extends ActionsBase {
|
|
3
4
|
rules;
|
|
4
5
|
defaultBackend;
|
|
@@ -110,12 +111,18 @@ export class RoutedStorage extends ActionsBase {
|
|
|
110
111
|
return Array.from(merged);
|
|
111
112
|
}
|
|
112
113
|
async beginTransaction() {
|
|
113
|
-
throw new
|
|
114
|
+
throw new UnsupportedOperationError("beginTransaction", {
|
|
115
|
+
adapter: "RoutedStorage",
|
|
116
|
+
});
|
|
114
117
|
}
|
|
115
118
|
async commitTransaction() {
|
|
116
|
-
throw new
|
|
119
|
+
throw new UnsupportedOperationError("commitTransaction", {
|
|
120
|
+
adapter: "RoutedStorage",
|
|
121
|
+
});
|
|
117
122
|
}
|
|
118
123
|
async rollbackTransaction() {
|
|
119
|
-
throw new
|
|
124
|
+
throw new UnsupportedOperationError("rollbackTransaction", {
|
|
125
|
+
adapter: "RoutedStorage",
|
|
126
|
+
});
|
|
120
127
|
}
|
|
121
128
|
}
|
package/dist/db/transaction.d.ts
CHANGED
|
@@ -13,7 +13,7 @@ export declare class Transaction {
|
|
|
13
13
|
constructor(handle: TransactionHandle, _parent: ValtheraClass);
|
|
14
14
|
c<T = Data>(name: string): Collection<T>;
|
|
15
15
|
add<T = Data>(q: VQueryT.Add<T>): Promise<T>;
|
|
16
|
-
bulkAdd<T = Data>(q: VQueryT.BulkAdd<T>): Promise<
|
|
16
|
+
bulkAdd<T = Data>(q: VQueryT.BulkAdd<T>): Promise<T[]>;
|
|
17
17
|
find<T = Data>(q: VQueryT.Find<T, true>): Promise<T[]>;
|
|
18
18
|
findOne<T = Data>(q: VQueryT.FindOne<T>): Promise<T | null>;
|
|
19
19
|
update<T = Data>(q: VQueryT.Update<T>): Promise<T[]>;
|
package/dist/db/transaction.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { wrapAdapterError } from "../errors.js";
|
|
1
2
|
import { Collection } from "../helpers/collection.js";
|
|
2
3
|
import { applyAddDefaults, applyBulkAddDefaults, applyCountDefaults, applyFindDefaults, applyFindOneDefaults, applyRemoveDefaults, applyToggleOneDefaults, applyUpdateDefaults, applyUpdateOneOrAddDefaults, } from "../helpers/queryDefaults.js";
|
|
3
4
|
/**
|
|
@@ -20,7 +21,7 @@ export class Transaction {
|
|
|
20
21
|
}
|
|
21
22
|
bulkAdd(q) {
|
|
22
23
|
applyBulkAddDefaults(q);
|
|
23
|
-
return this._parent.
|
|
24
|
+
return this._parent.execute("bulkAdd", q, this.handle);
|
|
24
25
|
}
|
|
25
26
|
find(q) {
|
|
26
27
|
applyFindDefaults(q);
|
|
@@ -56,24 +57,40 @@ export class Transaction {
|
|
|
56
57
|
}
|
|
57
58
|
count(q) {
|
|
58
59
|
applyCountDefaults(q);
|
|
59
|
-
return this._parent.
|
|
60
|
+
return this._parent.execute("count", q, this.handle);
|
|
60
61
|
}
|
|
61
62
|
ensureCollection(collection) {
|
|
62
|
-
return this._parent.
|
|
63
|
+
return this._parent.execute("ensureCollection", collection, this.handle);
|
|
63
64
|
}
|
|
64
65
|
issetCollection(collection) {
|
|
65
|
-
return this._parent.
|
|
66
|
+
return this._parent.execute("issetCollection", collection, this.handle);
|
|
66
67
|
}
|
|
67
68
|
getCollections() {
|
|
68
|
-
return this._parent.
|
|
69
|
+
return this._parent.execute("getCollections", {}, this.handle);
|
|
69
70
|
}
|
|
70
71
|
removeCollection(collection) {
|
|
71
|
-
return this._parent.
|
|
72
|
+
return this._parent.execute("removeCollection", collection, this.handle);
|
|
72
73
|
}
|
|
73
74
|
async commit() {
|
|
74
|
-
|
|
75
|
+
try {
|
|
76
|
+
await this._parent.adapter.commitTransaction(this.handle);
|
|
77
|
+
}
|
|
78
|
+
catch (err) {
|
|
79
|
+
throw wrapAdapterError(err, {
|
|
80
|
+
op: "commitTransaction",
|
|
81
|
+
adapter: this._parent.adapter?.version,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
75
84
|
}
|
|
76
85
|
async rollback() {
|
|
77
|
-
|
|
86
|
+
try {
|
|
87
|
+
await this._parent.adapter.rollbackTransaction(this.handle);
|
|
88
|
+
}
|
|
89
|
+
catch (err) {
|
|
90
|
+
throw wrapAdapterError(err, {
|
|
91
|
+
op: "rollbackTransaction",
|
|
92
|
+
adapter: this._parent.adapter?.version,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
78
95
|
}
|
|
79
96
|
}
|
package/dist/db/valthera.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { VEE } from "@wxn0brp/event-emitter";
|
|
|
2
2
|
import { ActionsBase } from "../base/actions.js";
|
|
3
3
|
import { Collection } from "../helpers/collection.js";
|
|
4
4
|
import { ExecutorInterface } from "../helpers/executor.js";
|
|
5
|
+
import { AdapterCapabilities } from "../types/action.js";
|
|
5
6
|
import { Data } from "../types/data.js";
|
|
6
7
|
import { IndexOpts } from "../types/idx.js";
|
|
7
8
|
import { DbOpts } from "../types/options.js";
|
|
@@ -97,6 +98,10 @@ export declare class ValtheraClass implements ValtheraCompatible {
|
|
|
97
98
|
*/
|
|
98
99
|
removeIndex(collection: string, fields: string[]): Promise<void>;
|
|
99
100
|
count(query: VQueryT.Count): Promise<number>;
|
|
101
|
+
/**
|
|
102
|
+
* Describe what the underlying adapter supports.
|
|
103
|
+
*/
|
|
104
|
+
capabilities(): Promise<AdapterCapabilities>;
|
|
100
105
|
/**
|
|
101
106
|
* @experimental
|
|
102
107
|
*
|
package/dist/db/valthera.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { VEE } from "@wxn0brp/event-emitter";
|
|
2
|
+
import { AdapterCloseError, AdapterInitError, ErrorCodes, isValtheraError, QueryValidationError, TransactionError, wrapAdapterError, } from "../errors.js";
|
|
2
3
|
import { Collection } from "../helpers/collection.js";
|
|
3
4
|
import { SmartExecutor } from "../helpers/executor.js";
|
|
4
5
|
import { genId } from "../helpers/gen.js";
|
|
5
|
-
import { applyAddDefaults,
|
|
6
|
+
import { applyAddDefaults, applyBulkAddDefaults, applyCountDefaults, applyFindDefaults, applyFindOneDefaults, applyRemoveDefaults, applyToggleOneDefaults, applyUpdateDefaults, applyUpdateOneOrAddDefaults, } from "../helpers/queryDefaults.js";
|
|
6
7
|
import { version } from "../version.js";
|
|
7
8
|
import { Transaction } from "./transaction.js";
|
|
8
9
|
/**
|
|
@@ -48,11 +49,24 @@ export class ValtheraClass {
|
|
|
48
49
|
if (this.adapter?._inited)
|
|
49
50
|
return;
|
|
50
51
|
const self = this;
|
|
52
|
+
const failInit = (err) => {
|
|
53
|
+
if (isValtheraError(err))
|
|
54
|
+
throw err;
|
|
55
|
+
throw new AdapterInitError(err, {
|
|
56
|
+
adapter: self.adapter?.version,
|
|
57
|
+
});
|
|
58
|
+
};
|
|
51
59
|
return await this.executor.addOp(async () => {
|
|
52
60
|
if (self.adapter?._inited)
|
|
53
61
|
return;
|
|
54
|
-
if (typeof self.options.adapter === "function")
|
|
55
|
-
|
|
62
|
+
if (typeof self.options.adapter === "function") {
|
|
63
|
+
try {
|
|
64
|
+
self.adapter = await self.options.adapter();
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
failInit(err);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
56
70
|
// if the executor is not set, and the action wants a smart executor
|
|
57
71
|
if (!self.options.executor &&
|
|
58
72
|
self.options.executorAware &&
|
|
@@ -65,7 +79,12 @@ export class ValtheraClass {
|
|
|
65
79
|
...self.options.adapterOpts,
|
|
66
80
|
};
|
|
67
81
|
}
|
|
68
|
-
|
|
82
|
+
try {
|
|
83
|
+
await self.adapter.init(...args);
|
|
84
|
+
}
|
|
85
|
+
catch (err) {
|
|
86
|
+
failInit(err);
|
|
87
|
+
}
|
|
69
88
|
self.adapter._inited = true;
|
|
70
89
|
});
|
|
71
90
|
}
|
|
@@ -76,15 +95,28 @@ export class ValtheraClass {
|
|
|
76
95
|
return await this.executor.addOp(async () => {
|
|
77
96
|
if (!self.adapter?._inited)
|
|
78
97
|
return;
|
|
79
|
-
|
|
98
|
+
try {
|
|
99
|
+
await self.adapter.close(...args);
|
|
100
|
+
}
|
|
101
|
+
catch (err) {
|
|
102
|
+
if (isValtheraError(err))
|
|
103
|
+
throw err;
|
|
104
|
+
throw new AdapterCloseError(err, {
|
|
105
|
+
adapter: self.adapter?.version,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
80
108
|
self.adapter._inited = false;
|
|
81
109
|
});
|
|
82
110
|
}
|
|
83
111
|
async execute(name, query, txHandle) {
|
|
84
112
|
await this.init();
|
|
85
|
-
|
|
113
|
+
const collection = typeof query === "string" ? query : query?.collection;
|
|
114
|
+
if (!collection && name !== "getCollections")
|
|
115
|
+
throw new QueryValidationError(`Missing "collection" for operation "${String(name)}"`, {
|
|
116
|
+
op: name,
|
|
117
|
+
});
|
|
118
|
+
if (txHandle && query && typeof query === "object")
|
|
86
119
|
query.transaction = txHandle;
|
|
87
|
-
const collection = typeof query === "string" ? query : query.collection;
|
|
88
120
|
const plugins = this._plugins.filter(p => !p.collections || p.collections.includes(collection));
|
|
89
121
|
const self = this;
|
|
90
122
|
let idx = 0;
|
|
@@ -94,9 +126,18 @@ export class ValtheraClass {
|
|
|
94
126
|
next: async () => {
|
|
95
127
|
if (idx < plugins.length)
|
|
96
128
|
return plugins[idx++].execute(ctx);
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
129
|
+
try {
|
|
130
|
+
if (txHandle)
|
|
131
|
+
return await self.adapter[ctx.op](query, txHandle);
|
|
132
|
+
return await self.executor.addOp(self.adapter[ctx.op].bind(self.adapter), ctx.query, typeof ctx.query === "string" ? ctx.query : ctx.query.collection);
|
|
133
|
+
}
|
|
134
|
+
catch (err) {
|
|
135
|
+
throw wrapAdapterError(err, {
|
|
136
|
+
op: ctx.op,
|
|
137
|
+
collection,
|
|
138
|
+
adapter: self.adapter?.version,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
100
141
|
},
|
|
101
142
|
};
|
|
102
143
|
const result = await ctx.next();
|
|
@@ -236,6 +277,15 @@ export class ValtheraClass {
|
|
|
236
277
|
applyCountDefaults(query);
|
|
237
278
|
return this.execute("count", query);
|
|
238
279
|
}
|
|
280
|
+
/**
|
|
281
|
+
* Describe what the underlying adapter supports.
|
|
282
|
+
*/
|
|
283
|
+
async capabilities() {
|
|
284
|
+
await this.init();
|
|
285
|
+
return {
|
|
286
|
+
...this.adapter.capabilities,
|
|
287
|
+
};
|
|
288
|
+
}
|
|
239
289
|
/**
|
|
240
290
|
* @experimental
|
|
241
291
|
*
|
|
@@ -264,7 +314,16 @@ export class ValtheraClass {
|
|
|
264
314
|
});
|
|
265
315
|
await Promise.all(promises);
|
|
266
316
|
try {
|
|
267
|
-
|
|
317
|
+
let handle;
|
|
318
|
+
try {
|
|
319
|
+
handle = await this.adapter.beginTransaction(genId());
|
|
320
|
+
}
|
|
321
|
+
catch (err) {
|
|
322
|
+
throw wrapAdapterError(err, {
|
|
323
|
+
op: "beginTransaction",
|
|
324
|
+
adapter: this.adapter?.version,
|
|
325
|
+
});
|
|
326
|
+
}
|
|
268
327
|
const tx = new Transaction(handle, this);
|
|
269
328
|
try {
|
|
270
329
|
const result = await fn(tx);
|
|
@@ -276,10 +335,16 @@ export class ValtheraClass {
|
|
|
276
335
|
await tx.rollback();
|
|
277
336
|
}
|
|
278
337
|
catch (rollbackErr) {
|
|
279
|
-
throw new
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
338
|
+
throw new TransactionError("Transaction failed and rollback failed", {
|
|
339
|
+
code: ErrorCodes.TRANSACTION_ROLLBACK_FAILED,
|
|
340
|
+
cause: new AggregateError([
|
|
341
|
+
err,
|
|
342
|
+
rollbackErr,
|
|
343
|
+
], "Transaction failed and rollback failed"),
|
|
344
|
+
context: {
|
|
345
|
+
collections,
|
|
346
|
+
},
|
|
347
|
+
});
|
|
283
348
|
}
|
|
284
349
|
throw err;
|
|
285
350
|
}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
export declare const ErrorCodes: {
|
|
2
|
+
readonly UNSUPPORTED_OPERATION: "UNSUPPORTED_OPERATION";
|
|
3
|
+
readonly ADAPTER_ERROR: "ADAPTER_ERROR";
|
|
4
|
+
readonly ADAPTER_INIT: "ADAPTER_INIT";
|
|
5
|
+
readonly ADAPTER_CLOSE: "ADAPTER_CLOSE";
|
|
6
|
+
readonly QUERY_INVALID: "QUERY_INVALID";
|
|
7
|
+
readonly TRANSACTION_FAILED: "TRANSACTION_FAILED";
|
|
8
|
+
readonly TRANSACTION_ROLLBACK_FAILED: "TRANSACTION_ROLLBACK_FAILED";
|
|
9
|
+
readonly REMOTE_ERROR: "REMOTE_ERROR";
|
|
10
|
+
readonly REMOTE_UNKNOWN: "REMOTE_UNKNOWN";
|
|
11
|
+
};
|
|
12
|
+
export type ErrorCode = (typeof ErrorCodes)[keyof typeof ErrorCodes];
|
|
13
|
+
export interface ValtheraErrorOpts {
|
|
14
|
+
code: string;
|
|
15
|
+
cause?: unknown;
|
|
16
|
+
suggestion?: string;
|
|
17
|
+
context?: Record<string, unknown>;
|
|
18
|
+
}
|
|
19
|
+
export interface ValtheraErrorWire {
|
|
20
|
+
code?: string;
|
|
21
|
+
message?: string;
|
|
22
|
+
suggestion?: string;
|
|
23
|
+
context?: Record<string, unknown>;
|
|
24
|
+
}
|
|
25
|
+
export declare class ValtheraError extends Error {
|
|
26
|
+
code: string;
|
|
27
|
+
suggestion?: string;
|
|
28
|
+
context?: Record<string, unknown>;
|
|
29
|
+
constructor(message: string, opts: ValtheraErrorOpts);
|
|
30
|
+
toJSON(): {
|
|
31
|
+
name: string;
|
|
32
|
+
code: string;
|
|
33
|
+
message: string;
|
|
34
|
+
suggestion?: string | undefined;
|
|
35
|
+
context?: Record<string, unknown> | undefined;
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
export declare class UnsupportedOperationError extends ValtheraError {
|
|
39
|
+
constructor(operation: string, context?: Record<string, unknown>);
|
|
40
|
+
}
|
|
41
|
+
export declare class QueryValidationError extends ValtheraError {
|
|
42
|
+
constructor(reason: string, context?: Record<string, unknown>);
|
|
43
|
+
}
|
|
44
|
+
export declare class AdapterError extends ValtheraError {
|
|
45
|
+
constructor(cause: unknown, context?: Record<string, unknown>);
|
|
46
|
+
}
|
|
47
|
+
export declare class AdapterInitError extends ValtheraError {
|
|
48
|
+
constructor(cause: unknown, context?: Record<string, unknown>);
|
|
49
|
+
}
|
|
50
|
+
export declare class AdapterCloseError extends ValtheraError {
|
|
51
|
+
constructor(cause: unknown, context?: Record<string, unknown>);
|
|
52
|
+
}
|
|
53
|
+
export declare class TransactionError extends ValtheraError {
|
|
54
|
+
constructor(message: string, opts?: {
|
|
55
|
+
cause?: unknown;
|
|
56
|
+
context?: Record<string, unknown>;
|
|
57
|
+
code?: string;
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
export declare class RemoteError extends ValtheraError {
|
|
61
|
+
constructor(cause: unknown, context?: Record<string, unknown>);
|
|
62
|
+
}
|
|
63
|
+
export declare function isValtheraError(e: unknown): e is ValtheraError;
|
|
64
|
+
/**
|
|
65
|
+
* Adapter errors: keep ValtheraError codes, else wrap into AdapterError.
|
|
66
|
+
*/
|
|
67
|
+
export declare function wrapAdapterError(cause: unknown, context?: Record<string, unknown>): ValtheraError;
|
|
68
|
+
/**
|
|
69
|
+
* Rebuild a ValtheraError from a server response; match by `code`, not class.
|
|
70
|
+
*/
|
|
71
|
+
export declare function errorFromWire(payload: ValtheraErrorWire): ValtheraError;
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
export const ErrorCodes = {
|
|
2
|
+
UNSUPPORTED_OPERATION: "UNSUPPORTED_OPERATION",
|
|
3
|
+
ADAPTER_ERROR: "ADAPTER_ERROR",
|
|
4
|
+
ADAPTER_INIT: "ADAPTER_INIT",
|
|
5
|
+
ADAPTER_CLOSE: "ADAPTER_CLOSE",
|
|
6
|
+
QUERY_INVALID: "QUERY_INVALID",
|
|
7
|
+
TRANSACTION_FAILED: "TRANSACTION_FAILED",
|
|
8
|
+
TRANSACTION_ROLLBACK_FAILED: "TRANSACTION_ROLLBACK_FAILED",
|
|
9
|
+
REMOTE_ERROR: "REMOTE_ERROR",
|
|
10
|
+
REMOTE_UNKNOWN: "REMOTE_UNKNOWN",
|
|
11
|
+
};
|
|
12
|
+
export class ValtheraError extends Error {
|
|
13
|
+
code;
|
|
14
|
+
suggestion;
|
|
15
|
+
context;
|
|
16
|
+
constructor(message, opts) {
|
|
17
|
+
super(message, {
|
|
18
|
+
cause: opts.cause,
|
|
19
|
+
});
|
|
20
|
+
this.name = "ValtheraError";
|
|
21
|
+
this.code = opts.code;
|
|
22
|
+
this.suggestion = opts.suggestion;
|
|
23
|
+
this.context = opts.context;
|
|
24
|
+
}
|
|
25
|
+
toJSON() {
|
|
26
|
+
return {
|
|
27
|
+
name: this.name,
|
|
28
|
+
code: this.code,
|
|
29
|
+
message: this.message,
|
|
30
|
+
...(this.suggestion
|
|
31
|
+
? {
|
|
32
|
+
suggestion: this.suggestion,
|
|
33
|
+
}
|
|
34
|
+
: {}),
|
|
35
|
+
...(this.context
|
|
36
|
+
? {
|
|
37
|
+
context: this.context,
|
|
38
|
+
}
|
|
39
|
+
: {}),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
export class UnsupportedOperationError extends ValtheraError {
|
|
44
|
+
constructor(operation, context = {}) {
|
|
45
|
+
super(`Operation "${operation}" is not supported`, {
|
|
46
|
+
code: ErrorCodes.UNSUPPORTED_OPERATION,
|
|
47
|
+
context: {
|
|
48
|
+
op: operation,
|
|
49
|
+
...context,
|
|
50
|
+
},
|
|
51
|
+
suggestion: "Check the adapter capabilities before calling this operation",
|
|
52
|
+
});
|
|
53
|
+
this.name = "UnsupportedOperationError";
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
export class QueryValidationError extends ValtheraError {
|
|
57
|
+
constructor(reason, context = {}) {
|
|
58
|
+
super(reason, {
|
|
59
|
+
code: ErrorCodes.QUERY_INVALID,
|
|
60
|
+
context,
|
|
61
|
+
suggestion: "Check the query shape and the collection name",
|
|
62
|
+
});
|
|
63
|
+
this.name = "QueryValidationError";
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
export class AdapterError extends ValtheraError {
|
|
67
|
+
constructor(cause, context = {}) {
|
|
68
|
+
super(errorMessage(cause), {
|
|
69
|
+
code: ErrorCodes.ADAPTER_ERROR,
|
|
70
|
+
cause,
|
|
71
|
+
context,
|
|
72
|
+
});
|
|
73
|
+
this.name = "AdapterError";
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
export class AdapterInitError extends ValtheraError {
|
|
77
|
+
constructor(cause, context = {}) {
|
|
78
|
+
super(`Adapter init failed: ${errorMessage(cause)}`, {
|
|
79
|
+
code: ErrorCodes.ADAPTER_INIT,
|
|
80
|
+
cause,
|
|
81
|
+
context,
|
|
82
|
+
});
|
|
83
|
+
this.name = "AdapterInitError";
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
export class AdapterCloseError extends ValtheraError {
|
|
87
|
+
constructor(cause, context = {}) {
|
|
88
|
+
super(`Adapter close failed: ${errorMessage(cause)}`, {
|
|
89
|
+
code: ErrorCodes.ADAPTER_CLOSE,
|
|
90
|
+
cause,
|
|
91
|
+
context,
|
|
92
|
+
});
|
|
93
|
+
this.name = "AdapterCloseError";
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
export class TransactionError extends ValtheraError {
|
|
97
|
+
constructor(message, opts = {}) {
|
|
98
|
+
super(message, {
|
|
99
|
+
code: opts.code ?? ErrorCodes.TRANSACTION_FAILED,
|
|
100
|
+
cause: opts.cause,
|
|
101
|
+
context: opts.context,
|
|
102
|
+
});
|
|
103
|
+
this.name = "TransactionError";
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
export class RemoteError extends ValtheraError {
|
|
107
|
+
constructor(cause, context = {}) {
|
|
108
|
+
super(errorMessage(cause), {
|
|
109
|
+
code: ErrorCodes.REMOTE_ERROR,
|
|
110
|
+
cause,
|
|
111
|
+
context,
|
|
112
|
+
});
|
|
113
|
+
this.name = "RemoteError";
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
function errorMessage(cause) {
|
|
117
|
+
return cause instanceof Error ? cause.message : String(cause);
|
|
118
|
+
}
|
|
119
|
+
export function isValtheraError(e) {
|
|
120
|
+
return e instanceof ValtheraError;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Copy a ValtheraError with merged context; keeps `instanceof` and `cause`
|
|
124
|
+
*/
|
|
125
|
+
function cloneWithContext(err, context) {
|
|
126
|
+
const clone = Object.create(Object.getPrototypeOf(err));
|
|
127
|
+
Object.assign(clone, err);
|
|
128
|
+
clone.message = err.message;
|
|
129
|
+
clone.stack = err.stack;
|
|
130
|
+
clone.cause = err.cause;
|
|
131
|
+
clone.context = {
|
|
132
|
+
...context,
|
|
133
|
+
...err.context,
|
|
134
|
+
};
|
|
135
|
+
return clone;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Adapter errors: keep ValtheraError codes, else wrap into AdapterError.
|
|
139
|
+
*/
|
|
140
|
+
export function wrapAdapterError(cause, context = {}) {
|
|
141
|
+
if (cause instanceof ValtheraError)
|
|
142
|
+
return Object.keys(context).length
|
|
143
|
+
? cloneWithContext(cause, context)
|
|
144
|
+
: cause;
|
|
145
|
+
return new AdapterError(cause, context);
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Rebuild a ValtheraError from a server response; match by `code`, not class.
|
|
149
|
+
*/
|
|
150
|
+
export function errorFromWire(payload) {
|
|
151
|
+
return new ValtheraError(payload.message ?? "Unknown remote error", {
|
|
152
|
+
code: payload.code ?? ErrorCodes.REMOTE_UNKNOWN,
|
|
153
|
+
suggestion: payload.suggestion,
|
|
154
|
+
context: payload.context,
|
|
155
|
+
});
|
|
156
|
+
}
|
package/dist/helpers/relation.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { QueryValidationError } from "../errors.js";
|
|
1
2
|
export function pickByPath(obj, paths) {
|
|
2
3
|
const result = {};
|
|
3
4
|
for (const path of paths) {
|
|
@@ -160,7 +161,10 @@ export async function processRelations(dbs, cfg, data, parentList = null) {
|
|
|
160
161
|
}
|
|
161
162
|
else if (type === "nm") {
|
|
162
163
|
if (!through || !through.table || !through.pk || !through.fk)
|
|
163
|
-
throw new
|
|
164
|
+
throw new QueryValidationError(`Relation type "nm" requires a defined "through" in "${key}"`, {
|
|
165
|
+
op: "relation",
|
|
166
|
+
key,
|
|
167
|
+
});
|
|
164
168
|
const allSourceIds = targets.map(i => i[pk]);
|
|
165
169
|
const pivotDb = dbs[through.db || dbKey];
|
|
166
170
|
const allPivots = await pivotDb.find({
|
|
@@ -248,7 +252,10 @@ export async function processRelations(dbs, cfg, data, parentList = null) {
|
|
|
248
252
|
}
|
|
249
253
|
}
|
|
250
254
|
else {
|
|
251
|
-
throw new
|
|
255
|
+
throw new QueryValidationError(`Unknown relation type: ${type}`, {
|
|
256
|
+
op: "relation",
|
|
257
|
+
type,
|
|
258
|
+
});
|
|
252
259
|
}
|
|
253
260
|
}
|
|
254
261
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
export { CustomFileCpu } from "./customFileCpu.js";
|
|
2
2
|
export { createMemoryValthera, ValtheraMemory } from "./db/memory.js";
|
|
3
3
|
export { ValtheraClass } from "./db/valthera.js";
|
|
4
|
+
export * from "./errors.js";
|
|
4
5
|
export { forgeTypedValthera } from "./helpers/forge.js";
|
|
5
6
|
export { genId } from "./helpers/gen.js";
|
|
6
7
|
export { Relation } from "./helpers/relation.js";
|
|
7
8
|
export { convertIdToUnix, sortByIds } from "./utils/id.js";
|
|
9
|
+
export type { AdapterCapabilities } from "./types/action.js";
|
|
8
10
|
export type { ValtheraTypes } from "./types/export.js";
|
|
9
11
|
export type { Id } from "./types/Id.js";
|
|
10
12
|
export type { RelationTypes } from "./types/relation.js";
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { CustomFileCpu } from "./customFileCpu.js";
|
|
2
2
|
export { createMemoryValthera, ValtheraMemory } from "./db/memory.js";
|
|
3
3
|
export { ValtheraClass } from "./db/valthera.js";
|
|
4
|
+
export * from "./errors.js";
|
|
4
5
|
export { forgeTypedValthera } from "./helpers/forge.js";
|
|
5
6
|
export { genId } from "./helpers/gen.js";
|
|
6
7
|
export { Relation } from "./helpers/relation.js";
|
package/dist/types/action.d.ts
CHANGED
|
@@ -3,10 +3,16 @@ import { Id } from "./Id.js";
|
|
|
3
3
|
import { AdapterOpts } from "./options.js";
|
|
4
4
|
import { VQueryT } from "./query.js";
|
|
5
5
|
import { TransactionHandle } from "./transaction.js";
|
|
6
|
+
export interface AdapterCapabilities {
|
|
7
|
+
transactions: boolean;
|
|
8
|
+
indexes: boolean;
|
|
9
|
+
persistent: boolean;
|
|
10
|
+
}
|
|
6
11
|
export interface ActionsBaseInterface {
|
|
7
12
|
_inited: boolean;
|
|
8
13
|
adapterOpts: AdapterOpts;
|
|
9
14
|
smartExecutor: boolean;
|
|
15
|
+
capabilities: AdapterCapabilities;
|
|
10
16
|
init(...args: any[]): Promise<void>;
|
|
11
17
|
close(...args: any[]): Promise<void>;
|
|
12
18
|
getCollections(): Promise<string[]>;
|
package/dist/types/export.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export declare namespace ValtheraTypes {
|
|
|
6
6
|
type FindOpts = import("./options.js").FindOpts;
|
|
7
7
|
type DbOpts = import("./options.js").DbOpts;
|
|
8
8
|
type AdapterOpts = import("./options.js").AdapterOpts;
|
|
9
|
+
type AdapterCapabilities = import("./action.js").AdapterCapabilities;
|
|
9
10
|
type Data = import("./data.js").Data;
|
|
10
11
|
type SearchOptions = import("./searchOpts.js").SearchOptions;
|
|
11
12
|
type Id = import("./Id.js").Id;
|
package/dist/types/valthera.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Collection } from "../helpers/collection.js";
|
|
2
|
+
import { AdapterCapabilities } from "./action.js";
|
|
2
3
|
import { Data } from "./data.js";
|
|
3
4
|
import { IndexOpts } from "./idx.js";
|
|
4
5
|
import { VQueryT } from "./query.js";
|
|
@@ -21,4 +22,5 @@ export interface ValtheraCompatible {
|
|
|
21
22
|
removeIndex(collection: string, fields: string[]): Promise<void>;
|
|
22
23
|
count(query: VQueryT.Count): Promise<number>;
|
|
23
24
|
bulkAdd<T = Data>(query: VQueryT.BulkAdd<T>): Promise<T[]>;
|
|
25
|
+
capabilities(): Promise<AdapterCapabilities>;
|
|
24
26
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { QueryValidationError } from "../errors.js";
|
|
1
2
|
import { hasFields } from "./hasFields.js";
|
|
2
3
|
import { compareIds } from "./id.js";
|
|
3
4
|
/**
|
|
@@ -5,7 +6,9 @@ import { compareIds } from "./id.js";
|
|
|
5
6
|
*/
|
|
6
7
|
export function hasFieldsAdvanced(obj, fields) {
|
|
7
8
|
if (typeof fields !== "object" || fields === null) {
|
|
8
|
-
throw new
|
|
9
|
+
throw new QueryValidationError("Fields must be an object", {
|
|
10
|
+
op: "search",
|
|
11
|
+
});
|
|
9
12
|
}
|
|
10
13
|
if (Object.keys(fields).length === 0)
|
|
11
14
|
return true;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { QueryValidationError } from "../errors.js";
|
|
1
2
|
import { _deepMerge } from "./merge.js";
|
|
2
3
|
/**
|
|
3
4
|
* Updates an object with new values.
|
|
@@ -6,7 +7,9 @@ import { _deepMerge } from "./merge.js";
|
|
|
6
7
|
*/
|
|
7
8
|
export function updateObjectAdvanced(obj, field) {
|
|
8
9
|
if (typeof field !== "object" || Array.isArray(field) || field === null)
|
|
9
|
-
throw new
|
|
10
|
+
throw new QueryValidationError("Fields must be an object", {
|
|
11
|
+
op: "update",
|
|
12
|
+
});
|
|
10
13
|
if (Object.keys(field).length === 0)
|
|
11
14
|
return;
|
|
12
15
|
const $fields = {};
|
|
@@ -97,7 +100,10 @@ function mainUpdate(obj, fields) {
|
|
|
97
100
|
}
|
|
98
101
|
if (!(key in deepObj))
|
|
99
102
|
return updater;
|
|
100
|
-
throw new
|
|
103
|
+
throw new QueryValidationError(`Cannot increment non-numeric value at key: ${key}`, {
|
|
104
|
+
op: "update",
|
|
105
|
+
key,
|
|
106
|
+
});
|
|
101
107
|
},
|
|
102
108
|
dec: (item, updater, key, deepObj) => {
|
|
103
109
|
if (typeof item === "number" && typeof updater === "number") {
|
|
@@ -105,7 +111,10 @@ function mainUpdate(obj, fields) {
|
|
|
105
111
|
}
|
|
106
112
|
if (!(key in deepObj))
|
|
107
113
|
return -updater;
|
|
108
|
-
throw new
|
|
114
|
+
throw new QueryValidationError(`Cannot decrement non-numeric value at key: ${key}`, {
|
|
115
|
+
op: "update",
|
|
116
|
+
key,
|
|
117
|
+
});
|
|
109
118
|
},
|
|
110
119
|
rename: (_, newKey, oldKey, deepObj) => {
|
|
111
120
|
if (oldKey in deepObj) {
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "0.12.
|
|
1
|
+
export declare const version = "0.12.10-alpha.0";
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = "0.12.
|
|
1
|
+
export const version = "0.12.10-alpha.0";
|