@freshguard/freshguard-core 0.17.4 → 0.18.1
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/CHANGELOG.md +14 -1
- package/README.md +2 -0
- package/SKILL.md +31 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/monitor/index.d.ts +2 -0
- package/dist/monitor/index.d.ts.map +1 -1
- package/dist/monitor/index.js +2 -0
- package/dist/monitor/index.js.map +1 -1
- package/dist/monitor/volume-threshold.d.ts +44 -0
- package/dist/monitor/volume-threshold.d.ts.map +1 -0
- package/dist/monitor/volume-threshold.js +148 -0
- package/dist/monitor/volume-threshold.js.map +1 -0
- package/dist/types/connector.js +5 -5
- package/dist/types/connector.js.map +1 -1
- package/dist/types.d.ts +3 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.18.1] - 2026-02-18
|
|
11
|
+
|
|
12
|
+
### Security
|
|
13
|
+
- Bump `fast-xml-parser` override from 5.3.4 → 5.3.6 to fix high-severity DoS vulnerability via DOCTYPE entity expansion (GHSA-jmr7-xgp7-cmfj)
|
|
14
|
+
|
|
15
|
+
## [0.18.0] - 2026-02-17
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
- **Volume threshold monitoring** (`checkVolumeThreshold`) — simple min/max row count alerting without historical baselines (#65)
|
|
19
|
+
- `volume_threshold` added to `RuleType` union
|
|
20
|
+
- `minRowThreshold` and `maxRowThreshold` fields on `MonitoringRule`
|
|
21
|
+
|
|
10
22
|
## [0.17.0] - 2026-02-16
|
|
11
23
|
|
|
12
24
|
### Added
|
|
@@ -179,7 +191,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
179
191
|
- Drizzle ORM database schema and migrations
|
|
180
192
|
- MIT license
|
|
181
193
|
|
|
182
|
-
[Unreleased]: https://github.com/freshguard-dev/freshguard-core/compare/v0.
|
|
194
|
+
[Unreleased]: https://github.com/freshguard-dev/freshguard-core/compare/v0.18.0...HEAD
|
|
195
|
+
[0.18.0]: https://github.com/freshguard-dev/freshguard-core/compare/v0.17.0...v0.18.0
|
|
183
196
|
[0.15.0]: https://github.com/freshguard-dev/freshguard-core/compare/v0.12.0...v0.15.0
|
|
184
197
|
[0.12.0]: https://github.com/freshguard-dev/freshguard-core/compare/v0.11.3...v0.12.0
|
|
185
198
|
[0.11.3]: https://github.com/freshguard-dev/freshguard-core/compare/v0.11.2...v0.11.3
|
package/README.md
CHANGED
|
@@ -52,6 +52,7 @@ if (result.status === 'alert') {
|
|
|
52
52
|
|
|
53
53
|
- **Freshness monitoring** — Alert when a table hasn't been updated within a tolerance window
|
|
54
54
|
- **Volume anomaly detection** — Alert when row counts deviate from a calculated baseline
|
|
55
|
+
- **Volume threshold monitoring** — Alert when row counts fall below a minimum or exceed a maximum
|
|
55
56
|
- **Schema change detection** — Alert when columns are added, removed, or modified
|
|
56
57
|
|
|
57
58
|
## API at a glance
|
|
@@ -62,6 +63,7 @@ if (result.status === 'alert') {
|
|
|
62
63
|
|---|---|
|
|
63
64
|
| `checkFreshness(connector, rule)` | Returns `'alert'` when `MAX(timestampColumn)` exceeds `toleranceMinutes` |
|
|
64
65
|
| `checkVolumeAnomaly(connector, rule)` | Returns `'alert'` when current row count deviates from the historical baseline |
|
|
66
|
+
| `checkVolumeThreshold(connector, rule)` | Returns `'alert'` when row count is below `minRowThreshold` or above `maxRowThreshold` |
|
|
65
67
|
| `checkSchemaChanges(connector, rule)` | Returns `'alert'` when columns are added, removed, or modified |
|
|
66
68
|
|
|
67
69
|
### Connectors
|
package/SKILL.md
CHANGED
|
@@ -104,7 +104,37 @@ if (result.status === 'alert') {
|
|
|
104
104
|
}
|
|
105
105
|
```
|
|
106
106
|
|
|
107
|
-
### 3.
|
|
107
|
+
### 3. Check volume thresholds (simple min/max)
|
|
108
|
+
|
|
109
|
+
Alert when a table's row count falls below a minimum or exceeds a maximum — no historical baseline needed.
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
import { checkVolumeThreshold, PostgresConnector } from '@freshguard/freshguard-core';
|
|
113
|
+
|
|
114
|
+
const connector = new PostgresConnector({ /* ... */ });
|
|
115
|
+
|
|
116
|
+
const rule = {
|
|
117
|
+
id: 'orders-threshold',
|
|
118
|
+
sourceId: 'prod_pg',
|
|
119
|
+
name: 'Orders Threshold',
|
|
120
|
+
tableName: 'orders',
|
|
121
|
+
ruleType: 'volume_threshold' as const,
|
|
122
|
+
minRowThreshold: 100, // alert if fewer than 100 rows
|
|
123
|
+
maxRowThreshold: 10_000_000, // alert if more than 10M rows
|
|
124
|
+
checkIntervalMinutes: 60,
|
|
125
|
+
isActive: true,
|
|
126
|
+
createdAt: new Date(),
|
|
127
|
+
updatedAt: new Date(),
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
const result = await checkVolumeThreshold(connector, rule);
|
|
131
|
+
|
|
132
|
+
if (result.status === 'alert') {
|
|
133
|
+
console.log(`Threshold breach: ${result.error}`);
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### 4. Detect schema changes
|
|
108
138
|
|
|
109
139
|
Alert when columns are added, removed, or modified.
|
|
110
140
|
|
package/dist/index.d.ts
CHANGED
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
* @license MIT
|
|
30
30
|
* @see {@link https://freshguard-dev.github.io/freshguard-core | Documentation}
|
|
31
31
|
*/
|
|
32
|
-
export { checkFreshness, checkVolumeAnomaly, checkSchemaChanges } from './monitor/index.js';
|
|
32
|
+
export { checkFreshness, checkVolumeAnomaly, checkVolumeThreshold, checkSchemaChanges } from './monitor/index.js';
|
|
33
33
|
export { PostgresConnector, DuckDBConnector, BigQueryConnector, SnowflakeConnector, MySQLConnector, RedshiftConnector, MSSQLConnector, AzureSQLConnector, SynapseConnector } from './connectors/index.js';
|
|
34
34
|
export { createDatabase, schema } from './db/index.js';
|
|
35
35
|
export type { Database } from './db/index.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAGH,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAGH,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAGlH,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,cAAc,EAAE,iBAAiB,EAAE,cAAc,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAG1M,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvD,YAAY,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAG9C,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAC9G,YAAY,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAGlF,OAAO,EACL,eAAe,EACf,aAAa,EACb,eAAe,EACf,YAAY,EACZ,UAAU,EACV,kBAAkB,EAClB,eAAe,EACf,YAAY,EACZ,WAAW,EACZ,MAAM,mBAAmB,CAAC;AAG3B,YAAY,EACV,UAAU,EACV,cAAc,EACd,WAAW,EACX,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,QAAQ,EACR,WAAW,EACX,oBAAoB,EACpB,gBAAgB,EAChB,aAAa,EACb,YAAY,EACZ,cAAc,GACf,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
* @see {@link https://freshguard-dev.github.io/freshguard-core | Documentation}
|
|
31
31
|
*/
|
|
32
32
|
// Monitoring functions
|
|
33
|
-
export { checkFreshness, checkVolumeAnomaly, checkSchemaChanges } from './monitor/index.js';
|
|
33
|
+
export { checkFreshness, checkVolumeAnomaly, checkVolumeThreshold, checkSchemaChanges } from './monitor/index.js';
|
|
34
34
|
// Database connectors
|
|
35
35
|
export { PostgresConnector, DuckDBConnector, BigQueryConnector, SnowflakeConnector, MySQLConnector, RedshiftConnector, MSSQLConnector, AzureSQLConnector, SynapseConnector } from './connectors/index.js';
|
|
36
36
|
// Database utilities
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,uBAAuB;AACvB,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,uBAAuB;AACvB,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAElH,sBAAsB;AACtB,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,cAAc,EAAE,iBAAiB,EAAE,cAAc,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE1M,qBAAqB;AACrB,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAGvD,mBAAmB;AACnB,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAG9G,gBAAgB;AAChB,OAAO,EACL,eAAe,EACf,aAAa,EACb,eAAe,EACf,YAAY,EACZ,UAAU,EACV,kBAAkB,EAClB,eAAe,EACf,YAAY,EACZ,WAAW,EACZ,MAAM,mBAAmB,CAAC"}
|
package/dist/monitor/index.d.ts
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* |------------------------|----------------------------------------------|
|
|
8
8
|
* | `checkFreshness` | Stale data — table not updated within SLA |
|
|
9
9
|
* | `checkVolumeAnomaly` | Row-count spikes or drops vs. historical baseline |
|
|
10
|
+
* | `checkVolumeThreshold` | Row count outside static min/max bounds |
|
|
10
11
|
* | `checkSchemaChanges` | Added, removed, or modified columns |
|
|
11
12
|
*
|
|
12
13
|
* All three accept a {@link Connector} and a {@link MonitoringRule}, returning
|
|
@@ -29,6 +30,7 @@
|
|
|
29
30
|
*/
|
|
30
31
|
export { checkFreshness } from './freshness.js';
|
|
31
32
|
export { checkVolumeAnomaly } from './volume.js';
|
|
33
|
+
export { checkVolumeThreshold } from './volume-threshold.js';
|
|
32
34
|
export { checkSchemaChanges } from './schema-changes.js';
|
|
33
35
|
export { SchemaBaselineManager, SchemaComparer } from './schema-baseline.js';
|
|
34
36
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/monitor/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/monitor/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC"}
|
package/dist/monitor/index.js
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* |------------------------|----------------------------------------------|
|
|
8
8
|
* | `checkFreshness` | Stale data — table not updated within SLA |
|
|
9
9
|
* | `checkVolumeAnomaly` | Row-count spikes or drops vs. historical baseline |
|
|
10
|
+
* | `checkVolumeThreshold` | Row count outside static min/max bounds |
|
|
10
11
|
* | `checkSchemaChanges` | Added, removed, or modified columns |
|
|
11
12
|
*
|
|
12
13
|
* All three accept a {@link Connector} and a {@link MonitoringRule}, returning
|
|
@@ -29,6 +30,7 @@
|
|
|
29
30
|
*/
|
|
30
31
|
export { checkFreshness } from './freshness.js';
|
|
31
32
|
export { checkVolumeAnomaly } from './volume.js';
|
|
33
|
+
export { checkVolumeThreshold } from './volume-threshold.js';
|
|
32
34
|
export { checkSchemaChanges } from './schema-changes.js';
|
|
33
35
|
export { SchemaBaselineManager, SchemaComparer } from './schema-baseline.js';
|
|
34
36
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/monitor/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/monitor/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple volume threshold check
|
|
3
|
+
* Alerts when row count falls below a minimum or exceeds a maximum threshold.
|
|
4
|
+
*
|
|
5
|
+
* Unlike `checkVolumeAnomaly` which compares against a historical baseline,
|
|
6
|
+
* this performs a simple static bounds check — ideal for users who need
|
|
7
|
+
* straightforward min/max row count monitoring.
|
|
8
|
+
*
|
|
9
|
+
* @module @freshguard/freshguard-core/monitor/volume-threshold
|
|
10
|
+
* @license MIT
|
|
11
|
+
*/
|
|
12
|
+
import type { CheckResult, MonitoringRule, FreshGuardConfig } from '../types.js';
|
|
13
|
+
import type { Connector } from '../types/connector.js';
|
|
14
|
+
/**
|
|
15
|
+
* Check whether a table's row count is within the configured min/max thresholds.
|
|
16
|
+
*
|
|
17
|
+
* Returns `'alert'` when the row count is below `minRowThreshold` or above
|
|
18
|
+
* `maxRowThreshold`. At least one threshold must be set on the rule.
|
|
19
|
+
*
|
|
20
|
+
* @param connector - Database connector instance
|
|
21
|
+
* @param rule - Monitoring rule with `ruleType: 'volume_threshold'` and at least one of `minRowThreshold` / `maxRowThreshold`
|
|
22
|
+
* @param config - Optional configuration including timeouts
|
|
23
|
+
* @returns CheckResult with `status`, `rowCount`, and `message`
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```typescript
|
|
27
|
+
* import { checkVolumeThreshold, PostgresConnector } from '@freshguard/freshguard-core';
|
|
28
|
+
*
|
|
29
|
+
* const connector = new PostgresConnector({ host: 'localhost', database: 'mydb', username: 'user', password: 'pass', ssl: true });
|
|
30
|
+
* const rule = {
|
|
31
|
+
* id: 'r1', sourceId: 's1', name: 'Orders Volume',
|
|
32
|
+
* tableName: 'orders', ruleType: 'volume_threshold' as const,
|
|
33
|
+
* minRowThreshold: 100, maxRowThreshold: 10_000_000,
|
|
34
|
+
* checkIntervalMinutes: 60, isActive: true,
|
|
35
|
+
* createdAt: new Date(), updatedAt: new Date(),
|
|
36
|
+
* };
|
|
37
|
+
* const result = await checkVolumeThreshold(connector, rule);
|
|
38
|
+
* console.log(result.status, result.rowCount);
|
|
39
|
+
* ```
|
|
40
|
+
*
|
|
41
|
+
* @since 0.3.0
|
|
42
|
+
*/
|
|
43
|
+
export declare function checkVolumeThreshold(connector: Connector, rule: MonitoringRule, config?: FreshGuardConfig): Promise<CheckResult>;
|
|
44
|
+
//# sourceMappingURL=volume-threshold.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"volume-threshold.d.ts","sourceRoot":"","sources":["../../src/monitor/volume-threshold.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACjF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAUvD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAsB,oBAAoB,CACxC,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,cAAc,EACpB,MAAM,CAAC,EAAE,gBAAgB,GACxB,OAAO,CAAC,WAAW,CAAC,CAgEtB"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple volume threshold check
|
|
3
|
+
* Alerts when row count falls below a minimum or exceeds a maximum threshold.
|
|
4
|
+
*
|
|
5
|
+
* Unlike `checkVolumeAnomaly` which compares against a historical baseline,
|
|
6
|
+
* this performs a simple static bounds check — ideal for users who need
|
|
7
|
+
* straightforward min/max row count monitoring.
|
|
8
|
+
*
|
|
9
|
+
* @module @freshguard/freshguard-core/monitor/volume-threshold
|
|
10
|
+
* @license MIT
|
|
11
|
+
*/
|
|
12
|
+
import { validateTableName } from '../validators/index.js';
|
|
13
|
+
import { TimeoutError, ConfigurationError, ErrorHandler, } from '../errors/index.js';
|
|
14
|
+
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
15
|
+
/**
|
|
16
|
+
* Check whether a table's row count is within the configured min/max thresholds.
|
|
17
|
+
*
|
|
18
|
+
* Returns `'alert'` when the row count is below `minRowThreshold` or above
|
|
19
|
+
* `maxRowThreshold`. At least one threshold must be set on the rule.
|
|
20
|
+
*
|
|
21
|
+
* @param connector - Database connector instance
|
|
22
|
+
* @param rule - Monitoring rule with `ruleType: 'volume_threshold'` and at least one of `minRowThreshold` / `maxRowThreshold`
|
|
23
|
+
* @param config - Optional configuration including timeouts
|
|
24
|
+
* @returns CheckResult with `status`, `rowCount`, and `message`
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* import { checkVolumeThreshold, PostgresConnector } from '@freshguard/freshguard-core';
|
|
29
|
+
*
|
|
30
|
+
* const connector = new PostgresConnector({ host: 'localhost', database: 'mydb', username: 'user', password: 'pass', ssl: true });
|
|
31
|
+
* const rule = {
|
|
32
|
+
* id: 'r1', sourceId: 's1', name: 'Orders Volume',
|
|
33
|
+
* tableName: 'orders', ruleType: 'volume_threshold' as const,
|
|
34
|
+
* minRowThreshold: 100, maxRowThreshold: 10_000_000,
|
|
35
|
+
* checkIntervalMinutes: 60, isActive: true,
|
|
36
|
+
* createdAt: new Date(), updatedAt: new Date(),
|
|
37
|
+
* };
|
|
38
|
+
* const result = await checkVolumeThreshold(connector, rule);
|
|
39
|
+
* console.log(result.status, result.rowCount);
|
|
40
|
+
* ```
|
|
41
|
+
*
|
|
42
|
+
* @since 0.3.0
|
|
43
|
+
*/
|
|
44
|
+
export async function checkVolumeThreshold(connector, rule, config) {
|
|
45
|
+
const startTime = process.hrtime.bigint();
|
|
46
|
+
try {
|
|
47
|
+
validateThresholdRule(rule);
|
|
48
|
+
validateTableName(rule.tableName);
|
|
49
|
+
const timeoutMs = config?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
50
|
+
const rowCount = await executeWithTimeout(() => connector.getRowCount(rule.tableName), timeoutMs, 'Volume threshold row count query timeout');
|
|
51
|
+
if (isNaN(rowCount) || rowCount < 0) {
|
|
52
|
+
throw new ConfigurationError('Invalid row count returned from connector');
|
|
53
|
+
}
|
|
54
|
+
if (rowCount > Number.MAX_SAFE_INTEGER) {
|
|
55
|
+
throw new ConfigurationError('Row count exceeds safe integer limit');
|
|
56
|
+
}
|
|
57
|
+
const executionDurationMs = Number(process.hrtime.bigint() - startTime) / 1_000_000;
|
|
58
|
+
const executedAt = new Date();
|
|
59
|
+
// Check thresholds
|
|
60
|
+
if (rule.minRowThreshold != null && rowCount < rule.minRowThreshold) {
|
|
61
|
+
return {
|
|
62
|
+
status: 'alert',
|
|
63
|
+
rowCount,
|
|
64
|
+
executionDurationMs,
|
|
65
|
+
executedAt,
|
|
66
|
+
error: `Row count ${rowCount} is below minimum threshold ${rule.minRowThreshold}`,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
if (rule.maxRowThreshold != null && rowCount > rule.maxRowThreshold) {
|
|
70
|
+
return {
|
|
71
|
+
status: 'alert',
|
|
72
|
+
rowCount,
|
|
73
|
+
executionDurationMs,
|
|
74
|
+
executedAt,
|
|
75
|
+
error: `Row count ${rowCount} exceeds maximum threshold ${rule.maxRowThreshold}`,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
return {
|
|
79
|
+
status: 'ok',
|
|
80
|
+
rowCount,
|
|
81
|
+
executionDurationMs,
|
|
82
|
+
executedAt,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
const userMessage = ErrorHandler.getUserMessage(error);
|
|
87
|
+
const executionDurationMs = Number(process.hrtime.bigint() - startTime) / 1_000_000;
|
|
88
|
+
return {
|
|
89
|
+
status: 'failed',
|
|
90
|
+
error: userMessage,
|
|
91
|
+
executionDurationMs,
|
|
92
|
+
executedAt: new Date(),
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Validate that the rule is correctly configured for volume threshold checks.
|
|
98
|
+
*/
|
|
99
|
+
function validateThresholdRule(rule) {
|
|
100
|
+
if (!rule) {
|
|
101
|
+
throw new ConfigurationError('Monitoring rule is required');
|
|
102
|
+
}
|
|
103
|
+
if (!rule.id || typeof rule.id !== 'string') {
|
|
104
|
+
throw new ConfigurationError('Rule ID is required and must be a string');
|
|
105
|
+
}
|
|
106
|
+
if (!rule.tableName || typeof rule.tableName !== 'string') {
|
|
107
|
+
throw new ConfigurationError('Table name is required and must be a string');
|
|
108
|
+
}
|
|
109
|
+
if (rule.tableName.length > 256) {
|
|
110
|
+
throw new ConfigurationError('Table name too long (max 256 characters)');
|
|
111
|
+
}
|
|
112
|
+
if (rule.ruleType !== 'volume_threshold') {
|
|
113
|
+
throw new ConfigurationError('Rule type must be "volume_threshold" for volume threshold checks');
|
|
114
|
+
}
|
|
115
|
+
const hasMin = rule.minRowThreshold != null;
|
|
116
|
+
const hasMax = rule.maxRowThreshold != null;
|
|
117
|
+
if (!hasMin && !hasMax) {
|
|
118
|
+
throw new ConfigurationError('At least one of minRowThreshold or maxRowThreshold must be set');
|
|
119
|
+
}
|
|
120
|
+
if (hasMin) {
|
|
121
|
+
if (typeof rule.minRowThreshold !== 'number' || !Number.isInteger(rule.minRowThreshold) || rule.minRowThreshold < 0) {
|
|
122
|
+
throw new ConfigurationError('minRowThreshold must be a non-negative integer');
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
if (hasMax) {
|
|
126
|
+
if (typeof rule.maxRowThreshold !== 'number' || !Number.isInteger(rule.maxRowThreshold) || rule.maxRowThreshold < 0) {
|
|
127
|
+
throw new ConfigurationError('maxRowThreshold must be a non-negative integer');
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
if (hasMin && hasMax && rule.minRowThreshold > rule.maxRowThreshold) {
|
|
131
|
+
throw new ConfigurationError('minRowThreshold cannot be greater than maxRowThreshold');
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Execute operation with timeout protection
|
|
136
|
+
*/
|
|
137
|
+
async function executeWithTimeout(operation, timeoutMs, timeoutMessage) {
|
|
138
|
+
return new Promise((resolve, reject) => {
|
|
139
|
+
const timer = setTimeout(() => {
|
|
140
|
+
reject(new TimeoutError(timeoutMessage, 'volume_threshold_check', timeoutMs));
|
|
141
|
+
}, timeoutMs);
|
|
142
|
+
operation()
|
|
143
|
+
.then(resolve)
|
|
144
|
+
.catch(reject)
|
|
145
|
+
.finally(() => clearTimeout(timer));
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=volume-threshold.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"volume-threshold.js","sourceRoot":"","sources":["../../src/monitor/volume-threshold.ts"],"names":[],"mappings":"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"}
|
package/dist/types/connector.js
CHANGED
|
@@ -22,12 +22,12 @@ export const DEFAULT_SECURITY_CONFIG = {
|
|
|
22
22
|
// backticks: `schema.table` (MySQL, BigQuery)
|
|
23
23
|
// brackets: [schema.table] (MSSQL, Azure SQL, Synapse)
|
|
24
24
|
// quotes: "schema.table" (PostgreSQL, Redshift)
|
|
25
|
-
/^SELECT\s+COUNT\(\*\)(?:\s+as\s+\w+)?\s+FROM\s+(?:[`"][\w
|
|
26
|
-
/^SELECT\s+MAX\((?:[`"]\w+[`"]|\[\w+\]|\w+)\)(?:\s+as\s+\w+)?\s+FROM\s+(?:[`"][\w
|
|
27
|
-
/^SELECT\s+MIN\((?:[`"]\w+[`"]|\[\w+\]|\w+)\)(?:\s+as\s+\w+)?\s+FROM\s+(?:[`"][\w
|
|
25
|
+
/^SELECT\s+COUNT\(\*\)(?:\s+as\s+\w+)?\s+FROM\s+(?:[`"][\w.-]+[`"]|\[[\w.]+\]|\w+(?:\.\w+)*)$/is, // getRowCount
|
|
26
|
+
/^SELECT\s+MAX\((?:[`"]\w+[`"]|\[\w+\]|\w+)\)(?:\s+as\s+\w+)?\s+FROM\s+(?:[`"][\w.-]+[`"]|\[[\w.]+\]|\w+(?:\.\w+)*)$/is, // getMaxTimestamp
|
|
27
|
+
/^SELECT\s+MIN\((?:[`"]\w+[`"]|\[\w+\]|\w+)\)(?:\s+as\s+\w+)?\s+FROM\s+(?:[`"][\w.-]+[`"]|\[[\w.]+\]|\w+(?:\.\w+)*)$/is, // getMinTimestamp
|
|
28
28
|
// Schema introspection queries
|
|
29
|
-
/^DESCRIBE\s+(?:[`"][\w
|
|
30
|
-
/^SHOW\s+(TABLES|COLUMNS)(?:\s+FROM\s+(?:[`"][\w
|
|
29
|
+
/^DESCRIBE\s+(?:[`"][\w.-]+[`"]|\[[\w.]+\]|\w+(?:\.\w+)*)$/i, // DESCRIBE [schema.]table
|
|
30
|
+
/^SHOW\s+(TABLES|COLUMNS)(?:\s+FROM\s+(?:[`"][\w.-]+[`"]|\[[\w.]+\]|\w+(?:\.\w+)*))?$/i, // SHOW TABLES/COLUMNS
|
|
31
31
|
// Information schema queries (cross-database compatibility)
|
|
32
32
|
/^SELECT\s+.+?\s+FROM\s+information_schema\.\w+/is, // PostgreSQL/MySQL information_schema
|
|
33
33
|
/^SELECT[\s\S]+?FROM[\s\S]+?information_schema\.\w+/is, // Multi-line information_schema queries
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connector.js","sourceRoot":"","sources":["../../src/types/connector.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AA+JH;;GAEG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAmB;IACrD,iBAAiB,EAAE,KAAK,EAAG,aAAa;IACxC,YAAY,EAAE,KAAK,EAAQ,aAAa;IACxC,OAAO,EAAE,IAAI;IACb,UAAU,EAAE,IAAI;IAChB,mHAAmH;IACnH,oBAAoB,EAAE;QACpB,gDAAgD;QAChD,kEAAkE;QAClE,mDAAmD;QACnD,gDAAgD;QAChD,0DAA0D;QAC1D,qDAAqD;QACrD
|
|
1
|
+
{"version":3,"file":"connector.js","sourceRoot":"","sources":["../../src/types/connector.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AA+JH;;GAEG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAmB;IACrD,iBAAiB,EAAE,KAAK,EAAG,aAAa;IACxC,YAAY,EAAE,KAAK,EAAQ,aAAa;IACxC,OAAO,EAAE,IAAI;IACb,UAAU,EAAE,IAAI;IAChB,mHAAmH;IACnH,oBAAoB,EAAE;QACpB,gDAAgD;QAChD,kEAAkE;QAClE,mDAAmD;QACnD,gDAAgD;QAChD,0DAA0D;QAC1D,qDAAqD;QACrD,gGAAgG,EAAqB,cAAc;QACnI,uHAAuH,EAAY,kBAAkB;QACrJ,uHAAuH,EAAY,kBAAkB;QAErJ,+BAA+B;QAC/B,4DAA4D,EAA+C,0BAA0B;QACrI,uFAAuF,EAAoB,sBAAsB;QAEjI,4DAA4D;QAC5D,kDAAkD,EAAmC,sCAAsC;QAC3H,sDAAsD,EAA+B,wCAAwC;QAC7H,8DAA8D,EAAuB,0CAA0C;QAE/H,yCAAyC;QACzC,4FAA4F,EAAE,sBAAsB;QACpH,0FAA0F,EAAI,qBAAqB;QAEnH,wDAAwD;QACxD,0CAA0C,EAA2C,yCAAyC;QAC9H,2CAA2C,EAA0C,+BAA+B;QAEpH,mCAAmC;QACnC,kDAAkD,EAAoC,uCAAuC;QAC7H,mCAAmC,EAAoD,qBAAqB;QAC5G,sCAAsC,EAAiD,iCAAiC;QAExH,0BAA0B;QAC1B,+BAA+B,EAAsD,wCAAwC;KAC9H;IACD,gDAAgD;IAChD,eAAe,EAAE;QACf,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU;QACnE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK;KAClD;CACF,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* @license MIT
|
|
8
8
|
*/
|
|
9
9
|
export type DataSourceType = 'postgres' | 'duckdb' | 'bigquery' | 'snowflake' | 'mysql' | 'redshift' | 'mssql' | 'azure_sql' | 'synapse';
|
|
10
|
-
export type RuleType = 'freshness' | 'volume_anomaly' | 'schema_change' | 'custom_sql';
|
|
10
|
+
export type RuleType = 'freshness' | 'volume_anomaly' | 'volume_threshold' | 'schema_change' | 'custom_sql';
|
|
11
11
|
export type CheckStatus = 'ok' | 'alert' | 'failed' | 'pending';
|
|
12
12
|
export type AlertDestinationType = 'slack' | 'email' | 'pagerduty' | 'webhook';
|
|
13
13
|
export type SeverityLevel = 'low' | 'medium' | 'high' | 'critical';
|
|
@@ -101,6 +101,8 @@ export interface MonitoringRule {
|
|
|
101
101
|
trimmedMeanPercentile?: number;
|
|
102
102
|
seasonalAdjustment?: boolean;
|
|
103
103
|
};
|
|
104
|
+
minRowThreshold?: number;
|
|
105
|
+
maxRowThreshold?: number;
|
|
104
106
|
trackColumnChanges?: boolean;
|
|
105
107
|
trackTableChanges?: boolean;
|
|
106
108
|
schemaChangeConfig?: {
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG,QAAQ,GAAG,UAAU,GAAG,WAAW,GAAG,OAAO,GAAG,UAAU,GAAG,OAAO,GAAG,WAAW,GAAG,SAAS,CAAC;AACzI,MAAM,MAAM,QAAQ,GAAG,WAAW,GAAG,gBAAgB,GAAG,eAAe,GAAG,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|