axiodb 20.6.7 → 22.1.2
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/README.md +2 -1
- package/lib/Helper/RegexGuard.helper.d.ts +85 -0
- package/lib/Helper/RegexGuard.helper.js +278 -0
- package/lib/Helper/RegexGuard.helper.js.map +1 -0
- package/lib/Helper/SafeErrorMessage.helper.d.ts +18 -0
- package/lib/Helper/SafeErrorMessage.helper.js +42 -0
- package/lib/Helper/SafeErrorMessage.helper.js.map +1 -0
- package/lib/Memory/memory.operation.d.ts +19 -7
- package/lib/Memory/memory.operation.js +32 -12
- package/lib/Memory/memory.operation.js.map +1 -1
- package/lib/Services/Aggregation/operators/expressionOperators.js +5 -1
- package/lib/Services/Aggregation/operators/expressionOperators.js.map +1 -1
- package/lib/Services/Aggregation/operators/stageOperators.js +5 -1
- package/lib/Services/Aggregation/operators/stageOperators.js.map +1 -1
- package/lib/Services/CRUD Operation/Delete.operation.d.ts +3 -1
- package/lib/Services/CRUD Operation/Delete.operation.js +4 -3
- package/lib/Services/CRUD Operation/Delete.operation.js.map +1 -1
- package/lib/Services/CRUD Operation/Reader.operation.d.ts +4 -1
- package/lib/Services/CRUD Operation/Reader.operation.js +7 -7
- package/lib/Services/CRUD Operation/Reader.operation.js.map +1 -1
- package/lib/Services/CRUD Operation/Update.operation.d.ts +3 -1
- package/lib/Services/CRUD Operation/Update.operation.js +4 -3
- package/lib/Services/CRUD Operation/Update.operation.js.map +1 -1
- package/lib/Services/Collection/collection.operation.d.ts +3 -1
- package/lib/Services/Collection/collection.operation.js +7 -6
- package/lib/Services/Collection/collection.operation.js.map +1 -1
- package/lib/Services/Database/database.operation.d.ts +3 -1
- package/lib/Services/Database/database.operation.js +5 -4
- package/lib/Services/Database/database.operation.js.map +1 -1
- package/lib/Services/Indexation.operation.d.ts +8 -0
- package/lib/Services/Indexation.operation.js +21 -5
- package/lib/Services/Indexation.operation.js.map +1 -1
- package/lib/Services/Transaction/Session.service.d.ts +3 -1
- package/lib/Services/Transaction/Session.service.js +3 -2
- package/lib/Services/Transaction/Session.service.js.map +1 -1
- package/lib/Services/Transaction/Transaction.service.d.ts +3 -1
- package/lib/Services/Transaction/Transaction.service.js +4 -4
- package/lib/Services/Transaction/Transaction.service.js.map +1 -1
- package/lib/config/Interfaces/Operation/Indexation.operation.interface.d.ts +8 -0
- package/lib/engine/Filesystem/FileManager.js +9 -3
- package/lib/engine/Filesystem/FileManager.js.map +1 -1
- package/lib/engine/Filesystem/FolderManager.js +8 -2
- package/lib/engine/Filesystem/FolderManager.js.map +1 -1
- package/lib/server/config/keys.d.ts +6 -0
- package/lib/server/config/keys.js +14 -1
- package/lib/server/config/keys.js.map +1 -1
- package/lib/server/config/server.js +5 -0
- package/lib/server/config/server.js.map +1 -1
- package/lib/server/controller/Database/Databse.controller.js +2 -1
- package/lib/server/controller/Database/Databse.controller.js.map +1 -1
- package/lib/server/controller/Stats.controller.js +1 -2
- package/lib/server/controller/Stats.controller.js.map +1 -1
- package/lib/server/router/Router.js +1 -2
- package/lib/server/router/Router.js.map +1 -1
- package/lib/tcp/config/server.js +2 -1
- package/lib/tcp/config/server.js.map +1 -1
- package/lib/tcp/connection/ConnectionManager.js +2 -1
- package/lib/tcp/connection/ConnectionManager.js.map +1 -1
- package/lib/tcp/connection/TransactionManager.d.ts +2 -1
- package/lib/tcp/connection/TransactionManager.js +2 -2
- package/lib/tcp/connection/TransactionManager.js.map +1 -1
- package/lib/tcp/handler/CommandHandler.js +3 -2
- package/lib/tcp/handler/CommandHandler.js.map +1 -1
- package/lib/tcp/handler/handlers/Collection.handler.d.ts +1 -1
- package/lib/tcp/handler/handlers/Collection.handler.js +6 -5
- package/lib/tcp/handler/handlers/Collection.handler.js.map +1 -1
- package/lib/tcp/handler/handlers/DB.handler.js +5 -4
- package/lib/tcp/handler/handlers/DB.handler.js.map +1 -1
- package/lib/tcp/handler/handlers/Operation.handler.js +3 -1
- package/lib/tcp/handler/handlers/Operation.handler.js.map +1 -1
- package/lib/tcp/handler/handlers/Transaction.handler.js +4 -2
- package/lib/tcp/handler/handlers/Transaction.handler.js.map +1 -1
- package/lib/utility/Searcher.utils.js +3 -2
- package/lib/utility/Searcher.utils.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -97,7 +97,8 @@ supported.
|
|
|
97
97
|
* **MongoDB-style queries** — `{ age: { $gt: 25 } }`, 19 operators + `hint()` + `findByIds()`
|
|
98
98
|
* **ACID transactions** — `savepoint`/`rollbackTo`/`WAL`, crashes recover via `Transaction.recoverTransactions()`
|
|
99
99
|
* **Aggregation** — 60+ stages, `$lookup` joins, `OperatorRegistry` custom ops
|
|
100
|
-
* **InMemoryCache + indexes** — dual-write, auto `IndexCache`
|
|
100
|
+
* **InMemoryCache + indexes** — per-instance cache, dual-write, auto `IndexCache`
|
|
101
|
+
* **Configurable cache** — `{ Cache, minTTL, maxTTL, cacheClearUp }` controls the per-instance InMemoryCache (default `5–15m` randomized TTL, `Cache: false` disables it) → [axiodb.in/api-reference](https://axiodb.in/api-reference)
|
|
101
102
|
* **Ports:** GUI `27018` · TCP `27019` `AxioDBCloud` · MCP `27020` Docker-only
|
|
102
103
|
|
|
103
104
|
> **Docs:** `axiodb.in` is the single source — this README is a quick start only.
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RegexGuard - Static ReDoS guard for user-supplied regex patterns.
|
|
3
|
+
*
|
|
4
|
+
* Rejects patterns that are too long, contain nested unbounded quantifiers
|
|
5
|
+
* (`(a+)+`), or have overlapping alternation branches inside an unboundedly
|
|
6
|
+
* quantified group (`(a|aa)+`). Bounded quantifiers like `{2,9}` are allowed.
|
|
7
|
+
*
|
|
8
|
+
* @class RegexGuard
|
|
9
|
+
* @example
|
|
10
|
+
* const safe = RegexGuard.compileRegex("(a+)b", "");
|
|
11
|
+
* const guarded = RegexGuard.compileRegex("(a+)+$", ""); // throws
|
|
12
|
+
*/
|
|
13
|
+
export default class RegexGuard {
|
|
14
|
+
/** Upper bound on pattern length. */
|
|
15
|
+
static readonly MAX_PATTERN_LENGTH = 512;
|
|
16
|
+
/**
|
|
17
|
+
* Compiles a user-supplied pattern into a RegExp after proving it is safe.
|
|
18
|
+
* @param pattern - The regex source to compile.
|
|
19
|
+
* @param flags - Optional regex flags (e.g. "i").
|
|
20
|
+
* @returns A compiled RegExp.
|
|
21
|
+
* @throws Error if the pattern is empty, too long, or prone to catastrophic backtracking.
|
|
22
|
+
*/
|
|
23
|
+
static compileRegex(pattern: string, flags?: string): RegExp;
|
|
24
|
+
/**
|
|
25
|
+
* Returns true when the pattern does not contain the catastrophic
|
|
26
|
+
* nested-quantifier shape. Pure check - callers decide what to do.
|
|
27
|
+
* @param pattern - The regex source to inspect.
|
|
28
|
+
* @returns true if the pattern is considered safe, false otherwise.
|
|
29
|
+
*/
|
|
30
|
+
static isSafePattern(pattern: string): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Static scan for the catastrophic-backtracking shape.
|
|
33
|
+
*
|
|
34
|
+
* Two classes are rejected:
|
|
35
|
+
* 1. Nested unbounded quantifiers: a group that contains an internally
|
|
36
|
+
* quantified atom and is itself unboundedly quantified, e.g. `(a+)+`.
|
|
37
|
+
* 2. Overlapping alternation inside an unboundedly quantified group: two
|
|
38
|
+
* branches where one is a strict prefix of another, e.g. `(a|aa)+` -
|
|
39
|
+
* the parser cannot decide where a branch ends, causing exponential work.
|
|
40
|
+
*
|
|
41
|
+
* @param pattern - The regex source to inspect.
|
|
42
|
+
* @throws Error describing the dangerous construct when detected.
|
|
43
|
+
*/
|
|
44
|
+
static assertSafePattern(pattern: string): void;
|
|
45
|
+
/**
|
|
46
|
+
* Splits a group body on top-level alternation operators and reports whether
|
|
47
|
+
* any two branches overlap, i.e. one is a strict prefix of another. Branch
|
|
48
|
+
* overlap on an unboundedly quantified group is what produces exponential
|
|
49
|
+
* backtracking in patterns like `(a|aa)+`.
|
|
50
|
+
* @param body - The characters between a group's '(' and ')'.
|
|
51
|
+
* @returns true when an overlapping branch pair is found.
|
|
52
|
+
*/
|
|
53
|
+
private static hasOverlappingAlternation;
|
|
54
|
+
/**
|
|
55
|
+
* Strips the special group marker (`?:`, `?=`, `?!`, `?<=`, `?<!`, `?<name>`)
|
|
56
|
+
* from a group body so branch analysis sees the actual alternation content.
|
|
57
|
+
* @param body - The raw text between '(' and ')'.
|
|
58
|
+
* @returns The body without its leading marker, if one was present.
|
|
59
|
+
*/
|
|
60
|
+
private static stripGroupMarker;
|
|
61
|
+
/**
|
|
62
|
+
* Splits a group body on '|' operators that are not nested inside a
|
|
63
|
+
* sub-group or character class.
|
|
64
|
+
* @param body - The group's raw body text.
|
|
65
|
+
* @returns The top-level alternation branches (at least one element).
|
|
66
|
+
*/
|
|
67
|
+
private static splitTopLevel;
|
|
68
|
+
/**
|
|
69
|
+
* Determines what kind of quantifier (if any) follows a closing parenthesis.
|
|
70
|
+
* @param pattern - The full regex source.
|
|
71
|
+
* @param closeIndex - Index of the ')' that just closed a group.
|
|
72
|
+
* @returns "none" when no quantifier follows, "unbounded" for `*`, `+`, or an
|
|
73
|
+
* open-ended `{n,}` range, otherwise "bounded".
|
|
74
|
+
*/
|
|
75
|
+
private static peekGroupQuantifier;
|
|
76
|
+
/**
|
|
77
|
+
* Parses a `{...}` quantifier starting at the given index.
|
|
78
|
+
* @param pattern - The full regex source.
|
|
79
|
+
* @param openIndex - Index of the '{'.
|
|
80
|
+
* @returns true for an unbounded `{n,}` range, false for a bounded `{n}` or
|
|
81
|
+
* `{n,m}`, and null when the character is not actually a quantifier
|
|
82
|
+
* (e.g. a literal brace inside a larger construct).
|
|
83
|
+
*/
|
|
84
|
+
private static isUnboundedRange;
|
|
85
|
+
}
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
/**
|
|
4
|
+
* RegexGuard - Static ReDoS guard for user-supplied regex patterns.
|
|
5
|
+
*
|
|
6
|
+
* Rejects patterns that are too long, contain nested unbounded quantifiers
|
|
7
|
+
* (`(a+)+`), or have overlapping alternation branches inside an unboundedly
|
|
8
|
+
* quantified group (`(a|aa)+`). Bounded quantifiers like `{2,9}` are allowed.
|
|
9
|
+
*
|
|
10
|
+
* @class RegexGuard
|
|
11
|
+
* @example
|
|
12
|
+
* const safe = RegexGuard.compileRegex("(a+)b", "");
|
|
13
|
+
* const guarded = RegexGuard.compileRegex("(a+)+$", ""); // throws
|
|
14
|
+
*/
|
|
15
|
+
class RegexGuard {
|
|
16
|
+
/**
|
|
17
|
+
* Compiles a user-supplied pattern into a RegExp after proving it is safe.
|
|
18
|
+
* @param pattern - The regex source to compile.
|
|
19
|
+
* @param flags - Optional regex flags (e.g. "i").
|
|
20
|
+
* @returns A compiled RegExp.
|
|
21
|
+
* @throws Error if the pattern is empty, too long, or prone to catastrophic backtracking.
|
|
22
|
+
*/
|
|
23
|
+
static compileRegex(pattern, flags) {
|
|
24
|
+
if (!pattern || typeof pattern !== "string") {
|
|
25
|
+
throw new Error("Invalid regex pattern: must be a non-empty string");
|
|
26
|
+
}
|
|
27
|
+
if (pattern.length > this.MAX_PATTERN_LENGTH) {
|
|
28
|
+
throw new Error(`Regex pattern exceeds maximum length of ${this.MAX_PATTERN_LENGTH}`);
|
|
29
|
+
}
|
|
30
|
+
this.assertSafePattern(pattern);
|
|
31
|
+
return new RegExp(pattern, flags || "");
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Returns true when the pattern does not contain the catastrophic
|
|
35
|
+
* nested-quantifier shape. Pure check - callers decide what to do.
|
|
36
|
+
* @param pattern - The regex source to inspect.
|
|
37
|
+
* @returns true if the pattern is considered safe, false otherwise.
|
|
38
|
+
*/
|
|
39
|
+
static isSafePattern(pattern) {
|
|
40
|
+
try {
|
|
41
|
+
this.assertSafePattern(pattern);
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
catch (_a) {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Static scan for the catastrophic-backtracking shape.
|
|
50
|
+
*
|
|
51
|
+
* Two classes are rejected:
|
|
52
|
+
* 1. Nested unbounded quantifiers: a group that contains an internally
|
|
53
|
+
* quantified atom and is itself unboundedly quantified, e.g. `(a+)+`.
|
|
54
|
+
* 2. Overlapping alternation inside an unboundedly quantified group: two
|
|
55
|
+
* branches where one is a strict prefix of another, e.g. `(a|aa)+` -
|
|
56
|
+
* the parser cannot decide where a branch ends, causing exponential work.
|
|
57
|
+
*
|
|
58
|
+
* @param pattern - The regex source to inspect.
|
|
59
|
+
* @throws Error describing the dangerous construct when detected.
|
|
60
|
+
*/
|
|
61
|
+
static assertSafePattern(pattern) {
|
|
62
|
+
let inClass = false;
|
|
63
|
+
let escaped = false;
|
|
64
|
+
// Stack of currently-open groups; each tracks whether it contains an
|
|
65
|
+
// internally quantified atom and where it opened (for branch analysis).
|
|
66
|
+
const groups = [];
|
|
67
|
+
for (let i = 0; i < pattern.length; i++) {
|
|
68
|
+
const c = pattern[i];
|
|
69
|
+
if (escaped) {
|
|
70
|
+
escaped = false;
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
if (c === "\\") {
|
|
74
|
+
escaped = true;
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
// Inside a character class like [abc+]: '+' is a literal there, not a quantifier.
|
|
78
|
+
if (inClass) {
|
|
79
|
+
if (c === "]")
|
|
80
|
+
inClass = false;
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
if (c === "[") {
|
|
84
|
+
inClass = true;
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
if (c === "(") {
|
|
88
|
+
groups.push({ openIndex: i, hasQuantifiedAtom: false });
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
if (c === ")") {
|
|
92
|
+
const group = groups.pop();
|
|
93
|
+
if (!group)
|
|
94
|
+
continue;
|
|
95
|
+
const quantifier = this.peekGroupQuantifier(pattern, i);
|
|
96
|
+
const isUnbounded = quantifier === "unbounded";
|
|
97
|
+
if (isUnbounded) {
|
|
98
|
+
if (group.hasQuantifiedAtom) {
|
|
99
|
+
throw new Error("Regex pattern rejected: contains nested quantifiers that can cause catastrophic backtracking");
|
|
100
|
+
}
|
|
101
|
+
const body = pattern.slice(group.openIndex + 1, i);
|
|
102
|
+
if (this.hasOverlappingAlternation(this.stripGroupMarker(body))) {
|
|
103
|
+
throw new Error("Regex pattern rejected: quantified alternation with overlapping branches can cause catastrophic backtracking");
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
// A quantified group, or a group containing quantified atoms, is itself
|
|
107
|
+
// a quantified atom to its parent group.
|
|
108
|
+
const isQuantifiedAtom = group.hasQuantifiedAtom || isUnbounded;
|
|
109
|
+
if (isQuantifiedAtom && groups.length > 0) {
|
|
110
|
+
groups[groups.length - 1].hasQuantifiedAtom = true;
|
|
111
|
+
}
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
// Track unbounded quantifiers (+ or * or {n,}): the atom before them is a
|
|
115
|
+
// quantified atom. '?' is deliberately excluded - a single optional atom
|
|
116
|
+
// cannot blow up on its own. `{m}` bounded and `{m,n}` bounded are also excluded.
|
|
117
|
+
let isUnbounded = false;
|
|
118
|
+
if (c === "+" || c === "*") {
|
|
119
|
+
isUnbounded = true;
|
|
120
|
+
}
|
|
121
|
+
else if (c === "{") {
|
|
122
|
+
isUnbounded = this.isUnboundedRange(pattern, i) === true;
|
|
123
|
+
}
|
|
124
|
+
if (isUnbounded && groups.length > 0) {
|
|
125
|
+
groups[groups.length - 1].hasQuantifiedAtom = true;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Splits a group body on top-level alternation operators and reports whether
|
|
131
|
+
* any two branches overlap, i.e. one is a strict prefix of another. Branch
|
|
132
|
+
* overlap on an unboundedly quantified group is what produces exponential
|
|
133
|
+
* backtracking in patterns like `(a|aa)+`.
|
|
134
|
+
* @param body - The characters between a group's '(' and ')'.
|
|
135
|
+
* @returns true when an overlapping branch pair is found.
|
|
136
|
+
*/
|
|
137
|
+
static hasOverlappingAlternation(body) {
|
|
138
|
+
const branches = this.splitTopLevel(body);
|
|
139
|
+
if (branches.length < 2)
|
|
140
|
+
return false;
|
|
141
|
+
for (let i = 0; i < branches.length; i++) {
|
|
142
|
+
for (let j = 0; j < branches.length; j++) {
|
|
143
|
+
if (i === j)
|
|
144
|
+
continue;
|
|
145
|
+
const a = branches[i];
|
|
146
|
+
const b = branches[j];
|
|
147
|
+
// An empty branch can match zero width, so no line is consumed - the
|
|
148
|
+
// classic `(|x)+` / `(a|)+` ambiguity.
|
|
149
|
+
if (a === "" || b === "")
|
|
150
|
+
return true;
|
|
151
|
+
if (b.length > a.length && b.startsWith(a))
|
|
152
|
+
return true;
|
|
153
|
+
if (a.length > b.length && a.startsWith(b))
|
|
154
|
+
return true;
|
|
155
|
+
if (a === b)
|
|
156
|
+
return true; // duplicate branches are always ambiguous
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Strips the special group marker (`?:`, `?=`, `?!`, `?<=`, `?<!`, `?<name>`)
|
|
163
|
+
* from a group body so branch analysis sees the actual alternation content.
|
|
164
|
+
* @param body - The raw text between '(' and ')'.
|
|
165
|
+
* @returns The body without its leading marker, if one was present.
|
|
166
|
+
*/
|
|
167
|
+
static stripGroupMarker(body) {
|
|
168
|
+
if (body[0] === "?" && body[1] === "<") {
|
|
169
|
+
const close = body.indexOf(">");
|
|
170
|
+
return close >= 0 ? body.slice(close + 1) : body;
|
|
171
|
+
}
|
|
172
|
+
if (body[0] === "?" && (body[1] === ":" || body[1] === "=" || body[1] === "!")) {
|
|
173
|
+
return body.slice(2);
|
|
174
|
+
}
|
|
175
|
+
return body;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Splits a group body on '|' operators that are not nested inside a
|
|
179
|
+
* sub-group or character class.
|
|
180
|
+
* @param body - The group's raw body text.
|
|
181
|
+
* @returns The top-level alternation branches (at least one element).
|
|
182
|
+
*/
|
|
183
|
+
static splitTopLevel(body) {
|
|
184
|
+
const branches = [];
|
|
185
|
+
let depth = 0;
|
|
186
|
+
let inClass = false;
|
|
187
|
+
let escaped = false;
|
|
188
|
+
let current = "";
|
|
189
|
+
for (const c of body) {
|
|
190
|
+
if (escaped) {
|
|
191
|
+
escaped = false;
|
|
192
|
+
current += c;
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
if (c === "\\") {
|
|
196
|
+
escaped = true;
|
|
197
|
+
current += c;
|
|
198
|
+
continue;
|
|
199
|
+
}
|
|
200
|
+
if (inClass) {
|
|
201
|
+
current += c;
|
|
202
|
+
if (c === "]")
|
|
203
|
+
inClass = false;
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
if (c === "[") {
|
|
207
|
+
inClass = true;
|
|
208
|
+
current += c;
|
|
209
|
+
continue;
|
|
210
|
+
}
|
|
211
|
+
if (c === "(") {
|
|
212
|
+
depth++;
|
|
213
|
+
current += c;
|
|
214
|
+
continue;
|
|
215
|
+
}
|
|
216
|
+
if (c === ")") {
|
|
217
|
+
depth--;
|
|
218
|
+
current += c;
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
221
|
+
if (c === "|" && depth === 0) {
|
|
222
|
+
branches.push(current);
|
|
223
|
+
current = "";
|
|
224
|
+
continue;
|
|
225
|
+
}
|
|
226
|
+
current += c;
|
|
227
|
+
}
|
|
228
|
+
branches.push(current);
|
|
229
|
+
return branches;
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Determines what kind of quantifier (if any) follows a closing parenthesis.
|
|
233
|
+
* @param pattern - The full regex source.
|
|
234
|
+
* @param closeIndex - Index of the ')' that just closed a group.
|
|
235
|
+
* @returns "none" when no quantifier follows, "unbounded" for `*`, `+`, or an
|
|
236
|
+
* open-ended `{n,}` range, otherwise "bounded".
|
|
237
|
+
*/
|
|
238
|
+
static peekGroupQuantifier(pattern, closeIndex) {
|
|
239
|
+
const next = pattern[closeIndex + 1];
|
|
240
|
+
if (next === "*" || next === "+")
|
|
241
|
+
return "unbounded";
|
|
242
|
+
if (next === "{") {
|
|
243
|
+
const bounded = this.isUnboundedRange(pattern, closeIndex + 1);
|
|
244
|
+
return bounded === true ? "unbounded" : bounded === false ? "bounded" : "none";
|
|
245
|
+
}
|
|
246
|
+
if (next === "?")
|
|
247
|
+
return "bounded";
|
|
248
|
+
return "none";
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Parses a `{...}` quantifier starting at the given index.
|
|
252
|
+
* @param pattern - The full regex source.
|
|
253
|
+
* @param openIndex - Index of the '{'.
|
|
254
|
+
* @returns true for an unbounded `{n,}` range, false for a bounded `{n}` or
|
|
255
|
+
* `{n,m}`, and null when the character is not actually a quantifier
|
|
256
|
+
* (e.g. a literal brace inside a larger construct).
|
|
257
|
+
*/
|
|
258
|
+
static isUnboundedRange(pattern, openIndex) {
|
|
259
|
+
let closeIndex = openIndex + 1;
|
|
260
|
+
while (closeIndex < pattern.length && pattern[closeIndex] !== "}") {
|
|
261
|
+
closeIndex++;
|
|
262
|
+
}
|
|
263
|
+
if (closeIndex >= pattern.length)
|
|
264
|
+
return null;
|
|
265
|
+
const body = pattern.slice(openIndex + 1, closeIndex);
|
|
266
|
+
if (/^\d+$/.test(body))
|
|
267
|
+
return false;
|
|
268
|
+
if (/^\d+,\d+$/.test(body))
|
|
269
|
+
return false;
|
|
270
|
+
if (/^\d+,$/.test(body))
|
|
271
|
+
return true;
|
|
272
|
+
return null;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
/** Upper bound on pattern length. */
|
|
276
|
+
RegexGuard.MAX_PATTERN_LENGTH = 512;
|
|
277
|
+
exports.default = RegexGuard;
|
|
278
|
+
//# sourceMappingURL=RegexGuard.helper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RegexGuard.helper.js","sourceRoot":"","sources":["../../source/Helper/RegexGuard.helper.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SafeErrorMessage - Redacts filesystem paths and internal details from error
|
|
3
|
+
* messages before they are returned to remote clients.
|
|
4
|
+
* @class SafeErrorMessage
|
|
5
|
+
* @example
|
|
6
|
+
* SafeErrorMessage.sanitize(new Error("open '/home/user/db'"));
|
|
7
|
+
* // 'open <path>'
|
|
8
|
+
*/
|
|
9
|
+
export default class SafeErrorMessage {
|
|
10
|
+
static readonly MAX_MESSAGE_LENGTH = 300;
|
|
11
|
+
static readonly FALLBACK_MESSAGE = "An internal error occurred. Please try again later.";
|
|
12
|
+
/**
|
|
13
|
+
* Sanitizes an error for transmission to a remote client.
|
|
14
|
+
* @param error - The caught error (may be any unknown).
|
|
15
|
+
* @returns A single-line, path-redacted message with a bounded length.
|
|
16
|
+
*/
|
|
17
|
+
static sanitize(error: unknown): string;
|
|
18
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
/**
|
|
4
|
+
* SafeErrorMessage - Redacts filesystem paths and internal details from error
|
|
5
|
+
* messages before they are returned to remote clients.
|
|
6
|
+
* @class SafeErrorMessage
|
|
7
|
+
* @example
|
|
8
|
+
* SafeErrorMessage.sanitize(new Error("open '/home/user/db'"));
|
|
9
|
+
* // 'open <path>'
|
|
10
|
+
*/
|
|
11
|
+
class SafeErrorMessage {
|
|
12
|
+
/**
|
|
13
|
+
* Sanitizes an error for transmission to a remote client.
|
|
14
|
+
* @param error - The caught error (may be any unknown).
|
|
15
|
+
* @returns A single-line, path-redacted message with a bounded length.
|
|
16
|
+
*/
|
|
17
|
+
static sanitize(error) {
|
|
18
|
+
const raw = error instanceof Error
|
|
19
|
+
? error.message
|
|
20
|
+
: typeof error === "string"
|
|
21
|
+
? error
|
|
22
|
+
: error !== undefined
|
|
23
|
+
? String(error)
|
|
24
|
+
: "";
|
|
25
|
+
let message = raw;
|
|
26
|
+
message = message.replace(/[a-zA-Z]:\\[^\s"'`]+/g, "<path>");
|
|
27
|
+
message = message.replace(/(^|[\s(['"`])[\/][^\s"'`]+/g, "$1<path>");
|
|
28
|
+
message = message.replace(/(^|[\s(['"`])(?:\.\.?(?:[\/\\]|$))[^\s"'`]*/g, "$1<path>");
|
|
29
|
+
message = message.replace(/['"`]\s*<path>\s*['"`]/g, "<path>");
|
|
30
|
+
message = message.replace(/\r?\n/g, " | ").replace(/\s{2,}/g, " ").trim();
|
|
31
|
+
if (!message || message === "<path>")
|
|
32
|
+
return this.FALLBACK_MESSAGE;
|
|
33
|
+
if (message.length > this.MAX_MESSAGE_LENGTH) {
|
|
34
|
+
message = message.slice(0, this.MAX_MESSAGE_LENGTH - 3) + "...";
|
|
35
|
+
}
|
|
36
|
+
return message;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
SafeErrorMessage.MAX_MESSAGE_LENGTH = 300;
|
|
40
|
+
SafeErrorMessage.FALLBACK_MESSAGE = "An internal error occurred. Please try again later.";
|
|
41
|
+
exports.default = SafeErrorMessage;
|
|
42
|
+
//# sourceMappingURL=SafeErrorMessage.helper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SafeErrorMessage.helper.js","sourceRoot":"","sources":["../../source/Helper/SafeErrorMessage.helper.ts"],"names":[],"mappings":";;AAAA;;;;;;;GAOG;AACH,MAAqB,gBAAgB;IAKnC;;;;OAIG;IACH,MAAM,CAAC,QAAQ,CAAC,KAAc;QAC5B,MAAM,GAAG,GACP,KAAK,YAAY,KAAK;YACpB,CAAC,CAAC,KAAK,CAAC,OAAO;YACf,CAAC,CAAC,OAAO,KAAK,KAAK,QAAQ;gBACzB,CAAC,CAAC,KAAK;gBACP,CAAC,CAAC,KAAK,KAAK,SAAS;oBACnB,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;oBACf,CAAC,CAAC,EAAE,CAAC;QAEb,IAAI,OAAO,GAAG,GAAG,CAAC;QAClB,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,uBAAuB,EAAE,QAAQ,CAAC,CAAC;QAC7D,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,6BAA6B,EAAE,UAAU,CAAC,CAAC;QACrE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,8CAA8C,EAAE,UAAU,CAAC,CAAC;QACtF,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,yBAAyB,EAAE,QAAQ,CAAC,CAAC;QAC/D,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;QAE1E,IAAI,CAAC,OAAO,IAAI,OAAO,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC,gBAAgB,CAAC;QAEnE,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC7C,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,kBAAkB,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC;QAClE,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;;AAhCe,mCAAkB,GAAG,GAAG,CAAC;AAEzB,iCAAgB,GAAG,qDAAqD,CAAC;kBAHtE,gBAAgB"}
|
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
export interface InMemoryCacheOptions {
|
|
2
|
+
/** When false the cache stores nothing and every lookup misses. Defaults to true. */
|
|
3
|
+
enabled?: boolean;
|
|
4
|
+
/** Minimum entry lifetime in minutes. Defaults to 5. */
|
|
5
|
+
minTTL?: number;
|
|
6
|
+
/** Maximum entry lifetime in minutes. Defaults to 15. */
|
|
7
|
+
maxTTL?: number;
|
|
8
|
+
/** Housekeeping cleanup cadence and search-query retention, in seconds. Defaults to 86400 (24 hours). */
|
|
9
|
+
cacheClearUp?: number;
|
|
10
|
+
}
|
|
1
11
|
/**
|
|
2
12
|
* Caches data in memory with smart TTL management:
|
|
3
13
|
* - Random TTL per entry (5-15 minutes) to prevent cache stampede
|
|
@@ -5,15 +15,19 @@
|
|
|
5
15
|
* - Auto-cleanup of expired entries
|
|
6
16
|
*/
|
|
7
17
|
export declare class InMemoryCache {
|
|
8
|
-
private readonly
|
|
18
|
+
private readonly enabled;
|
|
19
|
+
private readonly minTTL;
|
|
20
|
+
private readonly maxTTL;
|
|
21
|
+
private readonly cacheClearUp;
|
|
9
22
|
private cacheObject;
|
|
10
23
|
private tempSearchQuery;
|
|
11
|
-
private readonly autoResetCacheInterval;
|
|
12
24
|
private documentIndex;
|
|
13
|
-
/** @param TTL - Time to live in seconds for cache entries. Defaults to 86400 seconds (24 hours) */
|
|
14
|
-
constructor(TTL?: string | number);
|
|
15
25
|
/**
|
|
16
|
-
*
|
|
26
|
+
* @param TTL - InMemoryCacheOptions, or a legacy numeric/string value treated as `cacheClearUp`.
|
|
27
|
+
*/
|
|
28
|
+
constructor(TTL?: string | number | InMemoryCacheOptions);
|
|
29
|
+
/**
|
|
30
|
+
* Generates a random TTL between minTTL and maxTTL
|
|
17
31
|
* This prevents cache stampede (thundering herd problem)
|
|
18
32
|
*
|
|
19
33
|
* @returns Random TTL in milliseconds
|
|
@@ -79,5 +93,3 @@ export declare class InMemoryCache {
|
|
|
79
93
|
/** Periodically evicts expired cache entries and old search-query tracking. */
|
|
80
94
|
private autoResetCache;
|
|
81
95
|
}
|
|
82
|
-
declare const _default: InMemoryCache;
|
|
83
|
-
export default _default;
|
|
@@ -22,29 +22,41 @@ const Logger_helper_1 = __importDefault(require("../Helper/Logger.helper"));
|
|
|
22
22
|
* - Auto-cleanup of expired entries
|
|
23
23
|
*/
|
|
24
24
|
class InMemoryCache {
|
|
25
|
-
/**
|
|
26
|
-
|
|
25
|
+
/**
|
|
26
|
+
* @param TTL - InMemoryCacheOptions, or a legacy numeric/string value treated as `cacheClearUp`.
|
|
27
|
+
*/
|
|
28
|
+
constructor(TTL = {}) {
|
|
29
|
+
var _a, _b, _c, _d;
|
|
27
30
|
this.tempSearchQuery = [];
|
|
28
|
-
this.autoResetCacheInterval = 86400; // 24 hours
|
|
29
31
|
// Reverse index: "{collectionPath}::{documentId}" -> cache keys whose cached result contains that document.
|
|
30
32
|
// Lets invalidateByDocument(s) evict only the affected entries instead of the whole collection's cache.
|
|
31
33
|
this.documentIndex = new Map();
|
|
32
|
-
|
|
34
|
+
const options = typeof TTL === "object" ? TTL : { cacheClearUp: Number(TTL) || undefined };
|
|
35
|
+
const minMinutes = (_a = options.minTTL) !== null && _a !== void 0 ? _a : 5;
|
|
36
|
+
const maxMinutes = (_b = options.maxTTL) !== null && _b !== void 0 ? _b : 15;
|
|
37
|
+
if (typeof minMinutes !== "number" || typeof maxMinutes !== "number" || minMinutes <= 0 || maxMinutes <= 0 || maxMinutes < minMinutes) {
|
|
38
|
+
throw new Error("Invalid cache TTL: minTTL and maxTTL must be positive minutes and maxTTL must be >= minTTL.");
|
|
39
|
+
}
|
|
40
|
+
this.cacheClearUp = (_c = options.cacheClearUp) !== null && _c !== void 0 ? _c : 86400;
|
|
41
|
+
if (typeof this.cacheClearUp !== "number" || this.cacheClearUp <= 0) {
|
|
42
|
+
throw new Error("cacheClearUp must be a positive number of seconds.");
|
|
43
|
+
}
|
|
44
|
+
this.enabled = (_d = options.enabled) !== null && _d !== void 0 ? _d : true;
|
|
45
|
+
this.minTTL = minMinutes * 60 * 1000;
|
|
46
|
+
this.maxTTL = maxMinutes * 60 * 1000;
|
|
33
47
|
this.cacheObject = new Map();
|
|
34
48
|
this.tempSearchQuery = [];
|
|
35
49
|
this.autoResetCache();
|
|
36
50
|
}
|
|
37
51
|
/**
|
|
38
|
-
* Generates a random TTL between
|
|
52
|
+
* Generates a random TTL between minTTL and maxTTL
|
|
39
53
|
* This prevents cache stampede (thundering herd problem)
|
|
40
54
|
*
|
|
41
55
|
* @returns Random TTL in milliseconds
|
|
42
56
|
* @private
|
|
43
57
|
*/
|
|
44
58
|
generateRandomTTL() {
|
|
45
|
-
|
|
46
|
-
const MAX_TTL = 15 * 60 * 1000; // 15 minutes in milliseconds
|
|
47
|
-
return Math.floor(Math.random() * (MAX_TTL - MIN_TTL + 1)) + MIN_TTL;
|
|
59
|
+
return Math.floor(Math.random() * (this.maxTTL - this.minTTL + 1)) + this.minTTL;
|
|
48
60
|
}
|
|
49
61
|
/**
|
|
50
62
|
* Each cache entry gets its own random TTL (5-15 minutes) to prevent cache stampede
|
|
@@ -58,6 +70,9 @@ class InMemoryCache {
|
|
|
58
70
|
*/
|
|
59
71
|
setCache(key, value, collectionPath) {
|
|
60
72
|
return __awaiter(this, void 0, void 0, function* () {
|
|
73
|
+
if (!this.enabled) {
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
61
76
|
const ttl = this.generateRandomTTL();
|
|
62
77
|
const now = new Date();
|
|
63
78
|
const expiresAt = new Date(now.getTime() + ttl);
|
|
@@ -112,6 +127,9 @@ class InMemoryCache {
|
|
|
112
127
|
/** Tracked for analytics/monitoring only - does not gate or block caching. */
|
|
113
128
|
setTempSearchQuery(queryString) {
|
|
114
129
|
return __awaiter(this, void 0, void 0, function* () {
|
|
130
|
+
if (!this.enabled) {
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
115
133
|
this.tempSearchQuery.push({
|
|
116
134
|
queryString: queryString,
|
|
117
135
|
registeredAt: new Date(),
|
|
@@ -128,6 +146,9 @@ class InMemoryCache {
|
|
|
128
146
|
*/
|
|
129
147
|
getCache(key) {
|
|
130
148
|
return __awaiter(this, void 0, void 0, function* () {
|
|
149
|
+
if (!this.enabled) {
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
131
152
|
const cacheItem = this.cacheObject.get(key);
|
|
132
153
|
if (!cacheItem) {
|
|
133
154
|
return false;
|
|
@@ -256,12 +277,12 @@ class InMemoryCache {
|
|
|
256
277
|
}
|
|
257
278
|
}
|
|
258
279
|
keysToDelete.forEach(key => this.evictCacheEntry(key));
|
|
259
|
-
//
|
|
280
|
+
// cacheClearUp retention for temp search queries
|
|
260
281
|
this.tempSearchQuery = this.tempSearchQuery.filter((item) => {
|
|
261
282
|
const diff = Math.abs(now.getTime() - item.registeredAt.getTime());
|
|
262
|
-
return diff < this.
|
|
283
|
+
return diff < this.cacheClearUp * 1000;
|
|
263
284
|
});
|
|
264
|
-
}, parseInt(String(this.
|
|
285
|
+
}, parseInt(String(this.cacheClearUp)));
|
|
265
286
|
// Background housekeeping must never be the reason a short-lived script or CLI
|
|
266
287
|
// tool (a stated core use case) can't exit on its own - same reasoning as
|
|
267
288
|
// IndexCache's cleanup interval.
|
|
@@ -272,5 +293,4 @@ class InMemoryCache {
|
|
|
272
293
|
}
|
|
273
294
|
}
|
|
274
295
|
exports.InMemoryCache = InMemoryCache;
|
|
275
|
-
exports.default = new InMemoryCache(86400); // 24 hours
|
|
276
296
|
//# sourceMappingURL=memory.operation.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory.operation.js","sourceRoot":"","sources":["../../source/Memory/memory.operation.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,4CAAoB;AACpB,4EAA6C;
|
|
1
|
+
{"version":3,"file":"memory.operation.js","sourceRoot":"","sources":["../../source/Memory/memory.operation.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.getNestedValue = getNestedValue;
|
|
4
7
|
exports.setNestedValue = setNestedValue;
|
|
5
8
|
exports.evaluateExpression = evaluateExpression;
|
|
9
|
+
const RegexGuard_helper_1 = __importDefault(require("../../../Helper/RegexGuard.helper"));
|
|
6
10
|
function getNestedValue(obj, path) {
|
|
7
11
|
if (!path || !obj)
|
|
8
12
|
return undefined;
|
|
@@ -153,7 +157,7 @@ function evaluateExpression(doc, expr) {
|
|
|
153
157
|
case "$regexMatch": {
|
|
154
158
|
const input = exprObj.$regexMatch;
|
|
155
159
|
const str = String(evaluateExpression(doc, input.input));
|
|
156
|
-
const regex =
|
|
160
|
+
const regex = RegexGuard_helper_1.default.compileRegex(input.regex, input.options || "");
|
|
157
161
|
return regex.test(str);
|
|
158
162
|
}
|
|
159
163
|
case "$cmp": {
|