mcp-wordpress 2.4.2 → 2.5.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.
- package/README.md +114 -48
- package/dist/ajv-patch.js +34 -0
- package/dist/cache/CacheInvalidation.d.ts +3 -1
- package/dist/cache/CacheInvalidation.d.ts.map +1 -1
- package/dist/cache/CacheInvalidation.js +10 -4
- package/dist/cache/CacheInvalidation.js.map +1 -1
- package/dist/cache/CacheManager.d.ts +3 -2
- package/dist/cache/CacheManager.d.ts.map +1 -1
- package/dist/cache/CacheManager.js +11 -3
- package/dist/cache/CacheManager.js.map +1 -1
- package/dist/cache/HttpCacheWrapper.d.ts +7 -6
- package/dist/cache/HttpCacheWrapper.d.ts.map +1 -1
- package/dist/cache/HttpCacheWrapper.js +8 -5
- package/dist/cache/HttpCacheWrapper.js.map +1 -1
- package/dist/cache/__tests__/HttpCacheWrapper.test.js +6 -5
- package/dist/cache/__tests__/HttpCacheWrapper.test.js.map +1 -1
- package/dist/cache/index.d.ts +3 -3
- package/dist/cache/index.d.ts.map +1 -1
- package/dist/cache/index.js +1 -1
- package/dist/cache/index.js.map +1 -1
- package/dist/client/CachedWordPressClient.d.ts +23 -9
- package/dist/client/CachedWordPressClient.d.ts.map +1 -1
- package/dist/client/CachedWordPressClient.js +4 -1
- package/dist/client/CachedWordPressClient.js.map +1 -1
- package/dist/client/MockWordPressClient.d.ts +2 -1
- package/dist/client/MockWordPressClient.d.ts.map +1 -1
- package/dist/client/MockWordPressClient.js +3 -1
- package/dist/client/MockWordPressClient.js.map +1 -1
- package/dist/client/api.d.ts +17 -13
- package/dist/client/api.d.ts.map +1 -1
- package/dist/client/api.js +135 -30
- package/dist/client/api.js.map +1 -1
- package/dist/client/auth.d.ts.map +1 -1
- package/dist/client/auth.js +2 -3
- package/dist/client/auth.js.map +1 -1
- package/dist/client/managers/AuthenticationManager.d.ts +55 -2
- package/dist/client/managers/AuthenticationManager.d.ts.map +1 -1
- package/dist/client/managers/AuthenticationManager.js +269 -71
- package/dist/client/managers/AuthenticationManager.js.map +1 -1
- package/dist/client/managers/BaseManager.d.ts +3 -3
- package/dist/client/managers/BaseManager.d.ts.map +1 -1
- package/dist/client/managers/BaseManager.js +11 -5
- package/dist/client/managers/BaseManager.js.map +1 -1
- package/dist/client/managers/RequestManager.d.ts +2 -2
- package/dist/client/managers/RequestManager.d.ts.map +1 -1
- package/dist/client/managers/RequestManager.js +25 -12
- package/dist/client/managers/RequestManager.js.map +1 -1
- package/dist/config/Config.d.ts +155 -0
- package/dist/config/Config.d.ts.map +1 -0
- package/dist/config/Config.js +215 -0
- package/dist/config/Config.js.map +1 -0
- package/dist/config/ConfigurationSchema.d.ts +21 -21
- package/dist/config/ConfigurationSchema.d.ts.map +1 -1
- package/dist/config/ConfigurationSchema.js +19 -2
- package/dist/config/ConfigurationSchema.js.map +1 -1
- package/dist/config/ServerConfiguration.d.ts +2 -1
- package/dist/config/ServerConfiguration.d.ts.map +1 -1
- package/dist/config/ServerConfiguration.js +50 -41
- package/dist/config/ServerConfiguration.js.map +1 -1
- package/dist/docs/DocumentationGenerator.d.ts +9 -8
- package/dist/docs/DocumentationGenerator.d.ts.map +1 -1
- package/dist/docs/DocumentationGenerator.js +10 -7
- package/dist/docs/DocumentationGenerator.js.map +1 -1
- package/dist/docs/MarkdownFormatter.d.ts.map +1 -1
- package/dist/docs/MarkdownFormatter.js +3 -2
- package/dist/docs/MarkdownFormatter.js.map +1 -1
- package/dist/dxt-entry.cjs +81 -0
- package/dist/dxt-entry.js +15 -14
- package/dist/dxt-entry.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +37 -21
- package/dist/index.js.map +1 -1
- package/dist/performance/MetricsCollector.d.ts +13 -7
- package/dist/performance/MetricsCollector.d.ts.map +1 -1
- package/dist/performance/MetricsCollector.js +69 -27
- package/dist/performance/MetricsCollector.js.map +1 -1
- package/dist/performance/PerformanceAnalytics.d.ts +8 -2
- package/dist/performance/PerformanceAnalytics.d.ts.map +1 -1
- package/dist/performance/PerformanceAnalytics.js +17 -47
- package/dist/performance/PerformanceAnalytics.js.map +1 -1
- package/dist/performance/PerformanceMonitor.d.ts +2 -1
- package/dist/performance/PerformanceMonitor.d.ts.map +1 -1
- package/dist/performance/PerformanceMonitor.js +12 -13
- package/dist/performance/PerformanceMonitor.js.map +1 -1
- package/dist/performance/index.d.ts +2 -2
- package/dist/performance/index.d.ts.map +1 -1
- package/dist/security/AISecurityScanner.d.ts +1 -0
- package/dist/security/AISecurityScanner.d.ts.map +1 -1
- package/dist/security/AISecurityScanner.js +22 -12
- package/dist/security/AISecurityScanner.js.map +1 -1
- package/dist/security/AutomatedRemediation.d.ts +4 -3
- package/dist/security/AutomatedRemediation.d.ts.map +1 -1
- package/dist/security/AutomatedRemediation.js +46 -15
- package/dist/security/AutomatedRemediation.js.map +1 -1
- package/dist/security/InputValidator.d.ts +13 -9
- package/dist/security/InputValidator.d.ts.map +1 -1
- package/dist/security/InputValidator.js +4 -2
- package/dist/security/InputValidator.js.map +1 -1
- package/dist/security/SecurityCIPipeline.d.ts +1 -1
- package/dist/security/SecurityCIPipeline.d.ts.map +1 -1
- package/dist/security/SecurityCIPipeline.js +38 -29
- package/dist/security/SecurityCIPipeline.js.map +1 -1
- package/dist/security/SecurityConfig.d.ts +3 -3
- package/dist/security/SecurityConfig.d.ts.map +1 -1
- package/dist/security/SecurityConfig.js +13 -9
- package/dist/security/SecurityConfig.js.map +1 -1
- package/dist/security/SecurityConfigManager.d.ts +2 -2
- package/dist/security/SecurityConfigManager.d.ts.map +1 -1
- package/dist/security/SecurityConfigManager.js +20 -15
- package/dist/security/SecurityConfigManager.js.map +1 -1
- package/dist/security/SecurityMonitoring.d.ts +2 -2
- package/dist/security/SecurityMonitoring.d.ts.map +1 -1
- package/dist/security/SecurityMonitoring.js +19 -17
- package/dist/security/SecurityMonitoring.js.map +1 -1
- package/dist/security/SecurityReviewer.d.ts.map +1 -1
- package/dist/security/SecurityReviewer.js +10 -7
- package/dist/security/SecurityReviewer.js.map +1 -1
- package/dist/security/index.d.ts +24 -23
- package/dist/security/index.d.ts.map +1 -1
- package/dist/security/index.js +52 -23
- package/dist/security/index.js.map +1 -1
- package/dist/server/ConnectionTester.d.ts +12 -4
- package/dist/server/ConnectionTester.d.ts.map +1 -1
- package/dist/server/ConnectionTester.js +96 -22
- package/dist/server/ConnectionTester.js.map +1 -1
- package/dist/server/ToolRegistry.d.ts +2 -2
- package/dist/server/ToolRegistry.d.ts.map +1 -1
- package/dist/server/ToolRegistry.js +10 -5
- package/dist/server/ToolRegistry.js.map +1 -1
- package/dist/tools/BaseToolManager.d.ts +47 -11
- package/dist/tools/BaseToolManager.d.ts.map +1 -1
- package/dist/tools/BaseToolManager.js +168 -29
- package/dist/tools/BaseToolManager.js.map +1 -1
- package/dist/tools/auth.d.ts +16 -10
- package/dist/tools/auth.d.ts.map +1 -1
- package/dist/tools/auth.js +3 -2
- package/dist/tools/auth.js.map +1 -1
- package/dist/tools/cache.d.ts +30 -30
- package/dist/tools/cache.d.ts.map +1 -1
- package/dist/tools/cache.js +1 -6
- package/dist/tools/cache.js.map +1 -1
- package/dist/tools/comments.d.ts +20 -20
- package/dist/tools/comments.d.ts.map +1 -1
- package/dist/tools/comments.js +16 -9
- package/dist/tools/comments.js.map +1 -1
- package/dist/tools/media.d.ts +18 -16
- package/dist/tools/media.d.ts.map +1 -1
- package/dist/tools/media.js +16 -15
- package/dist/tools/media.js.map +1 -1
- package/dist/tools/pages.d.ts +19 -17
- package/dist/tools/pages.d.ts.map +1 -1
- package/dist/tools/pages.js +16 -12
- package/dist/tools/pages.js.map +1 -1
- package/dist/tools/performance.d.ts +11 -1
- package/dist/tools/performance.d.ts.map +1 -1
- package/dist/tools/performance.js +67 -34
- package/dist/tools/performance.js.map +1 -1
- package/dist/tools/posts/PostHandlers.d.ts +46 -0
- package/dist/tools/posts/PostHandlers.d.ts.map +1 -0
- package/dist/tools/posts/PostHandlers.js +400 -0
- package/dist/tools/posts/PostHandlers.js.map +1 -0
- package/dist/tools/posts/PostToolDefinitions.d.ts +37 -0
- package/dist/tools/posts/PostToolDefinitions.d.ts.map +1 -0
- package/dist/tools/posts/PostToolDefinitions.js +236 -0
- package/dist/tools/posts/PostToolDefinitions.js.map +1 -0
- package/dist/tools/posts/index.d.ts +138 -0
- package/dist/tools/posts/index.d.ts.map +1 -0
- package/dist/tools/posts/index.js +163 -0
- package/dist/tools/posts/index.js.map +1 -0
- package/dist/tools/posts.d.ts +10 -246
- package/dist/tools/posts.d.ts.map +1 -1
- package/dist/tools/posts.js +11 -723
- package/dist/tools/posts.js.map +1 -1
- package/dist/tools/site.d.ts +19 -18
- package/dist/tools/site.d.ts.map +1 -1
- package/dist/tools/site.js +14 -10
- package/dist/tools/site.js.map +1 -1
- package/dist/tools/taxonomies.d.ts +23 -24
- package/dist/tools/taxonomies.d.ts.map +1 -1
- package/dist/tools/taxonomies.js +24 -18
- package/dist/tools/taxonomies.js.map +1 -1
- package/dist/tools/users.d.ts +20 -15
- package/dist/tools/users.d.ts.map +1 -1
- package/dist/tools/users.js +12 -8
- package/dist/tools/users.js.map +1 -1
- package/dist/types/client.d.ts +48 -41
- package/dist/types/client.d.ts.map +1 -1
- package/dist/types/client.js +30 -5
- package/dist/types/client.js.map +1 -1
- package/dist/types/enhanced.d.ts +237 -0
- package/dist/types/enhanced.d.ts.map +1 -0
- package/dist/types/enhanced.js +49 -0
- package/dist/types/enhanced.js.map +1 -0
- package/dist/types/index.d.ts +15 -12
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/mcp.d.ts +12 -12
- package/dist/types/mcp.d.ts.map +1 -1
- package/dist/types/requests.d.ts +322 -0
- package/dist/types/requests.d.ts.map +1 -0
- package/dist/types/requests.js +8 -0
- package/dist/types/requests.js.map +1 -0
- package/dist/types/tools.d.ts +506 -0
- package/dist/types/tools.d.ts.map +1 -0
- package/dist/types/tools.js +8 -0
- package/dist/types/tools.js.map +1 -0
- package/dist/types/wordpress.d.ts +43 -15
- package/dist/types/wordpress.d.ts.map +1 -1
- package/dist/types/wordpress.js +8 -1
- package/dist/types/wordpress.js.map +1 -1
- package/dist/utils/debug.d.ts +19 -11
- package/dist/utils/debug.d.ts.map +1 -1
- package/dist/utils/debug.js +46 -10
- package/dist/utils/debug.js.map +1 -1
- package/dist/utils/enhancedError.d.ts +8 -8
- package/dist/utils/enhancedError.d.ts.map +1 -1
- package/dist/utils/enhancedError.js.map +1 -1
- package/dist/utils/error.d.ts +2 -4
- package/dist/utils/error.d.ts.map +1 -1
- package/dist/utils/error.js +42 -5
- package/dist/utils/error.js.map +1 -1
- package/dist/utils/logger.d.ts +106 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +280 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/streaming.d.ts +9 -9
- package/dist/utils/streaming.d.ts.map +1 -1
- package/dist/utils/streaming.js +71 -52
- package/dist/utils/streaming.js.map +1 -1
- package/dist/utils/toolWrapper.d.ts +9 -7
- package/dist/utils/toolWrapper.d.ts.map +1 -1
- package/dist/utils/toolWrapper.js.map +1 -1
- package/dist/utils/validation/core.d.ts +21 -0
- package/dist/utils/validation/core.d.ts.map +1 -0
- package/dist/utils/validation/core.js +71 -0
- package/dist/utils/validation/core.js.map +1 -0
- package/dist/utils/validation/index.d.ts +25 -0
- package/dist/utils/validation/index.d.ts.map +1 -0
- package/dist/utils/validation/index.js +29 -0
- package/dist/utils/validation/index.js.map +1 -0
- package/dist/utils/validation/network.d.ts +19 -0
- package/dist/utils/validation/network.d.ts.map +1 -0
- package/dist/utils/validation/network.js +93 -0
- package/dist/utils/validation/network.js.map +1 -0
- package/dist/utils/validation/rateLimit.d.ts +21 -0
- package/dist/utils/validation/rateLimit.d.ts.map +1 -0
- package/dist/utils/validation/rateLimit.js +43 -0
- package/dist/utils/validation/rateLimit.js.map +1 -0
- package/dist/utils/validation/security.d.ts +29 -0
- package/dist/utils/validation/security.d.ts.map +1 -0
- package/dist/utils/validation/security.js +327 -0
- package/dist/utils/validation/security.js.map +1 -0
- package/dist/utils/validation/wordpress.d.ts +31 -0
- package/dist/utils/validation/wordpress.d.ts.map +1 -0
- package/dist/utils/validation/wordpress.js +146 -0
- package/dist/utils/validation/wordpress.js.map +1 -0
- package/dist/utils/validation.d.ts +13 -82
- package/dist/utils/validation.d.ts.map +1 -1
- package/dist/utils/validation.js +25 -343
- package/dist/utils/validation.js.map +1 -1
- package/docs/BADGE_UPDATES.md +132 -0
- package/docs/CI_CD_IMPROVEMENTS.md +191 -0
- package/docs/INCREMENTAL_COVERAGE.md +183 -0
- package/docs/api/README.md +3 -1
- package/docs/api/openapi.json +5 -1
- package/docs/api/summary.json +1 -1
- package/docs/api/tools/wp_create_post.md +12 -14
- package/docs/examples/claude-desktop-config.md +1 -1
- package/docs/examples/docker-production.md +100 -93
- package/docs/examples/multi-site-setup.md +5 -4
- package/docs/examples/single-site-setup.md +3 -4
- package/docs/examples/use-case-workflows.md +4 -5
- package/docs/integrations/claude-desktop.md +31 -31
- package/docs/integrations/cline.md +4 -4
- package/docs/integrations/vs-code.md +9 -8
- package/docs/user-guides/SMITHERY_SETUP.md +10 -10
- package/package.json +44 -25
- package/src/cache/CacheInvalidation.ts +12 -5
- package/src/cache/CacheManager.ts +18 -15
- package/src/cache/HttpCacheWrapper.ts +30 -59
- package/src/cache/__tests__/HttpCacheWrapper.test.ts +6 -5
- package/src/cache/index.ts +3 -14
- package/src/client/CachedWordPressClient.ts +32 -30
- package/src/client/MockWordPressClient.ts +4 -2
- package/src/client/api.ts +186 -64
- package/src/client/auth.ts +15 -40
- package/src/client/managers/AuthenticationManager.ts +337 -77
- package/src/client/managers/BaseManager.ts +18 -30
- package/src/client/managers/RequestManager.ts +39 -44
- package/src/config/Config.ts +308 -0
- package/src/config/ConfigurationSchema.ts +23 -2
- package/src/config/ServerConfiguration.ts +51 -47
- package/src/docs/DocumentationGenerator.ts +50 -39
- package/src/docs/MarkdownFormatter.ts +19 -29
- package/src/dxt-entry.cjs +26 -16
- package/src/dxt-entry.ts +17 -27
- package/src/index.ts +42 -28
- package/src/performance/MetricsCollector.ts +108 -86
- package/src/performance/PerformanceAnalytics.ts +69 -164
- package/src/performance/PerformanceMonitor.ts +32 -47
- package/src/performance/index.ts +2 -10
- package/src/security/AISecurityScanner.ts +22 -12
- package/src/security/AutomatedRemediation.ts +49 -18
- package/src/security/InputValidator.ts +9 -6
- package/src/security/SecurityCIPipeline.ts +53 -37
- package/src/security/SecurityConfig.ts +22 -22
- package/src/security/SecurityConfigManager.ts +23 -19
- package/src/security/SecurityMonitoring.ts +24 -21
- package/src/security/SecurityReviewer.ts +10 -7
- package/src/security/index.ts +64 -29
- package/src/server/ConnectionTester.ts +120 -31
- package/src/server/ToolRegistry.ts +31 -21
- package/src/tools/BaseToolManager.ts +286 -33
- package/src/tools/auth.ts +20 -8
- package/src/tools/cache.ts +5 -15
- package/src/tools/comments.ts +34 -48
- package/src/tools/media.ts +41 -53
- package/src/tools/pages.ts +32 -54
- package/src/tools/performance.ts +141 -176
- package/src/tools/posts/PostHandlers.ts +474 -0
- package/src/tools/posts/PostToolDefinitions.ts +250 -0
- package/src/tools/posts/index.ts +192 -0
- package/src/tools/posts.ts +24 -780
- package/src/tools/site.ts +34 -19
- package/src/tools/taxonomies.ts +41 -57
- package/src/tools/users.ts +28 -16
- package/src/types/client.ts +114 -138
- package/src/types/enhanced.ts +318 -0
- package/src/types/index.ts +51 -30
- package/src/types/mcp.ts +20 -42
- package/src/types/requests.ts +378 -0
- package/src/types/tools.ts +608 -0
- package/src/types/wordpress.ts +56 -34
- package/src/utils/debug.ts +77 -59
- package/src/utils/enhancedError.ts +8 -8
- package/src/utils/error.ts +53 -31
- package/src/utils/logger.ts +351 -0
- package/src/utils/streaming.ts +86 -68
- package/src/utils/toolWrapper.ts +10 -12
- package/src/utils/validation/core.ts +108 -0
- package/src/utils/validation/index.ts +36 -0
- package/src/utils/validation/network.ts +132 -0
- package/src/utils/validation/rateLimit.ts +54 -0
- package/src/utils/validation/security.ts +361 -0
- package/src/utils/validation/wordpress.ts +180 -0
- package/src/utils/validation.ts +47 -470
|
@@ -1,84 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Security-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
*
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
*
|
|
10
|
-
*/
|
|
11
|
-
export
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
export declare function validateFilePath(userPath: string, allowedBasePath: string): string;
|
|
16
|
-
/**
|
|
17
|
-
* Validates WordPress post status values
|
|
18
|
-
*/
|
|
19
|
-
export declare function validatePostStatus(status: string): string;
|
|
20
|
-
/**
|
|
21
|
-
* Validates and sanitizes URLs with enhanced edge case handling
|
|
22
|
-
*/
|
|
23
|
-
export declare function validateUrl(url: string, fieldName?: string): string;
|
|
24
|
-
/**
|
|
25
|
-
* Validates file size
|
|
26
|
-
*/
|
|
27
|
-
export declare function validateFileSize(sizeInBytes: number, maxSizeInMB?: number): void;
|
|
28
|
-
/**
|
|
29
|
-
* Validates MIME types for file uploads
|
|
30
|
-
*/
|
|
31
|
-
export declare function validateMimeType(mimeType: string, allowedTypes: string[]): void;
|
|
32
|
-
/**
|
|
33
|
-
* Sanitizes HTML content to prevent XSS
|
|
34
|
-
* Note: This is a basic implementation. For production use,
|
|
35
|
-
* consider using a library like DOMPurify
|
|
36
|
-
*/
|
|
37
|
-
export declare function sanitizeHtml(html: string): string;
|
|
38
|
-
/**
|
|
39
|
-
* Validates array input
|
|
40
|
-
*/
|
|
41
|
-
export declare function validateArray<T>(value: any, fieldName: string, minItems?: number, maxItems?: number): T[];
|
|
42
|
-
/**
|
|
43
|
-
* Validates email addresses
|
|
44
|
-
*/
|
|
45
|
-
export declare function validateEmail(email: string): string;
|
|
46
|
-
/**
|
|
47
|
-
* Validates username format with enhanced security checks
|
|
48
|
-
*/
|
|
49
|
-
export declare function validateUsername(username: string): string;
|
|
50
|
-
/**
|
|
51
|
-
* Rate limiting tracker (simple in-memory implementation)
|
|
52
|
-
* For production, use Redis or similar
|
|
53
|
-
*/
|
|
54
|
-
declare class RateLimiter {
|
|
55
|
-
private maxAttempts;
|
|
56
|
-
private windowMs;
|
|
57
|
-
private attempts;
|
|
58
|
-
constructor(maxAttempts?: number, windowMs?: number);
|
|
59
|
-
check(identifier: string): void;
|
|
60
|
-
reset(identifier: string): void;
|
|
61
|
-
}
|
|
62
|
-
export declare const authRateLimiter: RateLimiter;
|
|
63
|
-
/**
|
|
64
|
-
* Validates and sanitizes search queries
|
|
65
|
-
*/
|
|
66
|
-
export declare function validateSearchQuery(query: string): string;
|
|
67
|
-
/**
|
|
68
|
-
* Validates pagination parameters as a set
|
|
69
|
-
*/
|
|
70
|
-
export declare function validatePaginationParams(params: {
|
|
71
|
-
page?: any;
|
|
72
|
-
per_page?: any;
|
|
73
|
-
offset?: any;
|
|
74
|
-
}): {
|
|
75
|
-
page?: number;
|
|
76
|
-
per_page?: number;
|
|
77
|
-
offset?: number;
|
|
78
|
-
};
|
|
79
|
-
/**
|
|
80
|
-
* Validates complex post creation parameters
|
|
81
|
-
*/
|
|
82
|
-
export declare function validatePostParams(params: any): any;
|
|
83
|
-
export {};
|
|
2
|
+
* Enhanced Security-Focused Validation Utilities - Legacy Export Module
|
|
3
|
+
*
|
|
4
|
+
* This file maintains backward compatibility while the codebase transitions
|
|
5
|
+
* to the new modular structure. The actual implementations have been refactored
|
|
6
|
+
* into focused modules under ./validation/ directory.
|
|
7
|
+
*
|
|
8
|
+
* @deprecated Use direct imports from ./validation/ modules instead
|
|
9
|
+
* @see ./validation/index.ts for the new modular implementation
|
|
10
|
+
*/
|
|
11
|
+
export { validateId, validateString, validateArray, validateFilePath, validateFileSize, validateMimeType, sanitizeHtml, validateUrl, validateEmail, validateUsername, validatePostStatus, validateSearchQuery, validatePaginationParams, validatePostParams, RateLimiter, authRateLimiter, type WordPressId, WordPressAPIError, } from "./validation/index.js";
|
|
12
|
+
export { validateId as validateWordPressId } from "./validation/core.js";
|
|
13
|
+
export { validatePostParams as validatePostData } from "./validation/wordpress.js";
|
|
14
|
+
export { sanitizeHtml as cleanHtml } from "./validation/security.js";
|
|
84
15
|
//# sourceMappingURL=validation.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAEL,UAAU,EACV,cAAc,EACd,aAAa,EAGb,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,EAGZ,WAAW,EACX,aAAa,EACb,gBAAgB,EAGhB,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EACxB,kBAAkB,EAGlB,WAAW,EACX,eAAe,EAGf,KAAK,WAAW,EAChB,iBAAiB,GAClB,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAAE,UAAU,IAAI,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AACzE,OAAO,EAAE,kBAAkB,IAAI,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AACnF,OAAO,EAAE,YAAY,IAAI,SAAS,EAAE,MAAM,0BAA0B,CAAC"}
|
package/dist/utils/validation.js
CHANGED
|
@@ -1,345 +1,27 @@
|
|
|
1
|
-
import * as path from "path";
|
|
2
|
-
import { WordPressAPIError } from "../types/client.js";
|
|
3
1
|
/**
|
|
4
|
-
* Security-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
*
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
// Check for negative or zero
|
|
30
|
-
if (numId <= 0) {
|
|
31
|
-
throw new WordPressAPIError(`Invalid ${fieldName}: must be a positive number (got ${numId})`, 400, "INVALID_PARAMETER");
|
|
32
|
-
}
|
|
33
|
-
// Check for max int32 limit (WordPress database limit)
|
|
34
|
-
if (numId > 2147483647) {
|
|
35
|
-
throw new WordPressAPIError(`Invalid ${fieldName}: exceeds maximum allowed value (2147483647)`, 400, "INVALID_PARAMETER");
|
|
36
|
-
}
|
|
37
|
-
return numId;
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* Validates string length within bounds
|
|
41
|
-
*/
|
|
42
|
-
export function validateString(value, fieldName, minLength = 1, maxLength = 1000) {
|
|
43
|
-
if (typeof value !== "string") {
|
|
44
|
-
throw new WordPressAPIError(`Invalid ${fieldName}: must be a string`, 400, "INVALID_PARAMETER");
|
|
45
|
-
}
|
|
46
|
-
const trimmed = value.trim();
|
|
47
|
-
if (trimmed.length < minLength || trimmed.length > maxLength) {
|
|
48
|
-
throw new WordPressAPIError(`Invalid ${fieldName}: length must be between ${minLength} and ${maxLength} characters`, 400, "INVALID_PARAMETER");
|
|
49
|
-
}
|
|
50
|
-
return trimmed;
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Validates and sanitizes file paths to prevent directory traversal
|
|
54
|
-
*/
|
|
55
|
-
export function validateFilePath(userPath, allowedBasePath) {
|
|
56
|
-
// Normalize the path to remove ../ and other dangerous patterns
|
|
57
|
-
const normalizedPath = path.normalize(userPath);
|
|
58
|
-
const resolvedPath = path.resolve(allowedBasePath, normalizedPath);
|
|
59
|
-
// Ensure the resolved path is within the allowed directory
|
|
60
|
-
if (!resolvedPath.startsWith(path.resolve(allowedBasePath))) {
|
|
61
|
-
throw new WordPressAPIError("Invalid file path: access denied", 403, "PATH_TRAVERSAL_ATTEMPT");
|
|
62
|
-
}
|
|
63
|
-
return resolvedPath;
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Validates WordPress post status values
|
|
67
|
-
*/
|
|
68
|
-
export function validatePostStatus(status) {
|
|
69
|
-
const validStatuses = ["publish", "draft", "pending", "private", "future", "auto-draft", "trash"];
|
|
70
|
-
if (!validStatuses.includes(status)) {
|
|
71
|
-
throw new WordPressAPIError(`Invalid status: must be one of ${validStatuses.join(", ")}`, 400, "INVALID_PARAMETER");
|
|
72
|
-
}
|
|
73
|
-
return status;
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* Validates and sanitizes URLs with enhanced edge case handling
|
|
77
|
-
*/
|
|
78
|
-
export function validateUrl(url, fieldName = "url") {
|
|
79
|
-
// Check for empty or whitespace-only URLs
|
|
80
|
-
const trimmedUrl = url.trim();
|
|
81
|
-
if (!trimmedUrl) {
|
|
82
|
-
throw new WordPressAPIError(`${fieldName} cannot be empty`, 400, "INVALID_PARAMETER");
|
|
83
|
-
}
|
|
84
|
-
// Remove trailing slashes for consistency
|
|
85
|
-
const cleanUrl = trimmedUrl.replace(/\/+$/, "");
|
|
86
|
-
// Check for common URL mistakes
|
|
87
|
-
if (!cleanUrl.match(/^https?:\/\//i)) {
|
|
88
|
-
throw new WordPressAPIError(`Invalid ${fieldName}: must start with http:// or https:// (got "${cleanUrl}")`, 400, "INVALID_PARAMETER");
|
|
89
|
-
}
|
|
90
|
-
try {
|
|
91
|
-
const urlObj = new URL(cleanUrl);
|
|
92
|
-
// Only allow http and https protocols
|
|
93
|
-
if (!["http:", "https:"].includes(urlObj.protocol)) {
|
|
94
|
-
throw new WordPressAPIError(`Invalid ${fieldName}: only HTTP and HTTPS protocols are allowed`, 400, "INVALID_PARAMETER");
|
|
95
|
-
}
|
|
96
|
-
// Validate hostname
|
|
97
|
-
if (!urlObj.hostname || urlObj.hostname.length < 3) {
|
|
98
|
-
throw new WordPressAPIError(`Invalid ${fieldName}: hostname is missing or too short`, 400, "INVALID_PARAMETER");
|
|
99
|
-
}
|
|
100
|
-
// Check for localhost in production
|
|
101
|
-
if (process.env.NODE_ENV === "production" && (urlObj.hostname === "localhost" || urlObj.hostname === "127.0.0.1")) {
|
|
102
|
-
throw new WordPressAPIError(`Invalid ${fieldName}: localhost URLs are not allowed in production`, 400, "INVALID_PARAMETER");
|
|
103
|
-
}
|
|
104
|
-
// Validate port if present
|
|
105
|
-
if (urlObj.port) {
|
|
106
|
-
const port = parseInt(urlObj.port);
|
|
107
|
-
if (port < 1 || port > 65535) {
|
|
108
|
-
throw new WordPressAPIError(`Invalid ${fieldName}: port number must be between 1 and 65535`, 400, "INVALID_PARAMETER");
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
return cleanUrl;
|
|
112
|
-
}
|
|
113
|
-
catch (error) {
|
|
114
|
-
if (error instanceof WordPressAPIError) {
|
|
115
|
-
throw error;
|
|
116
|
-
}
|
|
117
|
-
throw new WordPressAPIError(`Invalid ${fieldName}: malformed URL "${cleanUrl}"`, 400, "INVALID_PARAMETER");
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
/**
|
|
121
|
-
* Validates file size
|
|
122
|
-
*/
|
|
123
|
-
export function validateFileSize(sizeInBytes, maxSizeInMB = 10) {
|
|
124
|
-
const maxSizeInBytes = maxSizeInMB * 1024 * 1024;
|
|
125
|
-
if (sizeInBytes > maxSizeInBytes) {
|
|
126
|
-
throw new WordPressAPIError(`File size exceeds maximum allowed size of ${maxSizeInMB}MB`, 413, "FILE_TOO_LARGE");
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
/**
|
|
130
|
-
* Validates MIME types for file uploads
|
|
131
|
-
*/
|
|
132
|
-
export function validateMimeType(mimeType, allowedTypes) {
|
|
133
|
-
if (!allowedTypes.includes(mimeType)) {
|
|
134
|
-
throw new WordPressAPIError(`Invalid file type: ${mimeType}. Allowed types: ${allowedTypes.join(", ")}`, 415, "UNSUPPORTED_MEDIA_TYPE");
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
/**
|
|
138
|
-
* Sanitizes HTML content to prevent XSS
|
|
139
|
-
* Note: This is a basic implementation. For production use,
|
|
140
|
-
* consider using a library like DOMPurify
|
|
141
|
-
*/
|
|
142
|
-
export function sanitizeHtml(html) {
|
|
143
|
-
// Remove script tags and their content
|
|
144
|
-
let sanitized = html.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, "");
|
|
145
|
-
// Remove event handlers
|
|
146
|
-
sanitized = sanitized.replace(/\s*on\w+\s*=\s*["'][^"']*["']/gi, "");
|
|
147
|
-
// Remove javascript: protocol
|
|
148
|
-
sanitized = sanitized.replace(/javascript:/gi, "");
|
|
149
|
-
// Remove data: protocol (can be used for XSS)
|
|
150
|
-
sanitized = sanitized.replace(/data:text\/html/gi, "");
|
|
151
|
-
return sanitized;
|
|
152
|
-
}
|
|
153
|
-
/**
|
|
154
|
-
* Validates array input
|
|
155
|
-
*/
|
|
156
|
-
export function validateArray(value, fieldName, minItems = 0, maxItems = 100) {
|
|
157
|
-
if (!Array.isArray(value)) {
|
|
158
|
-
throw new WordPressAPIError(`Invalid ${fieldName}: must be an array`, 400, "INVALID_PARAMETER");
|
|
159
|
-
}
|
|
160
|
-
if (value.length < minItems || value.length > maxItems) {
|
|
161
|
-
throw new WordPressAPIError(`Invalid ${fieldName}: array must contain between ${minItems} and ${maxItems} items`, 400, "INVALID_PARAMETER");
|
|
162
|
-
}
|
|
163
|
-
return value;
|
|
164
|
-
}
|
|
165
|
-
/**
|
|
166
|
-
* Validates email addresses
|
|
167
|
-
*/
|
|
168
|
-
export function validateEmail(email) {
|
|
169
|
-
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
170
|
-
if (!emailRegex.test(email)) {
|
|
171
|
-
throw new WordPressAPIError("Invalid email address format", 400, "INVALID_PARAMETER");
|
|
172
|
-
}
|
|
173
|
-
return email.toLowerCase();
|
|
174
|
-
}
|
|
175
|
-
/**
|
|
176
|
-
* Validates username format with enhanced security checks
|
|
177
|
-
*/
|
|
178
|
-
export function validateUsername(username) {
|
|
179
|
-
// Trim and check for empty
|
|
180
|
-
const trimmed = username.trim();
|
|
181
|
-
if (!trimmed) {
|
|
182
|
-
throw new WordPressAPIError("Username cannot be empty", 400, "INVALID_PARAMETER");
|
|
183
|
-
}
|
|
184
|
-
// WordPress username rules: alphanumeric, space, underscore, hyphen, period, @ symbol
|
|
185
|
-
const usernameRegex = /^[a-zA-Z0-9 _.\-@]+$/;
|
|
186
|
-
if (!usernameRegex.test(trimmed)) {
|
|
187
|
-
throw new WordPressAPIError("Invalid username: can only contain letters, numbers, spaces, and _.-@ symbols", 400, "INVALID_PARAMETER");
|
|
188
|
-
}
|
|
189
|
-
// Length validation
|
|
190
|
-
if (trimmed.length < 3 || trimmed.length > 60) {
|
|
191
|
-
throw new WordPressAPIError(`Invalid username: must be between 3 and 60 characters (got ${trimmed.length})`, 400, "INVALID_PARAMETER");
|
|
192
|
-
}
|
|
193
|
-
// Check for consecutive spaces
|
|
194
|
-
if (/\s{2,}/.test(trimmed)) {
|
|
195
|
-
throw new WordPressAPIError("Invalid username: cannot contain consecutive spaces", 400, "INVALID_PARAMETER");
|
|
196
|
-
}
|
|
197
|
-
// Security: Prevent common problematic usernames
|
|
198
|
-
const blacklist = ["admin", "root", "wordpress", "wp-admin", "administrator"];
|
|
199
|
-
if (blacklist.includes(trimmed.toLowerCase())) {
|
|
200
|
-
throw new WordPressAPIError(`Username "${trimmed}" is reserved and cannot be used`, 400, "RESERVED_USERNAME");
|
|
201
|
-
}
|
|
202
|
-
return trimmed;
|
|
203
|
-
}
|
|
204
|
-
/**
|
|
205
|
-
* Rate limiting tracker (simple in-memory implementation)
|
|
206
|
-
* For production, use Redis or similar
|
|
207
|
-
*/
|
|
208
|
-
class RateLimiter {
|
|
209
|
-
maxAttempts;
|
|
210
|
-
windowMs;
|
|
211
|
-
attempts = new Map();
|
|
212
|
-
constructor(maxAttempts = 5, windowMs = 60000) {
|
|
213
|
-
this.maxAttempts = maxAttempts;
|
|
214
|
-
this.windowMs = windowMs;
|
|
215
|
-
}
|
|
216
|
-
check(identifier) {
|
|
217
|
-
const now = Date.now();
|
|
218
|
-
const record = this.attempts.get(identifier);
|
|
219
|
-
if (!record || record.resetTime < now) {
|
|
220
|
-
this.attempts.set(identifier, {
|
|
221
|
-
count: 1,
|
|
222
|
-
resetTime: now + this.windowMs,
|
|
223
|
-
});
|
|
224
|
-
return;
|
|
225
|
-
}
|
|
226
|
-
if (record.count >= this.maxAttempts) {
|
|
227
|
-
const waitTime = Math.ceil((record.resetTime - now) / 1000);
|
|
228
|
-
throw new WordPressAPIError(`Rate limit exceeded. Please wait ${waitTime} seconds before trying again.`, 429, "RATE_LIMIT_EXCEEDED");
|
|
229
|
-
}
|
|
230
|
-
record.count++;
|
|
231
|
-
}
|
|
232
|
-
reset(identifier) {
|
|
233
|
-
this.attempts.delete(identifier);
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
// Export a default rate limiter for authentication attempts
|
|
237
|
-
export const authRateLimiter = new RateLimiter(5, 300000); // 5 attempts per 5 minutes
|
|
238
|
-
/**
|
|
239
|
-
* Validates and sanitizes search queries
|
|
240
|
-
*/
|
|
241
|
-
export function validateSearchQuery(query) {
|
|
242
|
-
// Remove potentially dangerous characters while preserving search functionality
|
|
243
|
-
let sanitized = query.trim();
|
|
244
|
-
// Limit length to prevent DoS
|
|
245
|
-
if (sanitized.length > 200) {
|
|
246
|
-
sanitized = sanitized.substring(0, 200);
|
|
247
|
-
}
|
|
248
|
-
// Remove SQL-like patterns (basic protection)
|
|
249
|
-
sanitized = sanitized.replace(/(\b(union|select|insert|update|delete|drop|create)\b)/gi, "");
|
|
250
|
-
// Remove special characters that might be used for injection
|
|
251
|
-
sanitized = sanitized.replace(/[<>'"`;\\]/g, "");
|
|
252
|
-
return sanitized;
|
|
253
|
-
}
|
|
254
|
-
/**
|
|
255
|
-
* Validates pagination parameters as a set
|
|
256
|
-
*/
|
|
257
|
-
export function validatePaginationParams(params) {
|
|
258
|
-
const validated = {};
|
|
259
|
-
// Validate page
|
|
260
|
-
if (params.page !== undefined) {
|
|
261
|
-
const page = parseInt(String(params.page), 10);
|
|
262
|
-
if (isNaN(page) || page < 1) {
|
|
263
|
-
throw new WordPressAPIError("Page must be a positive integer", 400, "INVALID_PARAMETER");
|
|
264
|
-
}
|
|
265
|
-
if (page > 10000) {
|
|
266
|
-
throw new WordPressAPIError("Page number too high (max 10000)", 400, "INVALID_PARAMETER");
|
|
267
|
-
}
|
|
268
|
-
validated.page = page;
|
|
269
|
-
}
|
|
270
|
-
// Validate per_page
|
|
271
|
-
if (params.per_page !== undefined) {
|
|
272
|
-
const perPage = parseInt(String(params.per_page), 10);
|
|
273
|
-
if (isNaN(perPage) || perPage < 1) {
|
|
274
|
-
throw new WordPressAPIError("Per page must be a positive integer", 400, "INVALID_PARAMETER");
|
|
275
|
-
}
|
|
276
|
-
if (perPage > 100) {
|
|
277
|
-
throw new WordPressAPIError(`Per page exceeds maximum allowed (100), got ${perPage}`, 400, "INVALID_PARAMETER");
|
|
278
|
-
}
|
|
279
|
-
validated.per_page = perPage;
|
|
280
|
-
}
|
|
281
|
-
// Validate offset
|
|
282
|
-
if (params.offset !== undefined) {
|
|
283
|
-
const offset = parseInt(String(params.offset), 10);
|
|
284
|
-
if (isNaN(offset) || offset < 0) {
|
|
285
|
-
throw new WordPressAPIError("Offset must be a non-negative integer", 400, "INVALID_PARAMETER");
|
|
286
|
-
}
|
|
287
|
-
if (offset > 1000000) {
|
|
288
|
-
throw new WordPressAPIError("Offset too large (max 1000000)", 400, "INVALID_PARAMETER");
|
|
289
|
-
}
|
|
290
|
-
validated.offset = offset;
|
|
291
|
-
}
|
|
292
|
-
// Check for conflicting parameters
|
|
293
|
-
if (validated.page && validated.offset) {
|
|
294
|
-
throw new WordPressAPIError("Cannot use both 'page' and 'offset' parameters together", 400, "CONFLICTING_PARAMETERS");
|
|
295
|
-
}
|
|
296
|
-
return validated;
|
|
297
|
-
}
|
|
298
|
-
/**
|
|
299
|
-
* Validates complex post creation parameters
|
|
300
|
-
*/
|
|
301
|
-
export function validatePostParams(params) {
|
|
302
|
-
const validated = {};
|
|
303
|
-
// Title validation
|
|
304
|
-
if (!params.title || typeof params.title !== "string") {
|
|
305
|
-
throw new WordPressAPIError("Post title is required and must be a string", 400, "INVALID_PARAMETER");
|
|
306
|
-
}
|
|
307
|
-
validated.title = validateString(params.title, "title", 1, 200);
|
|
308
|
-
// Content validation
|
|
309
|
-
if (params.content !== undefined) {
|
|
310
|
-
validated.content = sanitizeHtml(String(params.content));
|
|
311
|
-
}
|
|
312
|
-
// Status validation with context
|
|
313
|
-
if (params.status) {
|
|
314
|
-
validated.status = validatePostStatus(params.status);
|
|
315
|
-
// Future posts need a date
|
|
316
|
-
if (validated.status === "future" && !params.date) {
|
|
317
|
-
throw new WordPressAPIError("Future posts require a 'date' parameter", 400, "MISSING_PARAMETER");
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
// Categories and tags validation
|
|
321
|
-
if (params.categories) {
|
|
322
|
-
validated.categories = validateArray(params.categories, "categories", 0, 50);
|
|
323
|
-
validated.categories = validated.categories.map((id) => validateId(id, "category ID"));
|
|
324
|
-
}
|
|
325
|
-
if (params.tags) {
|
|
326
|
-
validated.tags = validateArray(params.tags, "tags", 0, 100);
|
|
327
|
-
validated.tags = validated.tags.map((id) => validateId(id, "tag ID"));
|
|
328
|
-
}
|
|
329
|
-
// Date validation for scheduled posts
|
|
330
|
-
if (params.date) {
|
|
331
|
-
try {
|
|
332
|
-
const date = new Date(params.date);
|
|
333
|
-
if (isNaN(date.getTime())) {
|
|
334
|
-
throw new Error("Invalid date");
|
|
335
|
-
}
|
|
336
|
-
// WordPress expects ISO 8601 format
|
|
337
|
-
validated.date = date.toISOString();
|
|
338
|
-
}
|
|
339
|
-
catch {
|
|
340
|
-
throw new WordPressAPIError("Invalid date format. Use ISO 8601 format (YYYY-MM-DDTHH:mm:ss)", 400, "INVALID_PARAMETER");
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
return validated;
|
|
344
|
-
}
|
|
2
|
+
* Enhanced Security-Focused Validation Utilities - Legacy Export Module
|
|
3
|
+
*
|
|
4
|
+
* This file maintains backward compatibility while the codebase transitions
|
|
5
|
+
* to the new modular structure. The actual implementations have been refactored
|
|
6
|
+
* into focused modules under ./validation/ directory.
|
|
7
|
+
*
|
|
8
|
+
* @deprecated Use direct imports from ./validation/ modules instead
|
|
9
|
+
* @see ./validation/index.ts for the new modular implementation
|
|
10
|
+
*/
|
|
11
|
+
// Re-export everything from the modular structure for backward compatibility
|
|
12
|
+
export {
|
|
13
|
+
// Core validators
|
|
14
|
+
validateId, validateString, validateArray,
|
|
15
|
+
// Security validators
|
|
16
|
+
validateFilePath, validateFileSize, validateMimeType, sanitizeHtml,
|
|
17
|
+
// Network validators
|
|
18
|
+
validateUrl, validateEmail, validateUsername,
|
|
19
|
+
// WordPress-specific validators
|
|
20
|
+
validatePostStatus, validateSearchQuery, validatePaginationParams, validatePostParams,
|
|
21
|
+
// Rate limiting
|
|
22
|
+
RateLimiter, authRateLimiter, WordPressAPIError, } from "./validation/index.js";
|
|
23
|
+
// Legacy re-exports for specific components (advanced usage)
|
|
24
|
+
export { validateId as validateWordPressId } from "./validation/core.js";
|
|
25
|
+
export { validatePostParams as validatePostData } from "./validation/wordpress.js";
|
|
26
|
+
export { sanitizeHtml as cleanHtml } from "./validation/security.js";
|
|
345
27
|
//# sourceMappingURL=validation.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAEvD;;GAEG;AAEH;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,EAAO,EAAE,YAAoB,IAAI;IAC1D,wBAAwB;IACxB,IAAI,EAAE,KAAK,IAAI,IAAI,EAAE,KAAK,SAAS,EAAE,CAAC;QACpC,MAAM,IAAI,iBAAiB,CAAC,GAAG,SAAS,cAAc,EAAE,GAAG,EAAE,mBAAmB,CAAC,CAAC;IACpF,CAAC;IAED,wDAAwD;IACxD,MAAM,KAAK,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAEhC,oCAAoC;IACpC,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,iBAAiB,CAAC,GAAG,SAAS,kBAAkB,EAAE,GAAG,EAAE,mBAAmB,CAAC,CAAC;IACxF,CAAC;IAED,wBAAwB;IACxB,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,iBAAiB,CAAC,GAAG,SAAS,wCAAwC,EAAE,GAAG,EAAE,mBAAmB,CAAC,CAAC;IAC9G,CAAC;IAED,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAElC,gBAAgB;IAChB,IAAI,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;QACjB,MAAM,IAAI,iBAAiB,CAAC,WAAW,SAAS,MAAM,EAAE,yBAAyB,EAAE,GAAG,EAAE,mBAAmB,CAAC,CAAC;IAC/G,CAAC;IAED,6BAA6B;IAC7B,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;QACf,MAAM,IAAI,iBAAiB,CACzB,WAAW,SAAS,oCAAoC,KAAK,GAAG,EAChE,GAAG,EACH,mBAAmB,CACpB,CAAC;IACJ,CAAC;IAED,uDAAuD;IACvD,IAAI,KAAK,GAAG,UAAU,EAAE,CAAC;QACvB,MAAM,IAAI,iBAAiB,CACzB,WAAW,SAAS,8CAA8C,EAClE,GAAG,EACH,mBAAmB,CACpB,CAAC;IACJ,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,KAAU,EAAE,SAAiB,EAAE,YAAoB,CAAC,EAAE,YAAoB,IAAI;IAC3G,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,IAAI,iBAAiB,CAAC,WAAW,SAAS,oBAAoB,EAAE,GAAG,EAAE,mBAAmB,CAAC,CAAC;IAClG,CAAC;IAED,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,EAAE,CAAC;QAC7D,MAAM,IAAI,iBAAiB,CACzB,WAAW,SAAS,4BAA4B,SAAS,QAAQ,SAAS,aAAa,EACvF,GAAG,EACH,mBAAmB,CACpB,CAAC;IACJ,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAgB,EAAE,eAAuB;IACxE,gEAAgE;IAChE,MAAM,cAAc,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IAChD,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,cAAc,CAAC,CAAC;IAEnE,2DAA2D;IAC3D,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC;QAC5D,MAAM,IAAI,iBAAiB,CAAC,kCAAkC,EAAE,GAAG,EAAE,wBAAwB,CAAC,CAAC;IACjG,CAAC;IAED,OAAO,YAAY,CAAC;AACtB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAc;IAC/C,MAAM,aAAa,GAAG,CAAC,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;IAClG,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACpC,MAAM,IAAI,iBAAiB,CAAC,kCAAkC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,GAAG,EAAE,mBAAmB,CAAC,CAAC;IACtH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,GAAW,EAAE,YAAoB,KAAK;IAChE,0CAA0C;IAC1C,MAAM,UAAU,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IAC9B,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,IAAI,iBAAiB,CAAC,GAAG,SAAS,kBAAkB,EAAE,GAAG,EAAE,mBAAmB,CAAC,CAAC;IACxF,CAAC;IAED,0CAA0C;IAC1C,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAEhD,gCAAgC;IAChC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,eAAe,CAAC,EAAE,CAAC;QACrC,MAAM,IAAI,iBAAiB,CACzB,WAAW,SAAS,+CAA+C,QAAQ,IAAI,EAC/E,GAAG,EACH,mBAAmB,CACpB,CAAC;IACJ,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;QAEjC,sCAAsC;QACtC,IAAI,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;YACnD,MAAM,IAAI,iBAAiB,CACzB,WAAW,SAAS,6CAA6C,EACjE,GAAG,EACH,mBAAmB,CACpB,CAAC;QACJ,CAAC;QAED,oBAAoB;QACpB,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACnD,MAAM,IAAI,iBAAiB,CAAC,WAAW,SAAS,oCAAoC,EAAE,GAAG,EAAE,mBAAmB,CAAC,CAAC;QAClH,CAAC;QAED,oCAAoC;QACpC,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,IAAI,CAAC,MAAM,CAAC,QAAQ,KAAK,WAAW,IAAI,MAAM,CAAC,QAAQ,KAAK,WAAW,CAAC,EAAE,CAAC;YAClH,MAAM,IAAI,iBAAiB,CACzB,WAAW,SAAS,gDAAgD,EACpE,GAAG,EACH,mBAAmB,CACpB,CAAC;QACJ,CAAC;QAED,2BAA2B;QAC3B,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;YAChB,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACnC,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,KAAK,EAAE,CAAC;gBAC7B,MAAM,IAAI,iBAAiB,CACzB,WAAW,SAAS,2CAA2C,EAC/D,GAAG,EACH,mBAAmB,CACpB,CAAC;YACJ,CAAC;QACH,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,iBAAiB,EAAE,CAAC;YACvC,MAAM,KAAK,CAAC;QACd,CAAC;QACD,MAAM,IAAI,iBAAiB,CAAC,WAAW,SAAS,oBAAoB,QAAQ,GAAG,EAAE,GAAG,EAAE,mBAAmB,CAAC,CAAC;IAC7G,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,WAAmB,EAAE,cAAsB,EAAE;IAC5E,MAAM,cAAc,GAAG,WAAW,GAAG,IAAI,GAAG,IAAI,CAAC;IACjD,IAAI,WAAW,GAAG,cAAc,EAAE,CAAC;QACjC,MAAM,IAAI,iBAAiB,CAAC,6CAA6C,WAAW,IAAI,EAAE,GAAG,EAAE,gBAAgB,CAAC,CAAC;IACnH,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAgB,EAAE,YAAsB;IACvE,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACrC,MAAM,IAAI,iBAAiB,CACzB,sBAAsB,QAAQ,oBAAoB,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAC3E,GAAG,EACH,wBAAwB,CACzB,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,uCAAuC;IACvC,IAAI,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,qDAAqD,EAAE,EAAE,CAAC,CAAC;IAExF,wBAAwB;IACxB,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,iCAAiC,EAAE,EAAE,CAAC,CAAC;IAErE,8BAA8B;IAC9B,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;IAEnD,8CAA8C;IAC9C,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC;IAEvD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAI,KAAU,EAAE,SAAiB,EAAE,WAAmB,CAAC,EAAE,WAAmB,GAAG;IAC1G,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,iBAAiB,CAAC,WAAW,SAAS,oBAAoB,EAAE,GAAG,EAAE,mBAAmB,CAAC,CAAC;IAClG,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,GAAG,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,QAAQ,EAAE,CAAC;QACvD,MAAM,IAAI,iBAAiB,CACzB,WAAW,SAAS,gCAAgC,QAAQ,QAAQ,QAAQ,QAAQ,EACpF,GAAG,EACH,mBAAmB,CACpB,CAAC;IACJ,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,MAAM,UAAU,GAAG,4BAA4B,CAAC;IAChD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,iBAAiB,CAAC,8BAA8B,EAAE,GAAG,EAAE,mBAAmB,CAAC,CAAC;IACxF,CAAC;IACD,OAAO,KAAK,CAAC,WAAW,EAAE,CAAC;AAC7B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAgB;IAC/C,2BAA2B;IAC3B,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC;IAChC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,iBAAiB,CAAC,0BAA0B,EAAE,GAAG,EAAE,mBAAmB,CAAC,CAAC;IACpF,CAAC;IAED,sFAAsF;IACtF,MAAM,aAAa,GAAG,sBAAsB,CAAC;IAC7C,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACjC,MAAM,IAAI,iBAAiB,CACzB,+EAA+E,EAC/E,GAAG,EACH,mBAAmB,CACpB,CAAC;IACJ,CAAC;IAED,oBAAoB;IACpB,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;QAC9C,MAAM,IAAI,iBAAiB,CACzB,8DAA8D,OAAO,CAAC,MAAM,GAAG,EAC/E,GAAG,EACH,mBAAmB,CACpB,CAAC;IACJ,CAAC;IAED,+BAA+B;IAC/B,IAAI,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,iBAAiB,CAAC,qDAAqD,EAAE,GAAG,EAAE,mBAAmB,CAAC,CAAC;IAC/G,CAAC;IAED,iDAAiD;IACjD,MAAM,SAAS,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,eAAe,CAAC,CAAC;IAC9E,IAAI,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;QAC9C,MAAM,IAAI,iBAAiB,CAAC,aAAa,OAAO,kCAAkC,EAAE,GAAG,EAAE,mBAAmB,CAAC,CAAC;IAChH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,MAAM,WAAW;IAIL;IACA;IAJF,QAAQ,GAAsD,IAAI,GAAG,EAAE,CAAC;IAEhF,YACU,cAAsB,CAAC,EACvB,WAAmB,KAAK;QADxB,gBAAW,GAAX,WAAW,CAAY;QACvB,aAAQ,GAAR,QAAQ,CAAgB;IAC/B,CAAC;IAEJ,KAAK,CAAC,UAAkB;QACtB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAE7C,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,SAAS,GAAG,GAAG,EAAE,CAAC;YACtC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,EAAE;gBAC5B,KAAK,EAAE,CAAC;gBACR,SAAS,EAAE,GAAG,GAAG,IAAI,CAAC,QAAQ;aAC/B,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,IAAI,MAAM,CAAC,KAAK,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,SAAS,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;YAC5D,MAAM,IAAI,iBAAiB,CACzB,oCAAoC,QAAQ,+BAA+B,EAC3E,GAAG,EACH,qBAAqB,CACtB,CAAC;QACJ,CAAC;QAED,MAAM,CAAC,KAAK,EAAE,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,UAAkB;QACtB,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IACnC,CAAC;CACF;AAED,4DAA4D;AAC5D,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,WAAW,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,2BAA2B;AAEtF;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAAa;IAC/C,gFAAgF;IAChF,IAAI,SAAS,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAE7B,8BAA8B;IAC9B,IAAI,SAAS,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;QAC3B,SAAS,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC1C,CAAC;IAED,8CAA8C;IAC9C,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,yDAAyD,EAAE,EAAE,CAAC,CAAC;IAE7F,6DAA6D;IAC7D,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;IAEjD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,wBAAwB,CAAC,MAAoD;IAK3F,MAAM,SAAS,GAA0D,EAAE,CAAC;IAE5E,gBAAgB;IAChB,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC9B,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QAC/C,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,iBAAiB,CAAC,iCAAiC,EAAE,GAAG,EAAE,mBAAmB,CAAC,CAAC;QAC3F,CAAC;QACD,IAAI,IAAI,GAAG,KAAK,EAAE,CAAC;YACjB,MAAM,IAAI,iBAAiB,CAAC,kCAAkC,EAAE,GAAG,EAAE,mBAAmB,CAAC,CAAC;QAC5F,CAAC;QACD,SAAS,CAAC,IAAI,GAAG,IAAI,CAAC;IACxB,CAAC;IAED,oBAAoB;IACpB,IAAI,MAAM,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QAClC,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC;QACtD,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;YAClC,MAAM,IAAI,iBAAiB,CAAC,qCAAqC,EAAE,GAAG,EAAE,mBAAmB,CAAC,CAAC;QAC/F,CAAC;QACD,IAAI,OAAO,GAAG,GAAG,EAAE,CAAC;YAClB,MAAM,IAAI,iBAAiB,CAAC,+CAA+C,OAAO,EAAE,EAAE,GAAG,EAAE,mBAAmB,CAAC,CAAC;QAClH,CAAC;QACD,SAAS,CAAC,QAAQ,GAAG,OAAO,CAAC;IAC/B,CAAC;IAED,kBAAkB;IAClB,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAChC,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC;QACnD,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;YAChC,MAAM,IAAI,iBAAiB,CAAC,uCAAuC,EAAE,GAAG,EAAE,mBAAmB,CAAC,CAAC;QACjG,CAAC;QACD,IAAI,MAAM,GAAG,OAAO,EAAE,CAAC;YACrB,MAAM,IAAI,iBAAiB,CAAC,gCAAgC,EAAE,GAAG,EAAE,mBAAmB,CAAC,CAAC;QAC1F,CAAC;QACD,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC;IAC5B,CAAC;IAED,mCAAmC;IACnC,IAAI,SAAS,CAAC,IAAI,IAAI,SAAS,CAAC,MAAM,EAAE,CAAC;QACvC,MAAM,IAAI,iBAAiB,CACzB,yDAAyD,EACzD,GAAG,EACH,wBAAwB,CACzB,CAAC;IACJ,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAW;IAC5C,MAAM,SAAS,GAAQ,EAAE,CAAC;IAE1B,mBAAmB;IACnB,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,OAAO,MAAM,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;QACtD,MAAM,IAAI,iBAAiB,CAAC,6CAA6C,EAAE,GAAG,EAAE,mBAAmB,CAAC,CAAC;IACvG,CAAC;IACD,SAAS,CAAC,KAAK,GAAG,cAAc,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;IAEhE,qBAAqB;IACrB,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QACjC,SAAS,CAAC,OAAO,GAAG,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;IAC3D,CAAC;IAED,iCAAiC;IACjC,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClB,SAAS,CAAC,MAAM,GAAG,kBAAkB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAErD,2BAA2B;QAC3B,IAAI,SAAS,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YAClD,MAAM,IAAI,iBAAiB,CAAC,yCAAyC,EAAE,GAAG,EAAE,mBAAmB,CAAC,CAAC;QACnG,CAAC;IACH,CAAC;IAED,iCAAiC;IACjC,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QACtB,SAAS,CAAC,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,UAAU,EAAE,YAAY,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QAC7E,SAAS,CAAC,UAAU,GAAG,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,EAAO,EAAE,EAAE,CAAC,UAAU,CAAC,EAAE,EAAE,aAAa,CAAC,CAAC,CAAC;IAC9F,CAAC;IAED,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;QAChB,SAAS,CAAC,IAAI,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;QAC5D,SAAS,CAAC,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAO,EAAE,EAAE,CAAC,UAAU,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC7E,CAAC;IAED,sCAAsC;IACtC,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;QAChB,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACnC,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;gBAC1B,MAAM,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC;YAClC,CAAC;YACD,oCAAoC;YACpC,SAAS,CAAC,IAAI,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QACtC,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,iBAAiB,CACzB,gEAAgE,EAChE,GAAG,EACH,mBAAmB,CACpB,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
1
|
+
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,6EAA6E;AAC7E,OAAO;AACL,kBAAkB;AAClB,UAAU,EACV,cAAc,EACd,aAAa;AAEb,sBAAsB;AACtB,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,YAAY;AAEZ,qBAAqB;AACrB,WAAW,EACX,aAAa,EACb,gBAAgB;AAEhB,gCAAgC;AAChC,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EACxB,kBAAkB;AAElB,gBAAgB;AAChB,WAAW,EACX,eAAe,EAIf,iBAAiB,GAClB,MAAM,uBAAuB,CAAC;AAE/B,6DAA6D;AAC7D,OAAO,EAAE,UAAU,IAAI,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AACzE,OAAO,EAAE,kBAAkB,IAAI,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AACnF,OAAO,EAAE,YAAY,IAAI,SAAS,EAAE,MAAM,0BAA0B,CAAC"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# Badge Update Process
|
|
2
|
+
|
|
3
|
+
This document describes how to update the README badges with current test and coverage metrics.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The README.md contains dynamic badges showing:
|
|
8
|
+
|
|
9
|
+
- Test results (passed/total count)
|
|
10
|
+
- Line coverage percentage
|
|
11
|
+
- Branch coverage percentage
|
|
12
|
+
- Function coverage percentage
|
|
13
|
+
|
|
14
|
+
These badges should be updated when test counts or coverage metrics change significantly.
|
|
15
|
+
|
|
16
|
+
## Manual Update Process
|
|
17
|
+
|
|
18
|
+
### 1. Extract Current Metrics
|
|
19
|
+
|
|
20
|
+
Run the metrics extraction script:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
node scripts/extract-metrics.cjs
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
This will output current metrics and generate updated badge URLs.
|
|
27
|
+
|
|
28
|
+
### 2. Update README.md
|
|
29
|
+
|
|
30
|
+
Replace the badge URLs in README.md with the new ones from the script output.
|
|
31
|
+
|
|
32
|
+
**Badge Sections to Update:**
|
|
33
|
+
|
|
34
|
+
- Line 19: `[]`
|
|
35
|
+
- Line 20: `[]`
|
|
36
|
+
- Line 21: `[]`
|
|
37
|
+
- Line 22: `[]`
|
|
38
|
+
|
|
39
|
+
### 3. Badge Color Coding
|
|
40
|
+
|
|
41
|
+
The script automatically applies colors based on coverage levels:
|
|
42
|
+
|
|
43
|
+
| Coverage % | Color | Badge Color Code |
|
|
44
|
+
|-----------|-------|------------------|
|
|
45
|
+
| ≥ 70% | Bright Green | `brightgreen` |
|
|
46
|
+
| ≥ 50% | Green | `green` |
|
|
47
|
+
| ≥ 30% | Yellow | `yellow` |
|
|
48
|
+
| ≥ 20% | Orange | `orange` |
|
|
49
|
+
| < 20% | Red | `red` |
|
|
50
|
+
|
|
51
|
+
**Test Results:**
|
|
52
|
+
|
|
53
|
+
- All passing: `brightgreen`
|
|
54
|
+
- Some failing: `yellow`
|
|
55
|
+
- Many failing: `red`
|
|
56
|
+
|
|
57
|
+
## Script Details
|
|
58
|
+
|
|
59
|
+
### extract-metrics.cjs
|
|
60
|
+
|
|
61
|
+
The extraction script:
|
|
62
|
+
|
|
63
|
+
1. **Test Count**: Runs `npm test` and parses output for passed/failed/total counts
|
|
64
|
+
2. **Coverage**: Attempts to read `coverage/coverage-final.json` or uses fallback values
|
|
65
|
+
3. **Badge URLs**: Generates shields.io badge URLs with appropriate colors
|
|
66
|
+
4. **Fallback**: Uses existing README values if extraction fails
|
|
67
|
+
|
|
68
|
+
### Key Functions
|
|
69
|
+
|
|
70
|
+
- `extractMetrics()`: Main function to gather all metrics
|
|
71
|
+
- `getCoverageColor(percentage)`: Maps coverage % to badge colors
|
|
72
|
+
- Automatic test result parsing from Jest output
|
|
73
|
+
- Graceful fallback to existing values on errors
|
|
74
|
+
|
|
75
|
+
## Future Automation
|
|
76
|
+
|
|
77
|
+
### Planned CI Integration
|
|
78
|
+
|
|
79
|
+
Future improvements will include:
|
|
80
|
+
|
|
81
|
+
1. **Automated Badge Updates**: GitHub Actions workflow to update badges after successful CI runs
|
|
82
|
+
2. **Coverage Reporting**: Enhanced coverage collection from TypeScript sources
|
|
83
|
+
3. **Historical Tracking**: Track coverage trends over time
|
|
84
|
+
4. **PR Integration**: Show coverage diff in pull requests
|
|
85
|
+
|
|
86
|
+
### CI Workflow Structure
|
|
87
|
+
|
|
88
|
+
```yaml
|
|
89
|
+
name: Update Badges
|
|
90
|
+
on:
|
|
91
|
+
push:
|
|
92
|
+
branches: [main]
|
|
93
|
+
jobs:
|
|
94
|
+
update-badges:
|
|
95
|
+
runs-on: ubuntu-latest
|
|
96
|
+
steps:
|
|
97
|
+
- uses: actions/checkout@v3
|
|
98
|
+
- run: npm test
|
|
99
|
+
- run: node scripts/extract-metrics.cjs
|
|
100
|
+
- run: scripts/update-readme-badges.sh
|
|
101
|
+
- uses: stefanzweifel/git-auto-commit-action@v4
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Current Status
|
|
105
|
+
|
|
106
|
+
**As of August 2025:**
|
|
107
|
+
|
|
108
|
+
- **Tests**: 399/404 passing (5 failed)
|
|
109
|
+
- **Line Coverage**: 30.97%
|
|
110
|
+
- **Branch Coverage**: 23.84%
|
|
111
|
+
- **Function Coverage**: 27.69%
|
|
112
|
+
- **Statement Coverage**: 29.76%
|
|
113
|
+
|
|
114
|
+
## Related Issues
|
|
115
|
+
|
|
116
|
+
- Issue #54: Update README badges to reflect current status ✅
|
|
117
|
+
- Issue #55: Automate dynamic badges via CI (pending)
|
|
118
|
+
- Issue #66: Implement incremental coverage guardrail script (pending)
|
|
119
|
+
|
|
120
|
+
## Manual Badge Testing
|
|
121
|
+
|
|
122
|
+
Test badge rendering by visiting the URLs directly:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
# Test line coverage badge
|
|
126
|
+
curl -I "https://img.shields.io/badge/lines%20coverage-30.97%25-yellow?logo=jest&logoColor=white"
|
|
127
|
+
|
|
128
|
+
# Test test results badge
|
|
129
|
+
curl -I "https://img.shields.io/badge/tests-399%2F404%20passing-yellow?logo=checkmarx&logoColor=white"
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
All badges should return HTTP 200 and render properly in the README.
|