driftdetect-dashboard 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/dist/client/assets/main-DQAs4VF9.js +59 -0
  2. package/dist/client/assets/main-DQAs4VF9.js.map +1 -0
  3. package/dist/client/assets/main-Du5_09U3.css +2 -0
  4. package/dist/client/index.html +19 -0
  5. package/dist/server/api-routes.d.ts +50 -0
  6. package/dist/server/api-routes.d.ts.map +1 -0
  7. package/dist/server/api-routes.js +478 -0
  8. package/dist/server/api-routes.js.map +1 -0
  9. package/dist/server/dashboard-server.d.ts +64 -0
  10. package/dist/server/dashboard-server.d.ts.map +1 -0
  11. package/dist/server/dashboard-server.js +154 -0
  12. package/dist/server/dashboard-server.js.map +1 -0
  13. package/dist/server/drift-data-reader.d.ts +411 -0
  14. package/dist/server/drift-data-reader.d.ts.map +1 -0
  15. package/dist/server/drift-data-reader.js +1151 -0
  16. package/dist/server/drift-data-reader.js.map +1 -0
  17. package/dist/server/express-app.d.ts +24 -0
  18. package/dist/server/express-app.d.ts.map +1 -0
  19. package/dist/server/express-app.js +74 -0
  20. package/dist/server/express-app.js.map +1 -0
  21. package/dist/server/index.d.ts +20 -0
  22. package/dist/server/index.d.ts.map +1 -0
  23. package/dist/server/index.js +14 -0
  24. package/dist/server/index.js.map +1 -0
  25. package/dist/server/pattern-watcher.d.ts +55 -0
  26. package/dist/server/pattern-watcher.d.ts.map +1 -0
  27. package/dist/server/pattern-watcher.js +157 -0
  28. package/dist/server/pattern-watcher.js.map +1 -0
  29. package/dist/server/websocket-server.d.ts +83 -0
  30. package/dist/server/websocket-server.d.ts.map +1 -0
  31. package/dist/server/websocket-server.js +189 -0
  32. package/dist/server/websocket-server.js.map +1 -0
  33. package/package.json +86 -0
@@ -0,0 +1,64 @@
1
+ /**
2
+ * DashboardServer
3
+ *
4
+ * Main server class that orchestrates Express and WebSocket servers
5
+ * for the Drift Dashboard.
6
+ *
7
+ * @requirements 1.1 - Start an Express server on localhost:3847
8
+ * @requirements 1.2 - Start on the specified port
9
+ * @requirements 1.3 - Automatically open the default browser to the dashboard URL
10
+ * @requirements 1.5 - Handle port conflict errors gracefully
11
+ */
12
+ import { type DashboardViolation } from './drift-data-reader.js';
13
+ export interface DashboardServerOptions {
14
+ /** Port to listen on (default: 3847) */
15
+ port: number;
16
+ /** Path to the .drift directory */
17
+ driftDir: string;
18
+ /** Whether to automatically open browser on start */
19
+ openBrowser: boolean;
20
+ }
21
+ export declare class DashboardServer {
22
+ private readonly options;
23
+ private readonly reader;
24
+ private readonly wsManager;
25
+ private readonly patternWatcher;
26
+ private server;
27
+ constructor(options: DashboardServerOptions);
28
+ /**
29
+ * Get the configured port
30
+ */
31
+ get port(): number;
32
+ /**
33
+ * Get the drift directory path
34
+ */
35
+ get driftDir(): string;
36
+ /**
37
+ * Check if the server is running
38
+ */
39
+ get isRunning(): boolean;
40
+ /**
41
+ * Get the number of connected WebSocket clients
42
+ */
43
+ get connectedClients(): number;
44
+ /**
45
+ * Start the dashboard server
46
+ * @requirements 1.1, 1.2, 1.3
47
+ */
48
+ start(): Promise<void>;
49
+ /**
50
+ * Stop the dashboard server
51
+ */
52
+ stop(): Promise<void>;
53
+ /**
54
+ * Broadcast a violation to all connected WebSocket clients
55
+ * @requirements 2.3
56
+ */
57
+ broadcastViolation(violation: DashboardViolation): void;
58
+ /**
59
+ * Open the default browser to the dashboard URL
60
+ * @requirements 1.3
61
+ */
62
+ private openBrowser;
63
+ }
64
+ //# sourceMappingURL=dashboard-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard-server.d.ts","sourceRoot":"","sources":["../../src/server/dashboard-server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,EAAmB,KAAK,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AASlF,MAAM,WAAW,sBAAsB;IACrC,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,mCAAmC;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,qDAAqD;IACrD,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyB;IACjD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkB;IACzC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAmB;IAC7C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiB;IAChD,OAAO,CAAC,MAAM,CAAuB;gBAEzB,OAAO,EAAE,sBAAsB;IAgB3C;;OAEG;IACH,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED;;OAEG;IACH,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED;;OAEG;IACH,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED;;OAEG;IACH,IAAI,gBAAgB,IAAI,MAAM,CAE7B;IAED;;;OAGG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAmD5B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA0B3B;;;OAGG;IACH,kBAAkB,CAAC,SAAS,EAAE,kBAAkB,GAAG,IAAI;IAIvD;;;OAGG;YACW,WAAW;CAK1B"}
@@ -0,0 +1,154 @@
1
+ /**
2
+ * DashboardServer
3
+ *
4
+ * Main server class that orchestrates Express and WebSocket servers
5
+ * for the Drift Dashboard.
6
+ *
7
+ * @requirements 1.1 - Start an Express server on localhost:3847
8
+ * @requirements 1.2 - Start on the specified port
9
+ * @requirements 1.3 - Automatically open the default browser to the dashboard URL
10
+ * @requirements 1.5 - Handle port conflict errors gracefully
11
+ */
12
+ import * as path from 'node:path';
13
+ import { fileURLToPath } from 'node:url';
14
+ import { DriftDataReader } from './drift-data-reader.js';
15
+ import { createExpressApp } from './express-app.js';
16
+ import { WebSocketManager } from './websocket-server.js';
17
+ import { PatternWatcher } from './pattern-watcher.js';
18
+ // Get the directory of this file for resolving static files
19
+ const __filename = fileURLToPath(import.meta.url);
20
+ const __dirname = path.dirname(__filename);
21
+ export class DashboardServer {
22
+ options;
23
+ reader;
24
+ wsManager;
25
+ patternWatcher;
26
+ server = null;
27
+ constructor(options) {
28
+ this.options = options;
29
+ this.reader = new DriftDataReader(options.driftDir);
30
+ this.wsManager = new WebSocketManager();
31
+ this.patternWatcher = new PatternWatcher({ driftDir: options.driftDir });
32
+ // Wire up pattern watcher to WebSocket broadcasts
33
+ this.patternWatcher.on('change', (event) => {
34
+ this.wsManager.broadcastPatternsChanged({
35
+ type: event.type,
36
+ category: event.category,
37
+ status: event.status,
38
+ });
39
+ });
40
+ }
41
+ /**
42
+ * Get the configured port
43
+ */
44
+ get port() {
45
+ return this.options.port;
46
+ }
47
+ /**
48
+ * Get the drift directory path
49
+ */
50
+ get driftDir() {
51
+ return this.options.driftDir;
52
+ }
53
+ /**
54
+ * Check if the server is running
55
+ */
56
+ get isRunning() {
57
+ return this.server !== null;
58
+ }
59
+ /**
60
+ * Get the number of connected WebSocket clients
61
+ */
62
+ get connectedClients() {
63
+ return this.wsManager.clientCount;
64
+ }
65
+ /**
66
+ * Start the dashboard server
67
+ * @requirements 1.1, 1.2, 1.3
68
+ */
69
+ async start() {
70
+ if (this.server) {
71
+ throw new Error('Server is already running');
72
+ }
73
+ // Resolve static files directory (dist/client relative to dist/server)
74
+ const staticDir = path.resolve(__dirname, '..', 'client');
75
+ // Create Express app
76
+ const app = createExpressApp({
77
+ reader: this.reader,
78
+ staticDir,
79
+ enableCors: true,
80
+ });
81
+ // Create HTTP server
82
+ return new Promise((resolve, reject) => {
83
+ this.server = app.listen(this.options.port, async () => {
84
+ console.log(`Dashboard server running at http://localhost:${this.options.port}`);
85
+ // Attach WebSocket server
86
+ this.wsManager.attach(this.server);
87
+ // Start pattern watcher for realtime updates
88
+ this.patternWatcher.start();
89
+ // Open browser if requested
90
+ if (this.options.openBrowser) {
91
+ try {
92
+ await this.openBrowser();
93
+ }
94
+ catch (error) {
95
+ // Don't fail if browser can't be opened
96
+ console.warn('Could not open browser:', error);
97
+ }
98
+ }
99
+ resolve();
100
+ });
101
+ this.server.on('error', (error) => {
102
+ this.server = null;
103
+ if (error.code === 'EADDRINUSE') {
104
+ reject(new Error(`Port ${this.options.port} is already in use. Try a different port with --port <number>`));
105
+ }
106
+ else {
107
+ reject(error);
108
+ }
109
+ });
110
+ });
111
+ }
112
+ /**
113
+ * Stop the dashboard server
114
+ */
115
+ async stop() {
116
+ if (!this.server) {
117
+ return;
118
+ }
119
+ // Stop pattern watcher
120
+ this.patternWatcher.stop();
121
+ // Close WebSocket connections
122
+ this.wsManager.close();
123
+ // Close HTTP server
124
+ return new Promise((resolve, reject) => {
125
+ this.server.close((error) => {
126
+ this.server = null;
127
+ if (error) {
128
+ reject(error);
129
+ }
130
+ else {
131
+ console.log('Dashboard server stopped');
132
+ resolve();
133
+ }
134
+ });
135
+ });
136
+ }
137
+ /**
138
+ * Broadcast a violation to all connected WebSocket clients
139
+ * @requirements 2.3
140
+ */
141
+ broadcastViolation(violation) {
142
+ this.wsManager.broadcastViolation(violation);
143
+ }
144
+ /**
145
+ * Open the default browser to the dashboard URL
146
+ * @requirements 1.3
147
+ */
148
+ async openBrowser() {
149
+ // Dynamic import to avoid issues with ESM
150
+ const open = await import('open');
151
+ await open.default(`http://localhost:${this.options.port}`);
152
+ }
153
+ }
154
+ //# sourceMappingURL=dashboard-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard-server.js","sourceRoot":"","sources":["../../src/server/dashboard-server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,411 @@
1
+ /**
2
+ * DriftDataReader
3
+ *
4
+ * Reads and parses data from the .drift/ folder structure.
5
+ * Provides methods for accessing patterns, violations, files, and configuration.
6
+ *
7
+ * @requirements 1.6 - THE Dashboard_Server SHALL read pattern and violation data from the existing `.drift/` folder structure
8
+ * @requirements 8.1 - THE Dashboard_Server SHALL expose GET `/api/patterns` to list all patterns
9
+ * @requirements 8.2 - THE Dashboard_Server SHALL expose GET `/api/patterns/:id` to get pattern details with locations
10
+ * @requirements 8.6 - THE Dashboard_Server SHALL expose GET `/api/violations` to list all violations
11
+ * @requirements 8.7 - THE Dashboard_Server SHALL expose GET `/api/files` to get the file tree
12
+ * @requirements 8.8 - THE Dashboard_Server SHALL expose GET `/api/files/:path` to get patterns and violations for a specific file
13
+ * @requirements 8.9 - THE Dashboard_Server SHALL expose GET `/api/stats` to get overview statistics
14
+ */
15
+ import type { PatternStatus, PatternCategory, Severity } from 'driftdetect-core';
16
+ export interface PatternQuery {
17
+ category?: string;
18
+ status?: string;
19
+ minConfidence?: number;
20
+ search?: string;
21
+ }
22
+ export interface ViolationQuery {
23
+ severity?: string;
24
+ file?: string;
25
+ patternId?: string;
26
+ search?: string;
27
+ }
28
+ /**
29
+ * Pattern representation for the dashboard API
30
+ */
31
+ export interface DashboardPattern {
32
+ id: string;
33
+ name: string;
34
+ category: string;
35
+ subcategory: string;
36
+ status: PatternStatus;
37
+ description: string;
38
+ confidence: {
39
+ score: number;
40
+ level: string;
41
+ };
42
+ locationCount: number;
43
+ outlierCount: number;
44
+ severity: string;
45
+ metadata: {
46
+ firstSeen: string;
47
+ lastSeen: string;
48
+ tags?: string[] | undefined;
49
+ };
50
+ }
51
+ /**
52
+ * Pattern with full location details for the dashboard API
53
+ */
54
+ export interface DashboardPatternWithLocations extends DashboardPattern {
55
+ locations: SemanticLocation[];
56
+ outliers: OutlierWithDetails[];
57
+ }
58
+ /**
59
+ * Semantic location for the dashboard
60
+ */
61
+ export interface SemanticLocation {
62
+ file: string;
63
+ range: {
64
+ start: {
65
+ line: number;
66
+ character: number;
67
+ };
68
+ end: {
69
+ line: number;
70
+ character: number;
71
+ };
72
+ };
73
+ }
74
+ /**
75
+ * Outlier with reason details
76
+ */
77
+ export interface OutlierWithDetails extends SemanticLocation {
78
+ reason: string;
79
+ deviationScore?: number | undefined;
80
+ }
81
+ /**
82
+ * Violation representation for the dashboard API
83
+ */
84
+ export interface DashboardViolation {
85
+ id: string;
86
+ patternId: string;
87
+ patternName: string;
88
+ severity: string;
89
+ file: string;
90
+ range: {
91
+ start: {
92
+ line: number;
93
+ character: number;
94
+ };
95
+ end: {
96
+ line: number;
97
+ character: number;
98
+ };
99
+ };
100
+ message: string;
101
+ expected: string;
102
+ actual: string;
103
+ }
104
+ /**
105
+ * File tree node for hierarchical file structure
106
+ * @requirements 8.7 - GET `/api/files` to get the file tree
107
+ */
108
+ export interface FileTreeNode {
109
+ name: string;
110
+ path: string;
111
+ type: 'file' | 'directory';
112
+ children?: FileTreeNode[];
113
+ patternCount?: number;
114
+ violationCount?: number;
115
+ severity?: Severity;
116
+ }
117
+ /**
118
+ * File details with patterns and violations
119
+ * @requirements 8.8 - GET `/api/files/:path` to get patterns and violations for a specific file
120
+ */
121
+ export interface FileDetails {
122
+ path: string;
123
+ language: string;
124
+ lineCount: number;
125
+ patterns: Array<{
126
+ id: string;
127
+ name: string;
128
+ category: PatternCategory;
129
+ locations: SemanticLocation[];
130
+ }>;
131
+ violations: DashboardViolation[];
132
+ }
133
+ /**
134
+ * Drift configuration
135
+ * @requirements 8.10, 8.11 - Configuration management
136
+ */
137
+ export interface DriftConfig {
138
+ version: string;
139
+ detectors: DetectorConfigEntry[];
140
+ severityOverrides: Record<string, Severity>;
141
+ ignorePatterns: string[];
142
+ watchOptions?: {
143
+ debounce: number;
144
+ categories?: PatternCategory[];
145
+ };
146
+ }
147
+ /**
148
+ * Detector configuration entry
149
+ */
150
+ export interface DetectorConfigEntry {
151
+ id: string;
152
+ name: string;
153
+ enabled: boolean;
154
+ category: PatternCategory;
155
+ options?: Record<string, unknown>;
156
+ }
157
+ /**
158
+ * Dashboard statistics
159
+ * @requirements 8.9 - GET `/api/stats` to get overview statistics
160
+ */
161
+ export interface DashboardStats {
162
+ healthScore: number;
163
+ patterns: {
164
+ total: number;
165
+ byStatus: Record<PatternStatus, number>;
166
+ byCategory: Record<PatternCategory, number>;
167
+ };
168
+ violations: {
169
+ total: number;
170
+ bySeverity: Record<Severity, number>;
171
+ };
172
+ files: {
173
+ total: number;
174
+ scanned: number;
175
+ };
176
+ detectors: {
177
+ active: number;
178
+ total: number;
179
+ };
180
+ lastScan: string | null;
181
+ }
182
+ /**
183
+ * Contract representation for the dashboard API
184
+ */
185
+ export interface DashboardContract {
186
+ id: string;
187
+ method: string;
188
+ endpoint: string;
189
+ status: string;
190
+ backend: {
191
+ file: string;
192
+ line: number;
193
+ framework: string;
194
+ responseFields: Array<{
195
+ name: string;
196
+ type: string;
197
+ optional: boolean;
198
+ }>;
199
+ };
200
+ frontend: Array<{
201
+ file: string;
202
+ line: number;
203
+ library: string;
204
+ responseType?: string;
205
+ responseFields: Array<{
206
+ name: string;
207
+ type: string;
208
+ optional: boolean;
209
+ }>;
210
+ }>;
211
+ mismatches: Array<{
212
+ fieldPath: string;
213
+ mismatchType: string;
214
+ description: string;
215
+ severity: string;
216
+ }>;
217
+ mismatchCount: number;
218
+ confidence: {
219
+ score: number;
220
+ level: string;
221
+ };
222
+ metadata: {
223
+ firstSeen: string;
224
+ lastSeen: string;
225
+ verifiedAt?: string;
226
+ };
227
+ }
228
+ /**
229
+ * Contract statistics for the dashboard
230
+ */
231
+ export interface DashboardContractStats {
232
+ totalContracts: number;
233
+ byStatus: Record<string, number>;
234
+ byMethod: Record<string, number>;
235
+ totalMismatches: number;
236
+ mismatchesByType: Record<string, number>;
237
+ }
238
+ export declare class DriftDataReader {
239
+ private readonly driftDir;
240
+ private readonly patternsDir;
241
+ constructor(driftDir: string);
242
+ /**
243
+ * Get the drift directory path
244
+ */
245
+ get directory(): string;
246
+ /**
247
+ * Get all patterns, optionally filtered
248
+ *
249
+ * @requirements 8.1 - List all patterns
250
+ */
251
+ getPatterns(query?: PatternQuery): Promise<DashboardPattern[]>;
252
+ /**
253
+ * Get a single pattern by ID with all locations
254
+ *
255
+ * @requirements 8.2 - Get pattern details with locations
256
+ */
257
+ getPattern(id: string): Promise<DashboardPatternWithLocations | null>;
258
+ /**
259
+ * Get all violations, optionally filtered
260
+ *
261
+ * Violations are derived from pattern outliers.
262
+ *
263
+ * @requirements 8.6 - List all violations
264
+ */
265
+ getViolations(query?: ViolationQuery): Promise<DashboardViolation[]>;
266
+ /**
267
+ * Get dashboard statistics
268
+ * @requirements 8.9 - GET `/api/stats` to get overview statistics
269
+ */
270
+ getStats(): Promise<DashboardStats>;
271
+ /**
272
+ * Get the file tree structure
273
+ * @requirements 8.7 - GET `/api/files` to get the file tree
274
+ */
275
+ getFileTree(): Promise<FileTreeNode[]>;
276
+ /**
277
+ * Get details for a specific file
278
+ * @requirements 8.8 - GET `/api/files/:path` to get patterns and violations for a specific file
279
+ */
280
+ getFileDetails(filePath: string): Promise<FileDetails | null>;
281
+ /**
282
+ * Get configuration
283
+ * @requirements 8.10 - GET `/api/config` to get configuration
284
+ */
285
+ getConfig(): Promise<DriftConfig>;
286
+ /**
287
+ * Update configuration
288
+ * @requirements 8.11 - PUT `/api/config` to update configuration
289
+ */
290
+ updateConfig(partial: Partial<DriftConfig>): Promise<void>;
291
+ /**
292
+ * Approve a pattern - changes status to 'approved'
293
+ * @requirements 4.4 - Approve pattern
294
+ * @requirements 8.3 - POST `/api/patterns/:id/approve` to approve a pattern
295
+ */
296
+ approvePattern(id: string): Promise<void>;
297
+ /**
298
+ * Ignore a pattern - changes status to 'ignored'
299
+ * @requirements 4.5 - Ignore pattern
300
+ * @requirements 8.4 - POST `/api/patterns/:id/ignore` to ignore a pattern
301
+ */
302
+ ignorePattern(id: string): Promise<void>;
303
+ /**
304
+ * Delete a pattern - removes from storage
305
+ * @requirements 4.6 - Delete pattern
306
+ * @requirements 8.5 - DELETE `/api/patterns/:id` to delete a pattern
307
+ */
308
+ deletePattern(id: string): Promise<void>;
309
+ /**
310
+ * Convert a StoredPattern to DashboardPattern
311
+ */
312
+ private storedToDashboardPattern;
313
+ /**
314
+ * Convert a StoredPattern to DashboardPatternWithLocations
315
+ */
316
+ private storedToDashboardPatternWithLocations;
317
+ /**
318
+ * Convert an outlier to a violation
319
+ */
320
+ private outlierToViolation;
321
+ /**
322
+ * Filter patterns based on query
323
+ */
324
+ private filterPatterns;
325
+ /**
326
+ * Filter violations based on query
327
+ */
328
+ private filterViolations;
329
+ /**
330
+ * Calculate health score based on violations and patterns
331
+ *
332
+ * Health score formula:
333
+ * - Base score starts at 100
334
+ * - Deduct for violations by severity (error: -10, warning: -3, info: -1, hint: 0)
335
+ * - Bonus for approved patterns (shows intentional architecture)
336
+ * - Clamp to 0-100
337
+ */
338
+ private calculateHealthScore;
339
+ /**
340
+ * Build a hierarchical file tree from file information
341
+ */
342
+ private buildFileTree;
343
+ /**
344
+ * Sort file tree: directories first, then alphabetically
345
+ */
346
+ private sortFileTree;
347
+ /**
348
+ * Compare severity levels
349
+ * Returns positive if a > b, negative if a < b, 0 if equal
350
+ */
351
+ private compareSeverity;
352
+ /**
353
+ * Get programming language from file path
354
+ */
355
+ private getLanguageFromPath;
356
+ /**
357
+ * Change pattern status (move between status directories)
358
+ */
359
+ private changePatternStatus;
360
+ /**
361
+ * Find a pattern's location in the file system
362
+ */
363
+ private findPatternLocation;
364
+ /**
365
+ * Get default configuration
366
+ */
367
+ private getDefaultConfig;
368
+ /**
369
+ * Get code snippet from a file at a specific line with context
370
+ */
371
+ getCodeSnippet(filePath: string, line: number, contextLines?: number): Promise<{
372
+ code: string;
373
+ startLine: number;
374
+ endLine: number;
375
+ language: string;
376
+ } | null>;
377
+ /**
378
+ * Get all contracts, optionally filtered
379
+ */
380
+ getContracts(query?: {
381
+ status?: string;
382
+ method?: string;
383
+ hasMismatches?: boolean;
384
+ search?: string;
385
+ }): Promise<DashboardContract[]>;
386
+ /**
387
+ * Get a single contract by ID
388
+ */
389
+ getContract(id: string): Promise<DashboardContract | null>;
390
+ /**
391
+ * Get contract statistics
392
+ */
393
+ getContractStats(): Promise<DashboardContractStats>;
394
+ /**
395
+ * Verify a contract
396
+ */
397
+ verifyContract(id: string): Promise<void>;
398
+ /**
399
+ * Ignore a contract
400
+ */
401
+ ignoreContract(id: string): Promise<void>;
402
+ /**
403
+ * Change contract status
404
+ */
405
+ private changeContractStatus;
406
+ /**
407
+ * Filter contracts based on query
408
+ */
409
+ private filterContracts;
410
+ }
411
+ //# sourceMappingURL=drift-data-reader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drift-data-reader.d.ts","sourceRoot":"","sources":["../../src/server/drift-data-reader.ts"],"names":[],"mappings":"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"}