atlas-pipeline-mcp 1.0.23 → 1.0.26
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 +117 -4
- package/dist/common/error-handling.d.ts +86 -0
- package/dist/common/error-handling.d.ts.map +1 -0
- package/dist/common/error-handling.js +226 -0
- package/dist/common/error-handling.js.map +1 -0
- package/dist/mcp.js +232 -0
- package/dist/mcp.js.map +1 -1
- package/dist/tools/animation-studio.d.ts +83 -0
- package/dist/tools/animation-studio.d.ts.map +1 -0
- package/dist/tools/animation-studio.js +1064 -0
- package/dist/tools/animation-studio.js.map +1 -0
- package/dist/tools/api-design-consultant.d.ts +92 -0
- package/dist/tools/api-design-consultant.d.ts.map +1 -0
- package/dist/tools/api-design-consultant.js +374 -0
- package/dist/tools/api-design-consultant.js.map +1 -0
- package/dist/tools/api-integration-helper.d.ts +141 -0
- package/dist/tools/api-integration-helper.d.ts.map +1 -0
- package/dist/tools/api-integration-helper.js +907 -0
- package/dist/tools/api-integration-helper.js.map +1 -0
- package/dist/tools/css-architecture-wizard.d.ts +86 -0
- package/dist/tools/css-architecture-wizard.d.ts.map +1 -0
- package/dist/tools/css-architecture-wizard.js +790 -0
- package/dist/tools/css-architecture-wizard.js.map +1 -0
- package/dist/tools/debug/error-classifier.d.ts +14 -0
- package/dist/tools/debug/error-classifier.d.ts.map +1 -0
- package/dist/tools/debug/error-classifier.js +40 -0
- package/dist/tools/debug/error-classifier.js.map +1 -0
- package/dist/tools/debug/language-detector.d.ts +16 -0
- package/dist/tools/debug/language-detector.d.ts.map +1 -0
- package/dist/tools/debug/language-detector.js +67 -0
- package/dist/tools/debug/language-detector.js.map +1 -0
- package/dist/tools/debug/stack-parser.d.ts +25 -0
- package/dist/tools/debug/stack-parser.d.ts.map +1 -0
- package/dist/tools/debug/stack-parser.js +122 -0
- package/dist/tools/debug/stack-parser.js.map +1 -0
- package/dist/tools/dependencies.d.ts.map +1 -1
- package/dist/tools/dependencies.js +50 -25
- package/dist/tools/dependencies.js.map +1 -1
- package/dist/tools/frontend-performance-doctor.d.ts +108 -0
- package/dist/tools/frontend-performance-doctor.d.ts.map +1 -0
- package/dist/tools/frontend-performance-doctor.js +731 -0
- package/dist/tools/frontend-performance-doctor.js.map +1 -0
- package/dist/tools/performance-optimizer.d.ts +97 -0
- package/dist/tools/performance-optimizer.d.ts.map +1 -0
- package/dist/tools/performance-optimizer.js +295 -0
- package/dist/tools/performance-optimizer.js.map +1 -0
- package/dist/tools/security-scanner.d.ts +74 -0
- package/dist/tools/security-scanner.d.ts.map +1 -0
- package/dist/tools/security-scanner.js +290 -0
- package/dist/tools/security-scanner.js.map +1 -0
- package/dist/tools/senior-mentor.d.ts +81 -0
- package/dist/tools/senior-mentor.d.ts.map +1 -0
- package/dist/tools/senior-mentor.js +308 -0
- package/dist/tools/senior-mentor.js.map +1 -0
- package/dist/tools/state-management-architect.d.ts +77 -0
- package/dist/tools/state-management-architect.d.ts.map +1 -0
- package/dist/tools/state-management-architect.js +323 -0
- package/dist/tools/state-management-architect.js.map +1 -0
- package/dist/tools/test-utils.d.ts.map +1 -1
- package/dist/tools/test-utils.js +109 -56
- package/dist/tools/test-utils.js.map +1 -1
- package/dist/tools/ui-ux-designer.d.ts +91 -0
- package/dist/tools/ui-ux-designer.d.ts.map +1 -0
- package/dist/tools/ui-ux-designer.js +907 -0
- package/dist/tools/ui-ux-designer.js.map +1 -0
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -30,9 +30,63 @@ Works natively with **Cursor**, **Windsurf**, **Claude Desktop**, **GitHub Copil
|
|
|
30
30
|
|
|
31
31
|
---
|
|
32
32
|
|
|
33
|
-
## ✨ What's New in v1.0.
|
|
33
|
+
## ✨ What's New in v1.0.26
|
|
34
|
+
|
|
35
|
+
### 🎨 4 Powerful Frontend Developer Tools (NEW!)
|
|
36
|
+
|
|
37
|
+
These tools solve real-time frontend development problems with production-ready solutions:
|
|
38
|
+
|
|
39
|
+
<table>
|
|
40
|
+
<tr>
|
|
41
|
+
<td width="25%"><b>⚡ Performance Doctor</b></td>
|
|
42
|
+
<td>Detects React/Vue re-render issues, bundle bloat, memory leaks, and provides specific code fixes with improvement estimates</td>
|
|
43
|
+
</tr>
|
|
44
|
+
<tr>
|
|
45
|
+
<td><b>🎨 CSS Wizard</b></td>
|
|
46
|
+
<td>CSS architecture analyzer - detects specificity conflicts, generates design tokens, converts between BEM/Tailwind/CSS Modules/styled-components</td>
|
|
47
|
+
</tr>
|
|
48
|
+
<tr>
|
|
49
|
+
<td><b>✨ Animation Studio</b></td>
|
|
50
|
+
<td>Professional animation generator - CSS keyframes, Framer Motion, GSAP timelines, micro-interactions with accessibility support</td>
|
|
51
|
+
</tr>
|
|
52
|
+
<tr>
|
|
53
|
+
<td><b>🔌 API Helper</b></td>
|
|
54
|
+
<td>API integration assistant - generates TypeScript types, React Query/SWR hooks, mock data, Zod schemas, and error handling</td>
|
|
55
|
+
</tr>
|
|
56
|
+
</table>
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Previous Releases
|
|
34
61
|
|
|
35
|
-
###
|
|
62
|
+
### v1.0.25 - 5 Senior Developer Tools
|
|
63
|
+
|
|
64
|
+
<table>
|
|
65
|
+
<tr>
|
|
66
|
+
<td width="25%"><b>🧠 Senior Mentor</b></td>
|
|
67
|
+
<td>Architectural guidance from a 15+ year veteran perspective with trade-off analysis and senior lessons</td>
|
|
68
|
+
</tr>
|
|
69
|
+
<tr>
|
|
70
|
+
<td><b>⚡ Performance Optimizer</b></td>
|
|
71
|
+
<td>Deep performance analysis with Web Vitals optimization and bottleneck detection</td>
|
|
72
|
+
</tr>
|
|
73
|
+
<tr>
|
|
74
|
+
<td><b>🔒 Security Scanner</b></td>
|
|
75
|
+
<td>Enterprise-grade vulnerability detection with compliance assessment (GDPR, CCPA, HIPAA, PCI-DSS)</td>
|
|
76
|
+
</tr>
|
|
77
|
+
<tr>
|
|
78
|
+
<td><b>📦 State Management Architect</b></td>
|
|
79
|
+
<td>Pattern comparison and scalability analysis for Redux, Zustand, Jotai, Recoil, and more</td>
|
|
80
|
+
</tr>
|
|
81
|
+
<tr>
|
|
82
|
+
<td><b>🏗️ API Design Consultant</b></td>
|
|
83
|
+
<td>RESTful and GraphQL API design review with best practices and documentation templates</td>
|
|
84
|
+
</tr>
|
|
85
|
+
</table>
|
|
86
|
+
|
|
87
|
+
### Previous Releases (v1.0.23)
|
|
88
|
+
|
|
89
|
+
#### Advanced AI/ML Tools (4)
|
|
36
90
|
|
|
37
91
|
<table>
|
|
38
92
|
<tr>
|
|
@@ -92,6 +146,10 @@ Works natively with **Cursor**, **Windsurf**, **Claude Desktop**, **GitHub Copil
|
|
|
92
146
|
|
|
93
147
|
---
|
|
94
148
|
|
|
149
|
+
## ✨ What's New in v1.0.23
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
95
153
|
## 🎯 Key Features
|
|
96
154
|
|
|
97
155
|
<table>
|
|
@@ -120,7 +178,7 @@ Works natively with **Cursor**, **Windsurf**, **Claude Desktop**, **GitHub Copil
|
|
|
120
178
|
### 🌟 Why Atlas?
|
|
121
179
|
|
|
122
180
|
- **Zero Config**: No API keys required - uses your IDE's built-in AI (Copilot/Cursor)
|
|
123
|
-
- **
|
|
181
|
+
- **23 Professional Tools**: 13 core + 4 advanced AI/ML + 5 senior developer + 1 UI/UX designer
|
|
124
182
|
- **Agentic Workflow**: DAG-based task decomposition
|
|
125
183
|
- **Context Aware**: Project structure, dependencies, git history analysis
|
|
126
184
|
- **High Performance**: LRU caching, request deduplication, parallel execution
|
|
@@ -148,7 +206,7 @@ Restart your editor. You should see the Atlas server connected in your MCP setti
|
|
|
148
206
|
|
|
149
207
|
---
|
|
150
208
|
|
|
151
|
-
## 🛠️ All Available Tools (
|
|
209
|
+
## 🛠️ All Available Tools (27 Total)
|
|
152
210
|
|
|
153
211
|
### 🔥 Advanced AI/ML Tools
|
|
154
212
|
|
|
@@ -225,6 +283,61 @@ Restart your editor. You should see the Atlas server connected in your MCP setti
|
|
|
225
283
|
</tr>
|
|
226
284
|
</table>
|
|
227
285
|
|
|
286
|
+
### 🧠 Advanced Senior Developer Tools (NEW!)
|
|
287
|
+
|
|
288
|
+
<table>
|
|
289
|
+
<tr>
|
|
290
|
+
<td width="30%"><code>atlas_senior_mentor</code></td>
|
|
291
|
+
<td><b>Senior Mentor</b><br/>Architectural guidance from 15+ year veteran perspective with trade-off analysis and senior lessons</td>
|
|
292
|
+
</tr>
|
|
293
|
+
<tr>
|
|
294
|
+
<td><code>atlas_performance_optimizer</code></td>
|
|
295
|
+
<td><b>Performance Optimizer</b><br/>Deep performance analysis with Web Vitals optimization and bottleneck detection</td>
|
|
296
|
+
</tr>
|
|
297
|
+
<tr>
|
|
298
|
+
<td><code>atlas_security_scanner</code></td>
|
|
299
|
+
<td><b>Security Scanner Pro</b><br/>Enterprise-grade vulnerability detection with compliance assessment (GDPR, CCPA, HIPAA, PCI-DSS)</td>
|
|
300
|
+
</tr>
|
|
301
|
+
<tr>
|
|
302
|
+
<td><code>atlas_state_architect</code></td>
|
|
303
|
+
<td><b>State Management Architect</b><br/>Pattern comparison and scalability analysis for Redux, Zustand, Jotai, Recoil</td>
|
|
304
|
+
</tr>
|
|
305
|
+
<tr>
|
|
306
|
+
<td><code>atlas_api_consultant</code></td>
|
|
307
|
+
<td><b>API Design Consultant</b><br/>RESTful and GraphQL API design review with best practices and documentation templates</td>
|
|
308
|
+
</tr>
|
|
309
|
+
</table>
|
|
310
|
+
|
|
311
|
+
### 🎨 Design & UI/UX Tools
|
|
312
|
+
|
|
313
|
+
<table>
|
|
314
|
+
<tr>
|
|
315
|
+
<td width="30%"><code>atlas_ui_ux_designer</code></td>
|
|
316
|
+
<td><b>UI/UX Designer</b><br/>Find best design inspirations online, generate multiple design options with images, and create production-ready code. Supports React, Vue, HTML, Svelte with accessibility guidance.</td>
|
|
317
|
+
</tr>
|
|
318
|
+
</table>
|
|
319
|
+
|
|
320
|
+
### 🚀 Frontend Developer Tools (NEW in v1.0.26!)
|
|
321
|
+
|
|
322
|
+
<table>
|
|
323
|
+
<tr>
|
|
324
|
+
<td width="30%"><code>atlas_performance_doctor</code></td>
|
|
325
|
+
<td><b>Frontend Performance Doctor</b><br/>Detects React/Vue re-render issues, bundle bloat, memory leaks, Core Web Vitals issues. Provides specific code fixes with improvement estimates (e.g., "30-50% fewer re-renders").</td>
|
|
326
|
+
</tr>
|
|
327
|
+
<tr>
|
|
328
|
+
<td><code>atlas_css_wizard</code></td>
|
|
329
|
+
<td><b>CSS Architecture Wizard</b><br/>Analyzes CSS specificity conflicts, generates design tokens, converts between BEM/Tailwind/CSS Modules/styled-components/Emotion. Finds unused CSS and duplicates.</td>
|
|
330
|
+
</tr>
|
|
331
|
+
<tr>
|
|
332
|
+
<td><code>atlas_animation_studio</code></td>
|
|
333
|
+
<td><b>Animation Studio</b><br/>Professional animation generator with 30+ presets. Creates CSS keyframes, Framer Motion, GSAP, React Spring, and Anime.js code. Includes micro-interactions, scroll animations, and accessibility support.</td>
|
|
334
|
+
</tr>
|
|
335
|
+
<tr>
|
|
336
|
+
<td><code>atlas_api_helper</code></td>
|
|
337
|
+
<td><b>API Integration Helper</b><br/>Generates TypeScript types from API responses, React Query/SWR hooks, MSW mock handlers, Zod validation schemas, and complete API clients with error handling.</td>
|
|
338
|
+
</tr>
|
|
339
|
+
</table>
|
|
340
|
+
|
|
228
341
|
### 🚀 Development Productivity Tools
|
|
229
342
|
|
|
230
343
|
<table>
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Common Error Handling and Validation Utilities
|
|
3
|
+
* Centralized error handling to improve reliability across all tools
|
|
4
|
+
*/
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
export declare class ValidationError extends Error {
|
|
7
|
+
readonly field?: string | undefined;
|
|
8
|
+
constructor(message: string, field?: string | undefined);
|
|
9
|
+
}
|
|
10
|
+
export declare class FileSystemError extends Error {
|
|
11
|
+
readonly path?: string | undefined;
|
|
12
|
+
constructor(message: string, path?: string | undefined);
|
|
13
|
+
}
|
|
14
|
+
export declare class LLMProviderError extends Error {
|
|
15
|
+
readonly provider?: string | undefined;
|
|
16
|
+
constructor(message: string, provider?: string | undefined);
|
|
17
|
+
}
|
|
18
|
+
export declare class TimeoutError extends Error {
|
|
19
|
+
readonly timeoutMs?: number | undefined;
|
|
20
|
+
constructor(message: string, timeoutMs?: number | undefined);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Validate and parse input with Zod schema
|
|
24
|
+
*/
|
|
25
|
+
export declare function validateInput<T>(schema: z.ZodSchema<T>, data: unknown, errorMessage?: string): T;
|
|
26
|
+
/**
|
|
27
|
+
* Safely validate file path exists and is accessible
|
|
28
|
+
*/
|
|
29
|
+
export declare function validatePath(path: string, type?: 'file' | 'directory'): Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* Validate required fields are present
|
|
32
|
+
*/
|
|
33
|
+
export declare function requireFields<T extends Record<string, unknown>>(obj: T, fields: (keyof T)[]): void;
|
|
34
|
+
/**
|
|
35
|
+
* Wrap async function with error handling and logging
|
|
36
|
+
*/
|
|
37
|
+
export declare function withErrorHandling<T extends (...args: any[]) => Promise<any>>(fn: T, errorMessage?: string): T;
|
|
38
|
+
/**
|
|
39
|
+
* Retry async operation with exponential backoff
|
|
40
|
+
*/
|
|
41
|
+
export declare function withRetry<T>(fn: () => Promise<T>, options?: {
|
|
42
|
+
maxAttempts?: number;
|
|
43
|
+
delayMs?: number;
|
|
44
|
+
backoffMultiplier?: number;
|
|
45
|
+
onRetry?: (attempt: number, error: Error) => void;
|
|
46
|
+
}): Promise<T>;
|
|
47
|
+
/**
|
|
48
|
+
* Add timeout to async operation
|
|
49
|
+
*/
|
|
50
|
+
export declare function withTimeout<T>(fn: () => Promise<T>, timeoutMs: number, errorMessage?: string): Promise<T>;
|
|
51
|
+
/**
|
|
52
|
+
* Safe JSON parse with error handling
|
|
53
|
+
*/
|
|
54
|
+
export declare function safeJsonParse<T = unknown>(json: string, defaultValue?: T): T | undefined;
|
|
55
|
+
/**
|
|
56
|
+
* Safe async operation with fallback
|
|
57
|
+
*/
|
|
58
|
+
export declare function safeAsync<T>(fn: () => Promise<T>, fallback: T): Promise<T>;
|
|
59
|
+
/**
|
|
60
|
+
* Sanitize user input to prevent injection attacks
|
|
61
|
+
*/
|
|
62
|
+
export declare function sanitizeInput(input: string): string;
|
|
63
|
+
/**
|
|
64
|
+
* Validate and sanitize file path
|
|
65
|
+
*/
|
|
66
|
+
export declare function sanitizePath(path: string): string;
|
|
67
|
+
export type Result<T, E = Error> = {
|
|
68
|
+
success: true;
|
|
69
|
+
data: T;
|
|
70
|
+
} | {
|
|
71
|
+
success: false;
|
|
72
|
+
error: E;
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* Create success result
|
|
76
|
+
*/
|
|
77
|
+
export declare function success<T>(data: T): Result<T, never>;
|
|
78
|
+
/**
|
|
79
|
+
* Create error result
|
|
80
|
+
*/
|
|
81
|
+
export declare function failure<E = Error>(error: E): Result<never, E>;
|
|
82
|
+
/**
|
|
83
|
+
* Wrap function to return Result type
|
|
84
|
+
*/
|
|
85
|
+
export declare function tryAsync<T>(fn: () => Promise<T>): Promise<Result<T>>;
|
|
86
|
+
//# sourceMappingURL=error-handling.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-handling.d.ts","sourceRoot":"","sources":["../../src/common/error-handling.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Common Error Handling and Validation Utilities
|
|
3
|
+
* Centralized error handling to improve reliability across all tools
|
|
4
|
+
*/
|
|
5
|
+
import { logger } from '../utils.js';
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
// ============================================================================
|
|
8
|
+
// Custom Error Classes
|
|
9
|
+
// ============================================================================
|
|
10
|
+
export class ValidationError extends Error {
|
|
11
|
+
field;
|
|
12
|
+
constructor(message, field) {
|
|
13
|
+
super(message);
|
|
14
|
+
this.field = field;
|
|
15
|
+
this.name = 'ValidationError';
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export class FileSystemError extends Error {
|
|
19
|
+
path;
|
|
20
|
+
constructor(message, path) {
|
|
21
|
+
super(message);
|
|
22
|
+
this.path = path;
|
|
23
|
+
this.name = 'FileSystemError';
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export class LLMProviderError extends Error {
|
|
27
|
+
provider;
|
|
28
|
+
constructor(message, provider) {
|
|
29
|
+
super(message);
|
|
30
|
+
this.provider = provider;
|
|
31
|
+
this.name = 'LLMProviderError';
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export class TimeoutError extends Error {
|
|
35
|
+
timeoutMs;
|
|
36
|
+
constructor(message, timeoutMs) {
|
|
37
|
+
super(message);
|
|
38
|
+
this.timeoutMs = timeoutMs;
|
|
39
|
+
this.name = 'TimeoutError';
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
// ============================================================================
|
|
43
|
+
// Validation Helpers
|
|
44
|
+
// ============================================================================
|
|
45
|
+
/**
|
|
46
|
+
* Validate and parse input with Zod schema
|
|
47
|
+
*/
|
|
48
|
+
export function validateInput(schema, data, errorMessage) {
|
|
49
|
+
try {
|
|
50
|
+
return schema.parse(data);
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
if (error instanceof z.ZodError) {
|
|
54
|
+
const issues = error.issues.map(i => `${i.path.join('.')}: ${i.message}`).join(', ');
|
|
55
|
+
throw new ValidationError(errorMessage || `Validation failed: ${issues}`);
|
|
56
|
+
}
|
|
57
|
+
throw error;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Safely validate file path exists and is accessible
|
|
62
|
+
*/
|
|
63
|
+
export async function validatePath(path, type = 'file') {
|
|
64
|
+
const { promises: fs } = await import('fs');
|
|
65
|
+
try {
|
|
66
|
+
const stats = await fs.stat(path);
|
|
67
|
+
if (type === 'file' && !stats.isFile()) {
|
|
68
|
+
throw new FileSystemError(`Path is not a file: ${path}`, path);
|
|
69
|
+
}
|
|
70
|
+
if (type === 'directory' && !stats.isDirectory()) {
|
|
71
|
+
throw new FileSystemError(`Path is not a directory: ${path}`, path);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
if (error.code === 'ENOENT') {
|
|
76
|
+
throw new FileSystemError(`Path does not exist: ${path}`, path);
|
|
77
|
+
}
|
|
78
|
+
if (error.code === 'EACCES') {
|
|
79
|
+
throw new FileSystemError(`Permission denied: ${path}`, path);
|
|
80
|
+
}
|
|
81
|
+
throw error;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Validate required fields are present
|
|
86
|
+
*/
|
|
87
|
+
export function requireFields(obj, fields) {
|
|
88
|
+
const missing = fields.filter(field => obj[field] === undefined || obj[field] === null);
|
|
89
|
+
if (missing.length > 0) {
|
|
90
|
+
throw new ValidationError(`Missing required fields: ${missing.join(', ')}`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// ============================================================================
|
|
94
|
+
// Error Handling Wrappers
|
|
95
|
+
// ============================================================================
|
|
96
|
+
/**
|
|
97
|
+
* Wrap async function with error handling and logging
|
|
98
|
+
*/
|
|
99
|
+
export function withErrorHandling(fn, errorMessage) {
|
|
100
|
+
return (async (...args) => {
|
|
101
|
+
try {
|
|
102
|
+
return await fn(...args);
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
const message = errorMessage || `Operation failed: ${fn.name}`;
|
|
106
|
+
logger.error({ error, args }, message);
|
|
107
|
+
if (error instanceof Error) {
|
|
108
|
+
throw error;
|
|
109
|
+
}
|
|
110
|
+
throw new Error(`${message}: ${String(error)}`);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Retry async operation with exponential backoff
|
|
116
|
+
*/
|
|
117
|
+
export async function withRetry(fn, options = {}) {
|
|
118
|
+
const { maxAttempts = 3, delayMs = 1000, backoffMultiplier = 2, onRetry, } = options;
|
|
119
|
+
let lastError;
|
|
120
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
121
|
+
try {
|
|
122
|
+
return await fn();
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
126
|
+
if (attempt < maxAttempts) {
|
|
127
|
+
const delay = delayMs * Math.pow(backoffMultiplier, attempt - 1);
|
|
128
|
+
if (onRetry) {
|
|
129
|
+
onRetry(attempt, lastError);
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
logger.warn({ attempt, maxAttempts, delay, error: lastError }, 'Retrying after error');
|
|
133
|
+
}
|
|
134
|
+
await new Promise(resolve => setTimeout(resolve, delay));
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
throw lastError || new Error('Operation failed after retries');
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Add timeout to async operation
|
|
142
|
+
*/
|
|
143
|
+
export async function withTimeout(fn, timeoutMs, errorMessage) {
|
|
144
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
145
|
+
setTimeout(() => {
|
|
146
|
+
reject(new TimeoutError(errorMessage || `Operation timed out after ${timeoutMs}ms`, timeoutMs));
|
|
147
|
+
}, timeoutMs);
|
|
148
|
+
});
|
|
149
|
+
return Promise.race([fn(), timeoutPromise]);
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Safe JSON parse with error handling
|
|
153
|
+
*/
|
|
154
|
+
export function safeJsonParse(json, defaultValue) {
|
|
155
|
+
try {
|
|
156
|
+
return JSON.parse(json);
|
|
157
|
+
}
|
|
158
|
+
catch (error) {
|
|
159
|
+
logger.warn({ error }, 'Failed to parse JSON');
|
|
160
|
+
return defaultValue;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Safe async operation with fallback
|
|
165
|
+
*/
|
|
166
|
+
export async function safeAsync(fn, fallback) {
|
|
167
|
+
try {
|
|
168
|
+
return await fn();
|
|
169
|
+
}
|
|
170
|
+
catch (error) {
|
|
171
|
+
logger.warn({ error }, 'Async operation failed, using fallback');
|
|
172
|
+
return fallback;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
// ============================================================================
|
|
176
|
+
// Input Sanitization
|
|
177
|
+
// ============================================================================
|
|
178
|
+
/**
|
|
179
|
+
* Sanitize user input to prevent injection attacks
|
|
180
|
+
*/
|
|
181
|
+
export function sanitizeInput(input) {
|
|
182
|
+
return input
|
|
183
|
+
.replace(/[<>]/g, '') // Remove potential HTML tags
|
|
184
|
+
.replace(/[';]/g, '') // Remove potential SQL injection chars
|
|
185
|
+
.trim()
|
|
186
|
+
.substring(0, 10000); // Limit length
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Validate and sanitize file path
|
|
190
|
+
*/
|
|
191
|
+
export function sanitizePath(path) {
|
|
192
|
+
// Remove path traversal attempts
|
|
193
|
+
const sanitized = path
|
|
194
|
+
.replace(/\.\./g, '')
|
|
195
|
+
.replace(/\/\//g, '/')
|
|
196
|
+
.trim();
|
|
197
|
+
if (sanitized.length === 0) {
|
|
198
|
+
throw new ValidationError('Invalid path: empty after sanitization');
|
|
199
|
+
}
|
|
200
|
+
return sanitized;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Create success result
|
|
204
|
+
*/
|
|
205
|
+
export function success(data) {
|
|
206
|
+
return { success: true, data };
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Create error result
|
|
210
|
+
*/
|
|
211
|
+
export function failure(error) {
|
|
212
|
+
return { success: false, error };
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Wrap function to return Result type
|
|
216
|
+
*/
|
|
217
|
+
export async function tryAsync(fn) {
|
|
218
|
+
try {
|
|
219
|
+
const data = await fn();
|
|
220
|
+
return success(data);
|
|
221
|
+
}
|
|
222
|
+
catch (error) {
|
|
223
|
+
return failure(error instanceof Error ? error : new Error(String(error)));
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
//# sourceMappingURL=error-handling.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-handling.js","sourceRoot":"","sources":["../../src/common/error-handling.ts"],"names":[],"mappings":"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"}
|