@freshguard/freshguard-core 0.11.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/LICENSE +21 -0
- package/README.md +644 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +350 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/connectors/base-connector.d.ts +62 -0
- package/dist/connectors/base-connector.d.ts.map +1 -0
- package/dist/connectors/base-connector.js +549 -0
- package/dist/connectors/base-connector.js.map +1 -0
- package/dist/connectors/bigquery.d.ts +38 -0
- package/dist/connectors/bigquery.d.ts.map +1 -0
- package/dist/connectors/bigquery.js +406 -0
- package/dist/connectors/bigquery.js.map +1 -0
- package/dist/connectors/duckdb.d.ts +36 -0
- package/dist/connectors/duckdb.d.ts.map +1 -0
- package/dist/connectors/duckdb.js +364 -0
- package/dist/connectors/duckdb.js.map +1 -0
- package/dist/connectors/index.d.ts +7 -0
- package/dist/connectors/index.d.ts.map +1 -0
- package/dist/connectors/index.js +7 -0
- package/dist/connectors/index.js.map +1 -0
- package/dist/connectors/mysql.d.ts +32 -0
- package/dist/connectors/mysql.d.ts.map +1 -0
- package/dist/connectors/mysql.js +348 -0
- package/dist/connectors/mysql.js.map +1 -0
- package/dist/connectors/postgres.d.ts +31 -0
- package/dist/connectors/postgres.d.ts.map +1 -0
- package/dist/connectors/postgres.js +326 -0
- package/dist/connectors/postgres.js.map +1 -0
- package/dist/connectors/redshift.d.ts +32 -0
- package/dist/connectors/redshift.d.ts.map +1 -0
- package/dist/connectors/redshift.js +366 -0
- package/dist/connectors/redshift.js.map +1 -0
- package/dist/connectors/snowflake.d.ts +43 -0
- package/dist/connectors/snowflake.d.ts.map +1 -0
- package/dist/connectors/snowflake.js +442 -0
- package/dist/connectors/snowflake.js.map +1 -0
- package/dist/db/index.d.ts +9 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +10 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/migrate.d.ts +12 -0
- package/dist/db/migrate.d.ts.map +1 -0
- package/dist/db/migrate.js +114 -0
- package/dist/db/migrate.js.map +1 -0
- package/dist/db/schema.d.ts +2053 -0
- package/dist/db/schema.d.ts.map +1 -0
- package/dist/db/schema.js +164 -0
- package/dist/db/schema.js.map +1 -0
- package/dist/errors/debug-factory.d.ts +23 -0
- package/dist/errors/debug-factory.d.ts.map +1 -0
- package/dist/errors/debug-factory.js +149 -0
- package/dist/errors/debug-factory.js.map +1 -0
- package/dist/errors/index.d.ts +119 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +341 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/metadata/duckdb-storage.d.ts +31 -0
- package/dist/metadata/duckdb-storage.d.ts.map +1 -0
- package/dist/metadata/duckdb-storage.js +230 -0
- package/dist/metadata/duckdb-storage.js.map +1 -0
- package/dist/metadata/factory.d.ts +4 -0
- package/dist/metadata/factory.d.ts.map +1 -0
- package/dist/metadata/factory.js +23 -0
- package/dist/metadata/factory.js.map +1 -0
- package/dist/metadata/index.d.ts +6 -0
- package/dist/metadata/index.d.ts.map +1 -0
- package/dist/metadata/index.js +4 -0
- package/dist/metadata/index.js.map +1 -0
- package/dist/metadata/interface.d.ts +26 -0
- package/dist/metadata/interface.d.ts.map +1 -0
- package/dist/metadata/interface.js +2 -0
- package/dist/metadata/interface.js.map +1 -0
- package/dist/metadata/postgresql-storage.d.ts +32 -0
- package/dist/metadata/postgresql-storage.d.ts.map +1 -0
- package/dist/metadata/postgresql-storage.js +242 -0
- package/dist/metadata/postgresql-storage.js.map +1 -0
- package/dist/metadata/schema-config.d.ts +30 -0
- package/dist/metadata/schema-config.d.ts.map +1 -0
- package/dist/metadata/schema-config.js +94 -0
- package/dist/metadata/schema-config.js.map +1 -0
- package/dist/metadata/types.d.ts +35 -0
- package/dist/metadata/types.d.ts.map +1 -0
- package/dist/metadata/types.js +2 -0
- package/dist/metadata/types.js.map +1 -0
- package/dist/monitor/baseline-calculator.d.ts +30 -0
- package/dist/monitor/baseline-calculator.d.ts.map +1 -0
- package/dist/monitor/baseline-calculator.js +192 -0
- package/dist/monitor/baseline-calculator.js.map +1 -0
- package/dist/monitor/baseline-config.d.ts +37 -0
- package/dist/monitor/baseline-config.d.ts.map +1 -0
- package/dist/monitor/baseline-config.js +156 -0
- package/dist/monitor/baseline-config.js.map +1 -0
- package/dist/monitor/freshness.d.ts +5 -0
- package/dist/monitor/freshness.d.ts.map +1 -0
- package/dist/monitor/freshness.js +239 -0
- package/dist/monitor/freshness.js.map +1 -0
- package/dist/monitor/index.d.ts +5 -0
- package/dist/monitor/index.d.ts.map +1 -0
- package/dist/monitor/index.js +5 -0
- package/dist/monitor/index.js.map +1 -0
- package/dist/monitor/schema-baseline.d.ts +22 -0
- package/dist/monitor/schema-baseline.d.ts.map +1 -0
- package/dist/monitor/schema-baseline.js +211 -0
- package/dist/monitor/schema-baseline.js.map +1 -0
- package/dist/monitor/schema-changes.d.ts +5 -0
- package/dist/monitor/schema-changes.d.ts.map +1 -0
- package/dist/monitor/schema-changes.js +289 -0
- package/dist/monitor/schema-changes.js.map +1 -0
- package/dist/monitor/volume.d.ts +5 -0
- package/dist/monitor/volume.d.ts.map +1 -0
- package/dist/monitor/volume.js +262 -0
- package/dist/monitor/volume.js.map +1 -0
- package/dist/observability/logger.d.ts +63 -0
- package/dist/observability/logger.d.ts.map +1 -0
- package/dist/observability/logger.js +282 -0
- package/dist/observability/logger.js.map +1 -0
- package/dist/observability/metrics.d.ts +106 -0
- package/dist/observability/metrics.d.ts.map +1 -0
- package/dist/observability/metrics.js +441 -0
- package/dist/observability/metrics.js.map +1 -0
- package/dist/query-analyzer.js +526 -0
- package/dist/resilience/circuit-breaker.d.ts +94 -0
- package/dist/resilience/circuit-breaker.d.ts.map +1 -0
- package/dist/resilience/circuit-breaker.js +379 -0
- package/dist/resilience/circuit-breaker.js.map +1 -0
- package/dist/resilience/index.d.ts +7 -0
- package/dist/resilience/index.d.ts.map +1 -0
- package/dist/resilience/index.js +7 -0
- package/dist/resilience/index.js.map +1 -0
- package/dist/resilience/retry-policy.d.ts +87 -0
- package/dist/resilience/retry-policy.d.ts.map +1 -0
- package/dist/resilience/retry-policy.js +423 -0
- package/dist/resilience/retry-policy.js.map +1 -0
- package/dist/resilience/timeout-manager.d.ts +97 -0
- package/dist/resilience/timeout-manager.d.ts.map +1 -0
- package/dist/resilience/timeout-manager.js +339 -0
- package/dist/resilience/timeout-manager.js.map +1 -0
- package/dist/security/query-analyzer.d.ts +82 -0
- package/dist/security/query-analyzer.d.ts.map +1 -0
- package/dist/security/query-analyzer.js +381 -0
- package/dist/security/query-analyzer.js.map +1 -0
- package/dist/security/schema-cache.d.ts +95 -0
- package/dist/security/schema-cache.d.ts.map +1 -0
- package/dist/security/schema-cache.js +344 -0
- package/dist/security/schema-cache.js.map +1 -0
- package/dist/types/connector.d.ts +68 -0
- package/dist/types/connector.d.ts.map +1 -0
- package/dist/types/connector.js +26 -0
- package/dist/types/connector.js.map +1 -0
- package/dist/types.d.ts +244 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/validation/index.d.ts +7 -0
- package/dist/validation/index.d.ts.map +1 -0
- package/dist/validation/index.js +5 -0
- package/dist/validation/index.js.map +1 -0
- package/dist/validation/runtime-validator.d.ts +70 -0
- package/dist/validation/runtime-validator.d.ts.map +1 -0
- package/dist/validation/runtime-validator.js +206 -0
- package/dist/validation/runtime-validator.js.map +1 -0
- package/dist/validation/sanitizers.d.ts +56 -0
- package/dist/validation/sanitizers.d.ts.map +1 -0
- package/dist/validation/sanitizers.js +264 -0
- package/dist/validation/sanitizers.js.map +1 -0
- package/dist/validation/schemas.d.ts +224 -0
- package/dist/validation/schemas.d.ts.map +1 -0
- package/dist/validation/schemas.js +263 -0
- package/dist/validation/schemas.js.map +1 -0
- package/dist/validators/index.d.ts +18 -0
- package/dist/validators/index.d.ts.map +1 -0
- package/dist/validators/index.js +209 -0
- package/dist/validators/index.js.map +1 -0
- package/package.json +91 -0
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
export class FreshGuardError extends Error {
|
|
2
|
+
code;
|
|
3
|
+
timestamp;
|
|
4
|
+
sanitized;
|
|
5
|
+
debugId;
|
|
6
|
+
debug;
|
|
7
|
+
constructor(message, code, sanitized = true, debug) {
|
|
8
|
+
super(message);
|
|
9
|
+
this.name = this.constructor.name;
|
|
10
|
+
this.code = code;
|
|
11
|
+
this.timestamp = new Date();
|
|
12
|
+
this.sanitized = sanitized;
|
|
13
|
+
this.debugId = generateDebugId();
|
|
14
|
+
this.debug = debug;
|
|
15
|
+
if (Error.captureStackTrace) {
|
|
16
|
+
Error.captureStackTrace(this, this.constructor);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
toJSON() {
|
|
20
|
+
return {
|
|
21
|
+
name: this.name,
|
|
22
|
+
message: this.message,
|
|
23
|
+
code: this.code,
|
|
24
|
+
timestamp: this.timestamp.toISOString(),
|
|
25
|
+
sanitized: this.sanitized,
|
|
26
|
+
debugId: this.debugId,
|
|
27
|
+
debug: this.debug,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function generateDebugId() {
|
|
32
|
+
return `fg-${Date.now().toString(36)}-${Math.random().toString(36).substr(2, 5)}`;
|
|
33
|
+
}
|
|
34
|
+
export class SecurityError extends FreshGuardError {
|
|
35
|
+
attemptedAction;
|
|
36
|
+
constructor(message, attemptedAction = 'unknown') {
|
|
37
|
+
super(message, 'SECURITY_VIOLATION', true);
|
|
38
|
+
this.attemptedAction = attemptedAction;
|
|
39
|
+
}
|
|
40
|
+
static invalidIdentifier(identifier) {
|
|
41
|
+
return new SecurityError(`Invalid identifier: contains unsafe characters`, `invalid_identifier:${identifier.length}`);
|
|
42
|
+
}
|
|
43
|
+
static blockedQuery(keyword) {
|
|
44
|
+
return new SecurityError(`Query blocked: contains prohibited keyword`, `blocked_query:${keyword}`);
|
|
45
|
+
}
|
|
46
|
+
static queryPatternNotAllowed() {
|
|
47
|
+
return new SecurityError('Query pattern not allowed', 'invalid_pattern');
|
|
48
|
+
}
|
|
49
|
+
static sslRequired() {
|
|
50
|
+
return new SecurityError('SSL/TLS connection is required', 'ssl_required');
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
export class ConnectionError extends FreshGuardError {
|
|
54
|
+
host;
|
|
55
|
+
port;
|
|
56
|
+
constructor(message, host, port, originalError) {
|
|
57
|
+
const sanitizedMessage = ConnectionError.sanitizeConnectionError(message, originalError);
|
|
58
|
+
super(sanitizedMessage, 'CONNECTION_FAILED', true);
|
|
59
|
+
this.host = host;
|
|
60
|
+
this.port = port;
|
|
61
|
+
}
|
|
62
|
+
static sanitizeConnectionError(message, _originalError) {
|
|
63
|
+
const lowerMessage = message.toLowerCase();
|
|
64
|
+
if (lowerMessage.includes('connection refused')) {
|
|
65
|
+
return 'Connection refused - check host and port';
|
|
66
|
+
}
|
|
67
|
+
if (lowerMessage.includes('connection timed out') || lowerMessage.includes('timeout')) {
|
|
68
|
+
return 'Connection timeout - check network connectivity';
|
|
69
|
+
}
|
|
70
|
+
if (lowerMessage.includes('authentication failed') ||
|
|
71
|
+
lowerMessage.includes('permission denied') ||
|
|
72
|
+
lowerMessage.includes('access denied')) {
|
|
73
|
+
return 'Authentication failed - check credentials and permissions';
|
|
74
|
+
}
|
|
75
|
+
if (lowerMessage.includes('database') && lowerMessage.includes('does not exist')) {
|
|
76
|
+
return 'Database not found - check database name';
|
|
77
|
+
}
|
|
78
|
+
if (lowerMessage.includes('host') && lowerMessage.includes('not found')) {
|
|
79
|
+
return 'Host not found - check hostname';
|
|
80
|
+
}
|
|
81
|
+
if (lowerMessage.includes('ssl') || lowerMessage.includes('tls')) {
|
|
82
|
+
return 'SSL/TLS connection failed - check SSL configuration';
|
|
83
|
+
}
|
|
84
|
+
return 'Database connection failed - check configuration';
|
|
85
|
+
}
|
|
86
|
+
static hostUnreachable(host, port) {
|
|
87
|
+
return new ConnectionError('Host unreachable', host, port);
|
|
88
|
+
}
|
|
89
|
+
static authenticationFailed(host) {
|
|
90
|
+
return new ConnectionError('Authentication failed', host);
|
|
91
|
+
}
|
|
92
|
+
static databaseNotFound(_database, host) {
|
|
93
|
+
return new ConnectionError('Database not found', host);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
export class TimeoutError extends FreshGuardError {
|
|
97
|
+
operationType;
|
|
98
|
+
timeoutMs;
|
|
99
|
+
constructor(message, operationType = 'unknown', timeoutMs = 0) {
|
|
100
|
+
const sanitizedMessage = TimeoutError.sanitizeTimeoutError(message);
|
|
101
|
+
super(sanitizedMessage, 'OPERATION_TIMEOUT', true);
|
|
102
|
+
this.operationType = operationType;
|
|
103
|
+
this.timeoutMs = timeoutMs;
|
|
104
|
+
}
|
|
105
|
+
static sanitizeTimeoutError(message) {
|
|
106
|
+
const lowerMessage = message.toLowerCase();
|
|
107
|
+
if (lowerMessage.includes('query timeout')) {
|
|
108
|
+
return 'Query timeout - operation took too long';
|
|
109
|
+
}
|
|
110
|
+
if (lowerMessage.includes('connection timeout')) {
|
|
111
|
+
return 'Connection timeout - check network connectivity';
|
|
112
|
+
}
|
|
113
|
+
return 'Operation timeout - request took too long';
|
|
114
|
+
}
|
|
115
|
+
static queryTimeout(timeoutMs) {
|
|
116
|
+
return new TimeoutError(`Query timeout after ${timeoutMs}ms - table may be too large`, 'query', timeoutMs);
|
|
117
|
+
}
|
|
118
|
+
static connectionTimeout(timeoutMs) {
|
|
119
|
+
return new TimeoutError(`Connection timeout after ${timeoutMs}ms`, 'connection', timeoutMs);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
export class QueryError extends FreshGuardError {
|
|
123
|
+
queryType;
|
|
124
|
+
table;
|
|
125
|
+
constructor(message, queryType = 'unknown', table, originalError, debug) {
|
|
126
|
+
const sanitizedMessage = QueryError.sanitizeQueryError(message, originalError);
|
|
127
|
+
super(sanitizedMessage, 'QUERY_FAILED', true, debug);
|
|
128
|
+
this.queryType = queryType;
|
|
129
|
+
this.table = table;
|
|
130
|
+
}
|
|
131
|
+
static sanitizeQueryError(message, _originalError) {
|
|
132
|
+
const lowerMessage = message.toLowerCase();
|
|
133
|
+
if (lowerMessage.includes('syntax error')) {
|
|
134
|
+
return 'Invalid query syntax';
|
|
135
|
+
}
|
|
136
|
+
if (lowerMessage.includes('table') && lowerMessage.includes('not exist')) {
|
|
137
|
+
return 'Table does not exist';
|
|
138
|
+
}
|
|
139
|
+
if (lowerMessage.includes('column') && lowerMessage.includes('not exist')) {
|
|
140
|
+
return 'Column does not exist';
|
|
141
|
+
}
|
|
142
|
+
if (lowerMessage.includes('permission denied') || lowerMessage.includes('access denied')) {
|
|
143
|
+
return 'Insufficient permissions for query execution';
|
|
144
|
+
}
|
|
145
|
+
if (lowerMessage.includes('too many rows') || lowerMessage.includes('result too large')) {
|
|
146
|
+
return 'Query result too large - consider adding filters';
|
|
147
|
+
}
|
|
148
|
+
return 'Query execution failed';
|
|
149
|
+
}
|
|
150
|
+
static tableNotFound(table) {
|
|
151
|
+
return new QueryError('Table does not exist', 'table_access', table);
|
|
152
|
+
}
|
|
153
|
+
static columnNotFound(_column, table) {
|
|
154
|
+
return new QueryError('Column does not exist', 'column_access', table);
|
|
155
|
+
}
|
|
156
|
+
static resultTooLarge(maxRows, table) {
|
|
157
|
+
return new QueryError(`Query returned too many rows (max ${maxRows})`, 'result_size', table);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
export class ConfigurationError extends FreshGuardError {
|
|
161
|
+
field;
|
|
162
|
+
constructor(message, field) {
|
|
163
|
+
super(message, 'CONFIGURATION_ERROR', true);
|
|
164
|
+
this.field = field;
|
|
165
|
+
}
|
|
166
|
+
static missingRequired(field) {
|
|
167
|
+
return new ConfigurationError(`Required configuration field missing: ${field}`, field);
|
|
168
|
+
}
|
|
169
|
+
static invalidValue(field, _value, expected) {
|
|
170
|
+
return new ConfigurationError(`Invalid value for ${field}: expected ${expected}`, field);
|
|
171
|
+
}
|
|
172
|
+
static invalidFormat(field, format) {
|
|
173
|
+
return new ConfigurationError(`Invalid format for ${field}: expected ${format}`, field);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
export class MonitoringError extends FreshGuardError {
|
|
177
|
+
ruleId;
|
|
178
|
+
table;
|
|
179
|
+
checkType;
|
|
180
|
+
constructor(message, checkType, ruleId, table) {
|
|
181
|
+
super(message, 'MONITORING_FAILED', true);
|
|
182
|
+
this.checkType = checkType;
|
|
183
|
+
this.ruleId = ruleId;
|
|
184
|
+
this.table = table;
|
|
185
|
+
}
|
|
186
|
+
static freshnessCheckFailed(table, reason) {
|
|
187
|
+
return new MonitoringError(`Freshness check failed for table ${table}: ${reason}`, 'freshness', undefined, table);
|
|
188
|
+
}
|
|
189
|
+
static volumeCheckFailed(table, reason) {
|
|
190
|
+
return new MonitoringError(`Volume check failed for table ${table}: ${reason}`, 'volume', undefined, table);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
export class MetadataStorageError extends FreshGuardError {
|
|
194
|
+
operation;
|
|
195
|
+
context;
|
|
196
|
+
constructor(message, operation, context, originalError, skipSanitization = false) {
|
|
197
|
+
const sanitizedMessage = skipSanitization ? message : MetadataStorageError.sanitizeMetadataError(message, originalError);
|
|
198
|
+
super(sanitizedMessage, 'METADATA_STORAGE_FAILED', true);
|
|
199
|
+
this.operation = operation;
|
|
200
|
+
this.context = MetadataStorageError.sanitizeContext(context);
|
|
201
|
+
}
|
|
202
|
+
static sanitizeMetadataError(message, _originalError) {
|
|
203
|
+
const lowerMessage = message.toLowerCase();
|
|
204
|
+
if (lowerMessage.includes('lock') || lowerMessage.includes('deadlock')) {
|
|
205
|
+
return 'Metadata storage lock contention';
|
|
206
|
+
}
|
|
207
|
+
if (lowerMessage.includes('permission') ||
|
|
208
|
+
lowerMessage.includes('access denied') ||
|
|
209
|
+
lowerMessage.includes('privileges')) {
|
|
210
|
+
return 'Insufficient permissions for metadata storage operation';
|
|
211
|
+
}
|
|
212
|
+
if ((lowerMessage.includes('table') &&
|
|
213
|
+
(lowerMessage.includes('not exist') || lowerMessage.includes('does not exist'))) ||
|
|
214
|
+
(lowerMessage.includes('relation') && lowerMessage.includes('not found'))) {
|
|
215
|
+
return 'Metadata storage not properly initialized';
|
|
216
|
+
}
|
|
217
|
+
if ((lowerMessage.includes('connection') || lowerMessage.includes('connect')) &&
|
|
218
|
+
(!lowerMessage.includes('timeout') || lowerMessage.includes('database'))) {
|
|
219
|
+
return 'Metadata storage connection failed';
|
|
220
|
+
}
|
|
221
|
+
if (lowerMessage.includes('timeout') || lowerMessage.includes('timed out')) {
|
|
222
|
+
return 'Metadata storage operation timeout';
|
|
223
|
+
}
|
|
224
|
+
if (lowerMessage.includes('connection') || lowerMessage.includes('connect')) {
|
|
225
|
+
return 'Metadata storage connection failed';
|
|
226
|
+
}
|
|
227
|
+
if (lowerMessage.includes('disk') || lowerMessage.includes('space')) {
|
|
228
|
+
return 'Metadata storage disk space issue';
|
|
229
|
+
}
|
|
230
|
+
return 'Metadata storage operation failed';
|
|
231
|
+
}
|
|
232
|
+
static sanitizeContext(context) {
|
|
233
|
+
if (!context)
|
|
234
|
+
return undefined;
|
|
235
|
+
const sanitized = {};
|
|
236
|
+
Object.entries(context).forEach(([key, value]) => {
|
|
237
|
+
if (['operation', 'ruleId', 'table', 'recordCount', 'duration', 'phase', 'windowDays', 'version'].includes(key)) {
|
|
238
|
+
sanitized[key] = value;
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
return Object.keys(sanitized).length > 0 ? sanitized : undefined;
|
|
242
|
+
}
|
|
243
|
+
static initializationFailed(reason) {
|
|
244
|
+
return new MetadataStorageError(reason ? `Initialization failed: ${reason}` : 'Metadata storage initialization failed', 'initialize', { phase: 'initialization' }, undefined, true);
|
|
245
|
+
}
|
|
246
|
+
static saveExecutionFailed(ruleId, originalError) {
|
|
247
|
+
return new MetadataStorageError('Failed to save check execution result', 'saveExecution', { ruleId }, originalError, true);
|
|
248
|
+
}
|
|
249
|
+
static getHistoricalDataFailed(ruleId, days, originalError) {
|
|
250
|
+
return new MetadataStorageError('Failed to retrieve historical execution data', 'getHistoricalData', { ruleId, windowDays: days }, originalError, true);
|
|
251
|
+
}
|
|
252
|
+
static saveRuleFailed(ruleId, originalError) {
|
|
253
|
+
return new MetadataStorageError('Failed to save monitoring rule', 'saveRule', { ruleId }, originalError, true);
|
|
254
|
+
}
|
|
255
|
+
static getRuleFailed(ruleId, originalError) {
|
|
256
|
+
return new MetadataStorageError('Failed to retrieve monitoring rule', 'getRule', { ruleId }, originalError, true);
|
|
257
|
+
}
|
|
258
|
+
static connectionFailed(originalError) {
|
|
259
|
+
return new MetadataStorageError('Metadata storage connection failed', 'connect', undefined, originalError, true);
|
|
260
|
+
}
|
|
261
|
+
static migrationFailed(version, originalError) {
|
|
262
|
+
return new MetadataStorageError('Database migration failed', 'migrate', { version }, originalError, true);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
export class ErrorHandler {
|
|
266
|
+
static sanitize(error) {
|
|
267
|
+
if (error instanceof FreshGuardError) {
|
|
268
|
+
return error;
|
|
269
|
+
}
|
|
270
|
+
if (error instanceof Error) {
|
|
271
|
+
const message = error.message.toLowerCase();
|
|
272
|
+
if (message.includes('connection')) {
|
|
273
|
+
return new ConnectionError(error.message);
|
|
274
|
+
}
|
|
275
|
+
if (message.includes('timeout')) {
|
|
276
|
+
return new TimeoutError(error.message);
|
|
277
|
+
}
|
|
278
|
+
if (message.includes('syntax') || message.includes('query')) {
|
|
279
|
+
return new QueryError(error.message);
|
|
280
|
+
}
|
|
281
|
+
if (message.includes('security') || message.includes('invalid')) {
|
|
282
|
+
return new SecurityError('Security validation failed');
|
|
283
|
+
}
|
|
284
|
+
return new QueryError('Operation failed', 'unknown_operation');
|
|
285
|
+
}
|
|
286
|
+
return new QueryError('Unknown error occurred', 'unknown_operation');
|
|
287
|
+
}
|
|
288
|
+
static shouldLogDetails(error) {
|
|
289
|
+
return !error.sanitized || (process.env.NODE_ENV === 'development' &&
|
|
290
|
+
!(error instanceof SecurityError));
|
|
291
|
+
}
|
|
292
|
+
static getUserMessage(error) {
|
|
293
|
+
const sanitizedError = this.sanitize(error);
|
|
294
|
+
return sanitizedError.message;
|
|
295
|
+
}
|
|
296
|
+
static getErrorCode(error) {
|
|
297
|
+
const sanitizedError = this.sanitize(error);
|
|
298
|
+
return sanitizedError.code;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
export const createError = {
|
|
302
|
+
security: {
|
|
303
|
+
invalidIdentifier: (name) => SecurityError.invalidIdentifier(name),
|
|
304
|
+
blockedQuery: (keyword) => SecurityError.blockedQuery(keyword),
|
|
305
|
+
queryNotAllowed: () => SecurityError.queryPatternNotAllowed(),
|
|
306
|
+
sslRequired: () => SecurityError.sslRequired(),
|
|
307
|
+
},
|
|
308
|
+
connection: {
|
|
309
|
+
hostUnreachable: (host, port) => ConnectionError.hostUnreachable(host, port),
|
|
310
|
+
authFailed: (host) => ConnectionError.authenticationFailed(host),
|
|
311
|
+
databaseNotFound: (database, host) => ConnectionError.databaseNotFound(database, host),
|
|
312
|
+
},
|
|
313
|
+
timeout: {
|
|
314
|
+
query: (timeoutMs) => TimeoutError.queryTimeout(timeoutMs),
|
|
315
|
+
connection: (timeoutMs) => TimeoutError.connectionTimeout(timeoutMs),
|
|
316
|
+
},
|
|
317
|
+
query: {
|
|
318
|
+
tableNotFound: (table) => QueryError.tableNotFound(table),
|
|
319
|
+
columnNotFound: (column, table) => QueryError.columnNotFound(column, table),
|
|
320
|
+
resultTooLarge: (maxRows, table) => QueryError.resultTooLarge(maxRows, table),
|
|
321
|
+
},
|
|
322
|
+
config: {
|
|
323
|
+
missingRequired: (field) => ConfigurationError.missingRequired(field),
|
|
324
|
+
invalidValue: (field, value, expected) => ConfigurationError.invalidValue(field, value, expected),
|
|
325
|
+
invalidFormat: (field, format) => ConfigurationError.invalidFormat(field, format),
|
|
326
|
+
},
|
|
327
|
+
monitoring: {
|
|
328
|
+
freshnessCheckFailed: (table, reason) => MonitoringError.freshnessCheckFailed(table, reason),
|
|
329
|
+
volumeCheckFailed: (table, reason) => MonitoringError.volumeCheckFailed(table, reason),
|
|
330
|
+
},
|
|
331
|
+
metadata: {
|
|
332
|
+
initializationFailed: (reason) => MetadataStorageError.initializationFailed(reason),
|
|
333
|
+
saveExecutionFailed: (ruleId, originalError) => MetadataStorageError.saveExecutionFailed(ruleId, originalError),
|
|
334
|
+
getHistoricalDataFailed: (ruleId, days, originalError) => MetadataStorageError.getHistoricalDataFailed(ruleId, days, originalError),
|
|
335
|
+
saveRuleFailed: (ruleId, originalError) => MetadataStorageError.saveRuleFailed(ruleId, originalError),
|
|
336
|
+
getRuleFailed: (ruleId, originalError) => MetadataStorageError.getRuleFailed(ruleId, originalError),
|
|
337
|
+
connectionFailed: (originalError) => MetadataStorageError.connectionFailed(originalError),
|
|
338
|
+
migrationFailed: (version, originalError) => MetadataStorageError.migrationFailed(version, originalError),
|
|
339
|
+
},
|
|
340
|
+
};
|
|
341
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/errors/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { checkFreshness, checkVolumeAnomaly, checkSchemaChanges } from './monitor/index.js';
|
|
2
|
+
export { PostgresConnector, DuckDBConnector, BigQueryConnector, SnowflakeConnector, MySQLConnector, RedshiftConnector } from './connectors/index.js';
|
|
3
|
+
export { createDatabase, schema } from './db/index.js';
|
|
4
|
+
export type { Database } from './db/index.js';
|
|
5
|
+
export { createMetadataStorage, DuckDBMetadataStorage, PostgreSQLMetadataStorage } from './metadata/index.js';
|
|
6
|
+
export type { MetadataStorage, MetadataStorageConfig } from './metadata/index.js';
|
|
7
|
+
export { FreshGuardError, SecurityError, ConnectionError, TimeoutError, QueryError, ConfigurationError, MonitoringError, ErrorHandler, createError } from './errors/index.js';
|
|
8
|
+
export type { DataSource, MonitoringRule, CheckResult, CheckExecution, AlertDestination, SourceCredentials, DataSourceType, RuleType, CheckStatus, AlertDestinationType, FreshGuardConfig, SchemaChanges, ColumnChange, SchemaBaseline, } from './types.js';
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAG5F,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAGrJ,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
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { checkFreshness, checkVolumeAnomaly, checkSchemaChanges } from './monitor/index.js';
|
|
2
|
+
export { PostgresConnector, DuckDBConnector, BigQueryConnector, SnowflakeConnector, MySQLConnector, RedshiftConnector } from './connectors/index.js';
|
|
3
|
+
export { createDatabase, schema } from './db/index.js';
|
|
4
|
+
export { createMetadataStorage, DuckDBMetadataStorage, PostgreSQLMetadataStorage } from './metadata/index.js';
|
|
5
|
+
export { FreshGuardError, SecurityError, ConnectionError, TimeoutError, QueryError, ConfigurationError, MonitoringError, ErrorHandler, createError } from './errors/index.js';
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAG5F,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAGrJ,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAIvD,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAI9G,OAAO,EACL,eAAe,EACf,aAAa,EACb,eAAe,EACf,YAAY,EACZ,UAAU,EACV,kBAAkB,EAClB,eAAe,EACf,YAAY,EACZ,WAAW,EACZ,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { MetadataStorage } from './interface.js';
|
|
2
|
+
import type { SchemaBaseline, MonitoringRule } from '../types.js';
|
|
3
|
+
interface MetadataExecution {
|
|
4
|
+
ruleId: string;
|
|
5
|
+
status: 'ok' | 'alert' | 'failed' | 'pending';
|
|
6
|
+
rowCount?: number;
|
|
7
|
+
lagMinutes?: number;
|
|
8
|
+
deviation?: number;
|
|
9
|
+
baselineAverage?: number;
|
|
10
|
+
currentDeviationPercent?: number;
|
|
11
|
+
schemaChanges?: unknown;
|
|
12
|
+
executionDurationMs?: number;
|
|
13
|
+
executedAt: Date;
|
|
14
|
+
error?: string;
|
|
15
|
+
}
|
|
16
|
+
export declare class DuckDBMetadataStorage implements MetadataStorage {
|
|
17
|
+
private readonly dbPath;
|
|
18
|
+
private instance?;
|
|
19
|
+
private connection?;
|
|
20
|
+
constructor(dbPath?: string);
|
|
21
|
+
initialize(): Promise<void>;
|
|
22
|
+
saveExecution(execution: MetadataExecution): Promise<void>;
|
|
23
|
+
getHistoricalData(ruleId: string, days: number): Promise<MetadataExecution[]>;
|
|
24
|
+
saveRule(rule: MonitoringRule): Promise<void>;
|
|
25
|
+
getRule(ruleId: string): Promise<MonitoringRule | null>;
|
|
26
|
+
storeSchemaBaseline(baseline: SchemaBaseline, adaptationReason?: string): Promise<void>;
|
|
27
|
+
getSchemaBaseline(ruleId: string): Promise<SchemaBaseline | null>;
|
|
28
|
+
close(): Promise<void>;
|
|
29
|
+
}
|
|
30
|
+
export {};
|
|
31
|
+
//# sourceMappingURL=duckdb-storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"duckdb-storage.d.ts","sourceRoot":"","sources":["../../src/metadata/duckdb-storage.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlE,UAAU,iBAAiB;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,IAAI,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,CAAC;IAC9C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,UAAU,EAAE,IAAI,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,qBAAsB,YAAW,eAAe;IAI/C,OAAO,CAAC,QAAQ,CAAC,MAAM;IAHnC,OAAO,CAAC,QAAQ,CAAC,CAAiB;IAClC,OAAO,CAAC,UAAU,CAAC,CAAmB;gBAET,MAAM,SAA6B;IAE1D,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAwE3B,aAAa,CAAC,SAAS,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAuB1D,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAkC7E,QAAQ,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAsB7C,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IA2BvD,mBAAmB,CAAC,QAAQ,EAAE,cAAc,EAAE,gBAAgB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAyBvF,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAsBjE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAU7B"}
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import { DuckDBInstance } from '@duckdb/node-api';
|
|
2
|
+
export class DuckDBMetadataStorage {
|
|
3
|
+
dbPath;
|
|
4
|
+
instance;
|
|
5
|
+
connection;
|
|
6
|
+
constructor(dbPath = './freshguard-metadata.db') {
|
|
7
|
+
this.dbPath = dbPath;
|
|
8
|
+
}
|
|
9
|
+
async initialize() {
|
|
10
|
+
if (this.connection)
|
|
11
|
+
return;
|
|
12
|
+
this.instance = await DuckDBInstance.create(this.dbPath);
|
|
13
|
+
this.connection = await this.instance.connect();
|
|
14
|
+
await this.connection.run(`
|
|
15
|
+
CREATE TABLE IF NOT EXISTS check_executions (
|
|
16
|
+
rule_id TEXT NOT NULL,
|
|
17
|
+
status TEXT NOT NULL,
|
|
18
|
+
row_count INTEGER,
|
|
19
|
+
lag_minutes DOUBLE,
|
|
20
|
+
baseline_average DOUBLE,
|
|
21
|
+
current_deviation_percent DOUBLE,
|
|
22
|
+
schema_changes TEXT,
|
|
23
|
+
execution_duration_ms INTEGER,
|
|
24
|
+
executed_at TIMESTAMP NOT NULL,
|
|
25
|
+
error_message TEXT
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
CREATE TABLE IF NOT EXISTS monitoring_rules (
|
|
29
|
+
id TEXT PRIMARY KEY,
|
|
30
|
+
source_id TEXT NOT NULL,
|
|
31
|
+
name TEXT NOT NULL,
|
|
32
|
+
description TEXT,
|
|
33
|
+
table_name TEXT NOT NULL,
|
|
34
|
+
rule_type TEXT NOT NULL,
|
|
35
|
+
expected_frequency TEXT,
|
|
36
|
+
tolerance_minutes INTEGER,
|
|
37
|
+
timestamp_column TEXT,
|
|
38
|
+
baseline_window_days INTEGER,
|
|
39
|
+
deviation_threshold_percent INTEGER,
|
|
40
|
+
minimum_row_count INTEGER,
|
|
41
|
+
track_column_changes BOOLEAN DEFAULT FALSE,
|
|
42
|
+
track_table_changes BOOLEAN DEFAULT FALSE,
|
|
43
|
+
schema_change_config TEXT, -- JSON
|
|
44
|
+
custom_sql TEXT,
|
|
45
|
+
expected_result TEXT, -- JSON
|
|
46
|
+
check_interval_minutes INTEGER NOT NULL,
|
|
47
|
+
timezone TEXT,
|
|
48
|
+
is_active BOOLEAN DEFAULT TRUE,
|
|
49
|
+
last_check_at TIMESTAMP,
|
|
50
|
+
last_status TEXT,
|
|
51
|
+
consecutive_failures INTEGER DEFAULT 0,
|
|
52
|
+
created_at TIMESTAMP NOT NULL,
|
|
53
|
+
updated_at TIMESTAMP NOT NULL
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
CREATE TABLE IF NOT EXISTS schema_baselines (
|
|
57
|
+
id TEXT PRIMARY KEY DEFAULT (gen_random_uuid()::TEXT),
|
|
58
|
+
rule_id TEXT NOT NULL,
|
|
59
|
+
table_name TEXT NOT NULL,
|
|
60
|
+
schema_snapshot TEXT NOT NULL, -- JSON as text
|
|
61
|
+
schema_hash TEXT NOT NULL,
|
|
62
|
+
captured_at TIMESTAMP NOT NULL,
|
|
63
|
+
updated_at TIMESTAMP NOT NULL,
|
|
64
|
+
adaptation_reason TEXT,
|
|
65
|
+
UNIQUE(rule_id)
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
CREATE INDEX IF NOT EXISTS idx_executions_rule_time
|
|
69
|
+
ON check_executions(rule_id, executed_at);
|
|
70
|
+
|
|
71
|
+
CREATE INDEX IF NOT EXISTS idx_schema_baselines_rule_id
|
|
72
|
+
ON schema_baselines(rule_id);
|
|
73
|
+
|
|
74
|
+
CREATE INDEX IF NOT EXISTS idx_schema_baselines_table_name
|
|
75
|
+
ON schema_baselines(table_name);
|
|
76
|
+
`);
|
|
77
|
+
}
|
|
78
|
+
async saveExecution(execution) {
|
|
79
|
+
if (!this.connection)
|
|
80
|
+
throw new Error('DuckDB storage not initialized');
|
|
81
|
+
await this.connection.run(`
|
|
82
|
+
INSERT INTO check_executions (
|
|
83
|
+
rule_id, status, row_count, lag_minutes,
|
|
84
|
+
baseline_average, current_deviation_percent, schema_changes,
|
|
85
|
+
execution_duration_ms, executed_at, error_message
|
|
86
|
+
) VALUES (
|
|
87
|
+
'${execution.ruleId}',
|
|
88
|
+
'${execution.status}',
|
|
89
|
+
${execution.rowCount ?? 'NULL'},
|
|
90
|
+
${execution.lagMinutes ?? 'NULL'},
|
|
91
|
+
${execution.baselineAverage ?? 'NULL'},
|
|
92
|
+
${execution.currentDeviationPercent ?? 'NULL'},
|
|
93
|
+
${execution.schemaChanges ? `'${JSON.stringify(execution.schemaChanges).replace(/'/g, "''")}'` : 'NULL'},
|
|
94
|
+
${execution.executionDurationMs ?? 'NULL'},
|
|
95
|
+
'${execution.executedAt.toISOString()}',
|
|
96
|
+
${execution.error ? `'${execution.error.replace(/'/g, "''")}'` : 'NULL'}
|
|
97
|
+
)
|
|
98
|
+
`);
|
|
99
|
+
}
|
|
100
|
+
async getHistoricalData(ruleId, days) {
|
|
101
|
+
if (!this.connection)
|
|
102
|
+
throw new Error('DuckDB storage not initialized');
|
|
103
|
+
const cutoffDate = new Date();
|
|
104
|
+
cutoffDate.setDate(cutoffDate.getDate() - days);
|
|
105
|
+
const reader = await this.connection.runAndReadAll(`
|
|
106
|
+
SELECT
|
|
107
|
+
rule_id, status, row_count, lag_minutes,
|
|
108
|
+
baseline_average, current_deviation_percent, schema_changes,
|
|
109
|
+
execution_duration_ms, executed_at, error_message
|
|
110
|
+
FROM check_executions
|
|
111
|
+
WHERE rule_id = '${ruleId}'
|
|
112
|
+
AND executed_at > '${cutoffDate.toISOString()}'
|
|
113
|
+
AND row_count IS NOT NULL
|
|
114
|
+
ORDER BY executed_at DESC
|
|
115
|
+
LIMIT 1000
|
|
116
|
+
`);
|
|
117
|
+
const rows = reader.getRowObjects();
|
|
118
|
+
return rows.map((row) => ({
|
|
119
|
+
ruleId: row.rule_id,
|
|
120
|
+
status: row.status,
|
|
121
|
+
rowCount: row.row_count,
|
|
122
|
+
lagMinutes: row.lag_minutes,
|
|
123
|
+
baselineAverage: row.baseline_average,
|
|
124
|
+
currentDeviationPercent: row.current_deviation_percent,
|
|
125
|
+
schemaChanges: row.schema_changes ? JSON.parse(row.schema_changes) : undefined,
|
|
126
|
+
executionDurationMs: row.execution_duration_ms,
|
|
127
|
+
executedAt: new Date(row.executed_at),
|
|
128
|
+
error: row.error_message || undefined,
|
|
129
|
+
}));
|
|
130
|
+
}
|
|
131
|
+
async saveRule(rule) {
|
|
132
|
+
if (!this.connection)
|
|
133
|
+
throw new Error('DuckDB storage not initialized');
|
|
134
|
+
await this.connection.run(`
|
|
135
|
+
INSERT OR REPLACE INTO monitoring_rules (
|
|
136
|
+
id, source_id, name, table_name, rule_type, check_interval_minutes,
|
|
137
|
+
is_active, created_at, updated_at
|
|
138
|
+
) VALUES (
|
|
139
|
+
'${rule.id}',
|
|
140
|
+
'${rule.sourceId}',
|
|
141
|
+
'${rule.name}',
|
|
142
|
+
'${rule.tableName}',
|
|
143
|
+
'${rule.ruleType}',
|
|
144
|
+
${rule.checkIntervalMinutes},
|
|
145
|
+
${rule.isActive},
|
|
146
|
+
'${rule.createdAt.toISOString()}',
|
|
147
|
+
'${rule.updatedAt.toISOString()}'
|
|
148
|
+
)
|
|
149
|
+
`);
|
|
150
|
+
}
|
|
151
|
+
async getRule(ruleId) {
|
|
152
|
+
if (!this.connection)
|
|
153
|
+
throw new Error('DuckDB storage not initialized');
|
|
154
|
+
const reader = await this.connection.runAndReadAll(`
|
|
155
|
+
SELECT id, source_id, name, table_name, rule_type, check_interval_minutes,
|
|
156
|
+
is_active, created_at, updated_at
|
|
157
|
+
FROM monitoring_rules
|
|
158
|
+
WHERE id = '${ruleId}'
|
|
159
|
+
`);
|
|
160
|
+
const rows = reader.getRowObjects();
|
|
161
|
+
if (rows.length === 0)
|
|
162
|
+
return null;
|
|
163
|
+
const row = rows[0];
|
|
164
|
+
return {
|
|
165
|
+
id: row.id,
|
|
166
|
+
sourceId: row.source_id,
|
|
167
|
+
name: row.name,
|
|
168
|
+
tableName: row.table_name,
|
|
169
|
+
ruleType: row.rule_type,
|
|
170
|
+
checkIntervalMinutes: row.check_interval_minutes,
|
|
171
|
+
isActive: row.is_active,
|
|
172
|
+
createdAt: new Date(row.created_at),
|
|
173
|
+
updatedAt: new Date(row.updated_at),
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
async storeSchemaBaseline(baseline, adaptationReason) {
|
|
177
|
+
if (!this.connection)
|
|
178
|
+
throw new Error('DuckDB storage not initialized');
|
|
179
|
+
await this.connection.run(`
|
|
180
|
+
INSERT OR REPLACE INTO schema_baselines (
|
|
181
|
+
rule_id,
|
|
182
|
+
table_name,
|
|
183
|
+
schema_snapshot,
|
|
184
|
+
schema_hash,
|
|
185
|
+
captured_at,
|
|
186
|
+
updated_at,
|
|
187
|
+
adaptation_reason
|
|
188
|
+
) VALUES (
|
|
189
|
+
'${baseline.ruleId}',
|
|
190
|
+
'${baseline.tableName}',
|
|
191
|
+
'${JSON.stringify(baseline.schema).replace(/'/g, "''")}',
|
|
192
|
+
'${baseline.schemaHash}',
|
|
193
|
+
'${baseline.capturedAt.toISOString()}',
|
|
194
|
+
'${new Date().toISOString()}',
|
|
195
|
+
${adaptationReason ? `'${adaptationReason.replace(/'/g, "''")}'` : 'NULL'}
|
|
196
|
+
)
|
|
197
|
+
`);
|
|
198
|
+
}
|
|
199
|
+
async getSchemaBaseline(ruleId) {
|
|
200
|
+
if (!this.connection)
|
|
201
|
+
throw new Error('DuckDB storage not initialized');
|
|
202
|
+
const reader = await this.connection.runAndReadAll(`
|
|
203
|
+
SELECT rule_id, table_name, schema_snapshot, schema_hash, captured_at
|
|
204
|
+
FROM schema_baselines
|
|
205
|
+
WHERE rule_id = '${ruleId}'
|
|
206
|
+
`);
|
|
207
|
+
const rows = reader.getRowObjects();
|
|
208
|
+
if (rows.length === 0)
|
|
209
|
+
return null;
|
|
210
|
+
const row = rows[0];
|
|
211
|
+
return {
|
|
212
|
+
ruleId: row.rule_id,
|
|
213
|
+
tableName: row.table_name,
|
|
214
|
+
schema: JSON.parse(row.schema_snapshot),
|
|
215
|
+
schemaHash: row.schema_hash,
|
|
216
|
+
capturedAt: new Date(row.captured_at),
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
async close() {
|
|
220
|
+
if (this.connection) {
|
|
221
|
+
this.connection.closeSync();
|
|
222
|
+
this.connection = undefined;
|
|
223
|
+
}
|
|
224
|
+
if (this.instance) {
|
|
225
|
+
this.instance.closeSync();
|
|
226
|
+
this.instance = undefined;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
//# sourceMappingURL=duckdb-storage.js.map
|